Skip to content

Commit e4a9d34

Browse files
committed
StylintBear: Implement settings
Use the implemented settings to generate a `config_file` and use that file if the user does not explicitly mention `stylint_config`. Closes #1795
1 parent 9e43c80 commit e4a9d34

File tree

3 files changed

+293
-4
lines changed

3 files changed

+293
-4
lines changed

bears/stylus/StylintBear.py

+248-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import json
2+
13
from coalib.bearlib.abstractions.Linter import linter
24
from dependency_management.requirements.NpmRequirement import NpmRequirement
35

6+
_setting_map = {True: 'always',
7+
False: 'never',
8+
None: 'false'}
9+
410

511
@linter(executable='stylint',
612
output_format='regex',
@@ -35,13 +41,251 @@ class StylintBear:
3541
CAN_DETECT = {'Formatting', 'Syntax', 'Redundancy'}
3642
SEE_MORE = 'https://github.com/SimenB/stylint'
3743

44+
@staticmethod
45+
def generate_config(filename, file,
46+
block_keyword: bool=None,
47+
brackets: bool=False,
48+
colons_for_property_declaration: bool=True,
49+
color_variables_for_hex_values: bool=True,
50+
spaces_after_commas: bool=True,
51+
spaces_after_comments: bool=True,
52+
allow_trailing_whitespace: bool=False,
53+
no_css_literals: bool=False,
54+
max_selector_depth: bool=False,
55+
check_duplicates: bool=True,
56+
efficient_properties: bool=True,
57+
extend_preference: str=None,
58+
indent_size: int=0,
59+
leading_zero: bool=None,
60+
max_errors: int=0,
61+
max_warnings: int=0,
62+
mixed_spaces_and_tabs: bool=False,
63+
variable_naming_convention: str=None,
64+
strict_naming_convention: bool=False,
65+
none_keyword: bool=False,
66+
check_no_important_keyword: bool=True,
67+
spaces_inside_parentheses: bool=None,
68+
placeholder: bool=True,
69+
prefix_vars_with_dollar: bool=True,
70+
semicolons: bool=False,
71+
sort_order: str='alphabetical',
72+
stacked_properties: bool=False,
73+
check_property_validity: bool=True,
74+
preferred_quotation: str=None,
75+
zero_units: bool=False,
76+
z_index_normalize_base: int=0,
77+
stylint_config: str=''):
78+
"""
79+
:param block_keyword:
80+
When ``True`` expect the ``@block`` keyword when defining block
81+
variables. When ``False``, expect no ``@block`` keyword when
82+
defining block variables.
83+
:param brackets:
84+
When ``True``, expect ``{}`` when declaring a selector. When
85+
``False``, expect no brackets when declaring a selector.
86+
:param colons_for_property_declaration:
87+
When ``True``, expect ``:`` when declaring a property. When
88+
``False``, expect no ``:`` when declaring a property.
89+
:param color_variables_for_hex_values:
90+
When ``True``, enforce variables when defining hex values.
91+
:param spaces_after_commas:
92+
Enforce or disallow spaces after commas.
93+
:param spaces_after_comments:
94+
Enforce or disallow spaces after line comments.
95+
For example: If set to ``True``, prefer
96+
``// comment`` over ``//comment``.
97+
:param allow_trailing_whitespace:
98+
If ``True``, ignores trailing whitespace. If ``False``, trailing
99+
whitespace will throw a warning.
100+
:param no_css_literals:
101+
By default Stylint ignores ``@css`` blocks. If set to ``True``
102+
however, warnings are thrown if ``@css`` is used.
103+
:param max_selector_depth:
104+
Set the max selector depth. If set to 4, max selector depth will
105+
be 4 indents. Pseudo selectors like ``&:first-child`` or
106+
``&:hover`` won't count towards the limit.
107+
:param check_duplicates:
108+
Checks if selectors or properties are duplicated unnecessarily.
109+
:param efficient_properties:
110+
Check for places where properties can be written more efficiently.
111+
:param extend_preference:
112+
Pass in either ``@extend`` or ``@extends`` and then enforce that.
113+
Both are valid in Stylus. It doesn't really matter which one
114+
you use.
115+
For example: If set to ``@extends``, prefer
116+
``@extends $some-var`` instead of ``@extend $some-var``
117+
or if set to ``@extend``, prefer
118+
``@extend $some-var`` over ``@extends $some-var``.
119+
:param indent_size:
120+
This works in conjunction with ``max_selector_depth``. If you
121+
indent with spaces this is the number of spaces you indent with.
122+
If you use hard tabs, set this value to ``0``.
123+
For example: If set to ``2``, prefer
124+
``/s/smargin: 0`` over ``/s/s/smargin: 0``.
125+
:param leading_zero:
126+
When ``True``, prefer leading zeroes on decimal points. When
127+
``False``, disallow leading zeroes on decimal points.
128+
:param max_errors:
129+
Set maximum number of errors. If ``0``, all errors will
130+
be shown without a limit.
131+
:param max_warnings:
132+
Set maximum number of warnings. If ``0``, all errors will
133+
be shown without a limit.
134+
:param mixed_spaces_and_tabs:
135+
If a non-negative number is passed to ``indent_size``,
136+
soft tabs (i.e. spaces) are assumed, and if
137+
``0`` is passed to ``indent_size``, hard tabs are assumed.
138+
For example: If ``indent_size = 4`` and
139+
``mixed_spaces_and_tabs = True``, prefer
140+
``/s/s/s/smargin 0`` over ``/tmargin 0``
141+
or if ``indent_size = 0`` and
142+
``mixed_spaces_and_tabs = True``, prefer
143+
``/tmargin 0`` over ``/s/s/s/smargin 0``.
144+
:param variable_naming_convention:
145+
Enforce a particular naming convention when declaring variables.
146+
Throws a warning if you don't follow the convention.
147+
Supported values are ``lowercase-dash``, ``lowercase_underscore``,
148+
``camelCase`` and ``BEM``.
149+
:param strict_naming_convention:
150+
By default, ``variable_naming_convention`` only looks at variable
151+
names. If ``strict_naming_convention`` is set to ``True``,
152+
``variable_naming_convention`` will also look at class and
153+
ID names.
154+
:param none_keyword:
155+
If ``True`` check for places where ``none`` used instead of ``0``.
156+
If ``False`` check for places where ``0`` could be used
157+
instead of ``none``.
158+
:param check_no_important_keyword:
159+
If ``True``, show warning when ``!important`` is found.
160+
For example: If set to ``True``, this will throw a warning::
161+
162+
div
163+
color red !important
164+
165+
:param spaces_inside_parentheses:
166+
Enforce or disallow use of extra spaces inside parentheses.
167+
For example: If set to ``True``, prefer
168+
``my-mixin( $myParam )`` over ``my-mixin($myParam)``
169+
or if set to ``False``, prefer
170+
``my-mixin($myParam)`` over ``my-mixin( $myParam )``.
171+
:param placeholder:
172+
Enforce extending placeholder vars when using ``@extend(s)``.
173+
:param prefix_vars_with_dollar:
174+
Enforce use of ``$`` when defining a variable. In Stylus, using a
175+
``$`` when defining a variable is optional, but is a good idea
176+
if you want to prevent ambiguity. Not including the ``$`` sets up
177+
situations where you wonder: "Is this a variable or a value?"
178+
For instance: ``padding $default`` is easier to understand than
179+
``padding default``.
180+
For example: If set to ``True``, prefer
181+
``$my-var = 0`` over ``my-var = 0``
182+
or if set to ``False``, prefer
183+
``my-var = 0`` over ``$my-var = 0``.
184+
:param semicolons:
185+
When ``True``, enforce semicolons. When ``False``, disallow
186+
semicolons.
187+
:param sort_order:
188+
Enforce a particular sort order when declaring properties. Throws
189+
a warning if you don't follow the order.
190+
For example: If set to ``alphabetical``, prefer this::
191+
192+
.some-class
193+
display block
194+
float left
195+
position absolute
196+
right 10px
197+
top 0
198+
199+
over this::
200+
201+
.some-class
202+
position absolute
203+
top 0
204+
right 10px
205+
display block
206+
float left
207+
208+
Supported values are ``alphabetical`` and ``grouped``.
209+
:param stacked_properties:
210+
No one-liners. Enforce putting properties on new lines.
211+
For example: If set to ``False``, prefer::
212+
213+
.className
214+
padding 0
215+
216+
over
217+
``.className { padding 0 }``
218+
:param check_property_validity:
219+
Check that a property is valid CSS or HTML.
220+
:param preferred_quotation:
221+
Your preferred quotation character, e.g. ``double`` or ``single``.
222+
:param zero_units:
223+
Looks for instances of ``0px``. You don't need the ``px``.
224+
Checks all units, not just ``px``.
225+
:param z_index_normalize_base:
226+
Enforce some basic z-index sanity. Any number passed in
227+
will be used as the base for your z-index values.
228+
Use ``0`` to disable this feature.
229+
For example: If set to ``5``, prefer
230+
``z-index 10`` over ``z-index 9``
231+
or if set to ``10``, prefer
232+
``z-index 20`` over ``z-index 15``.
233+
"""
234+
if stylint_config:
235+
return None
236+
else:
237+
options = {
238+
'blocks': _setting_map[block_keyword],
239+
'brackets': _setting_map[brackets],
240+
'colons': _setting_map[colons_for_property_declaration],
241+
'colors': _setting_map[color_variables_for_hex_values],
242+
'commaSpace': _setting_map[spaces_after_commas],
243+
'commentSpace': _setting_map[spaces_after_comments],
244+
'cssLiteral': _setting_map[no_css_literals],
245+
'depthLimit': max_selector_depth,
246+
'duplicates': check_duplicates,
247+
'efficient': _setting_map[efficient_properties],
248+
'extendPref': extend_preference,
249+
'indentPref': indent_size,
250+
'leadingZero': _setting_map[leading_zero],
251+
'maxErrors': max_errors,
252+
'maxWarnings': max_warnings,
253+
'mixed': mixed_spaces_and_tabs,
254+
'namingConvention': variable_naming_convention,
255+
'namingConventionStrict': strict_naming_convention,
256+
'none': _setting_map[none_keyword],
257+
'noImportant': check_no_important_keyword,
258+
'parenSpace': _setting_map[spaces_inside_parentheses],
259+
'placeholders': _setting_map[placeholder],
260+
'prefixVarsWithDollar': _setting_map[prefix_vars_with_dollar],
261+
'quotePref': preferred_quotation,
262+
'semicolons': _setting_map[semicolons],
263+
'sortOrder': sort_order,
264+
'stackedProperties': _setting_map[stacked_properties],
265+
'trailingWhitespace':
266+
False if allow_trailing_whitespace is True else 'never',
267+
'valid': check_property_validity,
268+
'zeroUnits': _setting_map[zero_units],
269+
'zIndexNormalize':
270+
False if z_index_normalize_base == 0
271+
else z_index_normalize_base,
272+
'groupOutputByFile': True,
273+
'reporterOptions': {
274+
'columns': ['lineData', 'severity', 'description', 'rule'],
275+
'columnSplitter': ' ',
276+
'showHeaders': False,
277+
'truncate': True
278+
}
279+
}
280+
281+
return json.dumps(options)
282+
38283
@staticmethod
39284
def create_arguments(filename, file, config_file, stylint_config: str=''):
40285
"""
41286
:param stylint_config:
42287
The location of the ``.stylintrc`` config file.
43288
"""
44-
if stylint_config:
45-
return '--config', stylint_config, filename
46-
else:
47-
return filename,
289+
return ('--config',
290+
stylint_config if stylint_config else config_file,
291+
filename)

tests/stylus/StylintBearTest.py

+36
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,42 @@ def test_bad_mixed_spaces_tabs(self):
145145
filename=get_testfile_path(filename),
146146
settings={'stylint_config': get_testfile_path('.stylintrc')})
147147

148+
def test_bad_placeholder_space_color(self):
149+
filename = 'test_bad_placeholder_space_color.styl'
150+
file_contents = load_testfile(filename)
151+
self.check_results(
152+
self.uut,
153+
file_contents,
154+
[Result.from_values('StylintBear',
155+
message='always use a placeholder variable '
156+
'when extending',
157+
file=get_testfile_path(filename),
158+
line=4,
159+
severity=RESULT_SEVERITY.NORMAL),
160+
Result.from_values('StylintBear',
161+
message='hexidecimal color should '
162+
'be a variable',
163+
file=get_testfile_path(filename),
164+
line=6,
165+
column=8,
166+
severity=RESULT_SEVERITY.NORMAL),
167+
Result.from_values('StylintBear',
168+
message='line comments require a space '
169+
'after //',
170+
file=get_testfile_path(filename),
171+
line=8,
172+
column=2,
173+
severity=RESULT_SEVERITY.NORMAL),
174+
Result.from_values('StylintBear',
175+
message='commas must be followed '
176+
'by a space for readability',
177+
file=get_testfile_path(filename),
178+
line=9,
179+
column=6,
180+
severity=RESULT_SEVERITY.NORMAL),
181+
],
182+
filename=get_testfile_path(filename))
183+
148184
def test_valid_file(self):
149185
filename = 'test_valid_file.styl'
150186
file_contents = load_testfile(filename)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.message
2+
padding: 10px
3+
body
4+
@extend .message
5+
color: $var_name
6+
color #f00
7+
font: 12px Helvetica, Arial, sans-serif
8+
//comment
9+
rgba(0,0,0,.18)

0 commit comments

Comments
 (0)