scss-lint 0.20.3 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/default.yml +4 -0
- data/lib/scss_lint/cli.rb +3 -1
- data/lib/scss_lint/config.rb +1 -1
- data/lib/scss_lint/engine.rb +2 -2
- data/lib/scss_lint/linter.rb +3 -9
- data/lib/scss_lint/linter/border_zero.rb +11 -10
- data/lib/scss_lint/linter/color_keyword.rb +1 -1
- data/lib/scss_lint/linter/comment.rb +1 -5
- data/lib/scss_lint/linter/debug_statement.rb +1 -5
- data/lib/scss_lint/linter/declaration_order.rb +4 -5
- data/lib/scss_lint/linter/duplicate_property.rb +23 -9
- data/lib/scss_lint/linter/empty_line_between_blocks.rb +15 -0
- data/lib/scss_lint/linter/empty_rule.rb +1 -5
- data/lib/scss_lint/linter/id_with_extraneous_selector.rb +6 -1
- data/lib/scss_lint/linter/indentation.rb +19 -19
- data/lib/scss_lint/linter/placeholder_in_extend.rb +4 -5
- data/lib/scss_lint/linter/property_sort_order.rb +33 -26
- data/lib/scss_lint/linter/shorthand.rb +14 -6
- data/lib/scss_lint/linter/space_before_brace.rb +1 -5
- data/lib/scss_lint/linter/string_quotes.rb +4 -4
- data/lib/scss_lint/linter/url_format.rb +55 -0
- data/lib/scss_lint/reporter/default_reporter.rb +2 -4
- data/lib/scss_lint/version.rb +1 -1
- metadata +55 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a7439d0611e864629c12a2f1e95c417b0e0615a
|
4
|
+
data.tar.gz: 4ca3047aa3497339ee4dc9164764d229e38f9a27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74cf4f6c5e8fcd106500db1a05ef37d311065cbd97ef4e120380d2d6c6c90ff252d9f6818a863708337b42cc24d352cd6ba5909a2216c987b7b1d07419f9aa79
|
7
|
+
data.tar.gz: 04e23316befdbaf54f37f6004df3b5e93a9eab83ce00a5f36de107ec5176485092c1f22e965fc3f2617e4a7c7f536d171a8099a5c5ea50353b80cd86030aee0c
|
data/config/default.yml
CHANGED
@@ -23,6 +23,7 @@ linters:
|
|
23
23
|
|
24
24
|
EmptyLineBetweenBlocks:
|
25
25
|
enabled: true
|
26
|
+
ignore_single_line_blocks: true
|
26
27
|
|
27
28
|
EmptyRule:
|
28
29
|
enabled: true
|
@@ -88,6 +89,9 @@ linters:
|
|
88
89
|
TrailingSemicolonAfterPropertyValue:
|
89
90
|
enabled: true
|
90
91
|
|
92
|
+
UrlFormat:
|
93
|
+
enabled: true
|
94
|
+
|
91
95
|
UrlQuotes:
|
92
96
|
enabled: true
|
93
97
|
|
data/lib/scss_lint/cli.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'find'
|
2
2
|
require 'optparse'
|
3
|
+
require 'rainbow'
|
4
|
+
require 'rainbow/ext/string'
|
3
5
|
|
4
6
|
module SCSSLint
|
5
7
|
# Responsible for parsing command-line options and executing the appropriate
|
@@ -104,7 +106,7 @@ module SCSSLint
|
|
104
106
|
rescue => ex
|
105
107
|
puts ex.message
|
106
108
|
puts ex.backtrace
|
107
|
-
puts 'Report this bug at '.yellow + BUG_REPORT_URL.cyan
|
109
|
+
puts 'Report this bug at '.color(:yellow) + BUG_REPORT_URL.color(:cyan)
|
108
110
|
halt :software
|
109
111
|
end
|
110
112
|
|
data/lib/scss_lint/config.rb
CHANGED
data/lib/scss_lint/engine.rb
CHANGED
@@ -11,7 +11,7 @@ module SCSSLint
|
|
11
11
|
attr_reader :contents, :filename, :lines, :tree
|
12
12
|
|
13
13
|
def initialize(scss_or_filename)
|
14
|
-
if File.
|
14
|
+
if File.exist?(scss_or_filename)
|
15
15
|
@filename = scss_or_filename
|
16
16
|
@engine = Sass::Engine.for_file(scss_or_filename, ENGINE_OPTIONS)
|
17
17
|
@contents = File.open(scss_or_filename, 'r').read
|
@@ -26,7 +26,7 @@ module SCSSLint
|
|
26
26
|
if error.is_a?(Encoding::UndefinedConversionError) ||
|
27
27
|
error.message.include?('invalid byte sequence')
|
28
28
|
raise FileEncodingError,
|
29
|
-
"Unable to parse SCSS file: #{error
|
29
|
+
"Unable to parse SCSS file: #{error}",
|
30
30
|
error.backtrace
|
31
31
|
else
|
32
32
|
raise
|
data/lib/scss_lint/linter.rb
CHANGED
@@ -18,22 +18,16 @@ module SCSSLint
|
|
18
18
|
visit(engine.tree)
|
19
19
|
end
|
20
20
|
|
21
|
-
# Define if you want a default message for your linter
|
22
|
-
# @return [String, nil]
|
23
|
-
def description
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
|
27
21
|
# Helper for creating lint from a parse tree node
|
28
22
|
#
|
29
23
|
# @param node_or_line [Sass::Script::Tree::Node, Sass::Engine::Line]
|
30
|
-
# @param message [String
|
31
|
-
def add_lint(node_or_line, message
|
24
|
+
# @param message [String]
|
25
|
+
def add_lint(node_or_line, message)
|
32
26
|
line = node_or_line.respond_to?(:line) ? node_or_line.line : node_or_line
|
33
27
|
|
34
28
|
@lints << Lint.new(engine.filename,
|
35
29
|
line,
|
36
|
-
message
|
30
|
+
message)
|
37
31
|
end
|
38
32
|
|
39
33
|
# @param source_position [Sass::Source::Position]
|
@@ -4,20 +4,21 @@ module SCSSLint
|
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
6
|
def visit_prop(node)
|
7
|
-
return unless BORDER_PROPERTIES.include?
|
8
|
-
add_lint(node) if node.value.to_sass.strip == 'none'
|
9
|
-
end
|
7
|
+
return unless BORDER_PROPERTIES.include?(node.name.first.to_s)
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
if node.value.to_sass.strip == 'none'
|
10
|
+
add_lint(node, '`border: 0;` is preferred over `border: none;`')
|
11
|
+
end
|
13
12
|
end
|
14
13
|
|
15
14
|
private
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
BORDER_PROPERTIES = %w[
|
17
|
+
border
|
18
|
+
border-top
|
19
|
+
border-right
|
20
|
+
border-bottom
|
21
|
+
border-left
|
22
|
+
]
|
22
23
|
end
|
23
24
|
end
|
@@ -4,11 +4,7 @@ module SCSSLint
|
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
6
|
def visit_comment(node)
|
7
|
-
add_lint(node) unless node.invisible?
|
8
|
-
end
|
9
|
-
|
10
|
-
def description
|
11
|
-
'Use // comments everywhere'
|
7
|
+
add_lint(node, 'Use `//` comments everywhere') unless node.invisible?
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|
@@ -18,18 +18,17 @@ module SCSSLint
|
|
18
18
|
end
|
19
19
|
|
20
20
|
if children != sorted_children
|
21
|
-
add_lint(node.children.first)
|
21
|
+
add_lint(node.children.first, MESSAGE)
|
22
22
|
end
|
23
23
|
|
24
24
|
yield # Continue linting children
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
private
|
28
|
+
|
29
|
+
MESSAGE =
|
28
30
|
'Rule sets should start with @extend declarations, followed by ' <<
|
29
31
|
'properties and nested rule sets, in that order'
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
32
|
|
34
33
|
def important_node?(node)
|
35
34
|
DECLARATION_ORDER.include? node.class
|
@@ -4,6 +4,28 @@ module SCSSLint
|
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
6
|
def visit_rule(node)
|
7
|
+
check_properties(node)
|
8
|
+
end
|
9
|
+
|
10
|
+
def visit_mixindef(node)
|
11
|
+
check_properties(node)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def property_value(prop)
|
17
|
+
case prop.value
|
18
|
+
when Sass::Script::Funcall
|
19
|
+
prop.value.name
|
20
|
+
when Sass::Script::String
|
21
|
+
when Sass::Script::Tree::Literal
|
22
|
+
prop.value.value
|
23
|
+
else
|
24
|
+
prop.value.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_properties(node)
|
7
29
|
properties = node.children
|
8
30
|
.select { |child| child.is_a?(Sass::Tree::PropNode) }
|
9
31
|
.reject { |prop| prop.name.any? { |item| item.is_a?(Sass::Script::Node) } }
|
@@ -14,15 +36,7 @@ module SCSSLint
|
|
14
36
|
name = prop.name.join
|
15
37
|
|
16
38
|
prop_hash = name
|
17
|
-
prop_value =
|
18
|
-
case prop.value
|
19
|
-
when Sass::Script::Funcall
|
20
|
-
prop.value.name
|
21
|
-
when Sass::Script::String
|
22
|
-
prop.value.value
|
23
|
-
else
|
24
|
-
prop.value.to_s
|
25
|
-
end
|
39
|
+
prop_value = property_value(prop)
|
26
40
|
|
27
41
|
prop_value.to_s.scan(/^(-[^-]+-.+)/) do |vendor_keyword|
|
28
42
|
prop_hash << vendor_keyword.first
|
@@ -30,6 +30,7 @@ module SCSSLint
|
|
30
30
|
MESSAGE_FORMAT = '%s declaration should be %s by an empty line'
|
31
31
|
|
32
32
|
def check(node, type)
|
33
|
+
return if config['ignore_single_line_blocks'] && node_on_single_line(node)
|
33
34
|
check_preceding_node(node, type)
|
34
35
|
check_following_node(node, type)
|
35
36
|
end
|
@@ -79,5 +80,19 @@ module SCSSLint
|
|
79
80
|
.children
|
80
81
|
.select { |child| child.is_a?(Sass::Tree::Node) }
|
81
82
|
end
|
83
|
+
|
84
|
+
def node_on_single_line(node)
|
85
|
+
return if node.source_range.start_pos.line != node.source_range.end_pos.line
|
86
|
+
|
87
|
+
# The Sass parser reports an incorrect source range if the trailing curly
|
88
|
+
# brace is on the next line, e.g.
|
89
|
+
#
|
90
|
+
# p {
|
91
|
+
# }
|
92
|
+
#
|
93
|
+
# Since we don't want to count this as a single line node, check if the
|
94
|
+
# last character on the first line is an opening curly brace.
|
95
|
+
engine.lines[node.line - 1].strip[-1] != '{'
|
96
|
+
end
|
82
97
|
end
|
83
98
|
end
|
@@ -4,12 +4,8 @@ module SCSSLint
|
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
6
|
def visit_rule(node)
|
7
|
-
add_lint(node) if node.children.empty?
|
7
|
+
add_lint(node, 'Empty rule') if node.children.empty?
|
8
8
|
yield # Continue linting children
|
9
9
|
end
|
10
|
-
|
11
|
-
def description
|
12
|
-
'Empty rule'
|
13
|
-
end
|
14
10
|
end
|
15
11
|
end
|
@@ -7,7 +7,12 @@ module SCSSLint
|
|
7
7
|
id_sel = seq.members.find { |simple| simple.is_a?(Sass::Selector::Id) }
|
8
8
|
return unless id_sel
|
9
9
|
|
10
|
-
|
10
|
+
can_be_simplified = seq.members.any? do |simple|
|
11
|
+
!simple.is_a?(Sass::Selector::Id) &&
|
12
|
+
!simple.is_a?(Sass::Selector::Pseudo)
|
13
|
+
end
|
14
|
+
|
15
|
+
if can_be_simplified
|
11
16
|
add_lint(seq, "Selector `#{seq}` can be simplified to `#{id_sel}`, " <<
|
12
17
|
'since IDs should be uniquely identifying')
|
13
18
|
end
|
@@ -44,26 +44,26 @@ module SCSSLint
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Define node types that increase indentation level
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
47
|
+
alias_method :visit_directive, :check_and_visit_children
|
48
|
+
alias_method :visit_each, :check_and_visit_children
|
49
|
+
alias_method :visit_for, :check_and_visit_children
|
50
|
+
alias_method :visit_function, :check_and_visit_children
|
51
|
+
alias_method :visit_media, :check_and_visit_children
|
52
|
+
alias_method :visit_mixin, :check_and_visit_children
|
53
|
+
alias_method :visit_mixindef, :check_and_visit_children
|
54
|
+
alias_method :visit_prop, :check_and_visit_children
|
55
|
+
alias_method :visit_rule, :check_and_visit_children
|
56
|
+
alias_method :visit_supports, :check_and_visit_children
|
57
|
+
alias_method :visit_while, :check_and_visit_children
|
58
58
|
|
59
59
|
# Define node types to check indentation of (notice comments are left out)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
60
|
+
alias_method :visit_charset, :check_indentation
|
61
|
+
alias_method :visit_content, :check_indentation
|
62
|
+
alias_method :visit_cssimport, :check_indentation
|
63
|
+
alias_method :visit_extend, :check_indentation
|
64
|
+
alias_method :visit_import, :check_indentation
|
65
|
+
alias_method :visit_return, :check_indentation
|
66
|
+
alias_method :visit_variable, :check_indentation
|
67
|
+
alias_method :visit_warn, :check_indentation
|
68
68
|
end
|
69
69
|
end
|
@@ -8,11 +8,10 @@ module SCSSLint
|
|
8
8
|
# every word boundary (so %placeholder becomes ['%', 'placeholder']).
|
9
9
|
selector = node.selector.join
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
'Always use placeholder selectors (e.g. %some-placeholder) with @extend'
|
11
|
+
unless selector.start_with?('%')
|
12
|
+
add_lint(node,
|
13
|
+
'Prefer using placeholder selectors (e.g. %some-placeholder) with @extend')
|
14
|
+
end
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -10,18 +10,19 @@ module SCSSLint
|
|
10
10
|
child.name.all? { |part| part.is_a?(String) }
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
sortable_prop_info = sortable_props
|
14
|
+
.map { |child| child.name.join }
|
15
|
+
.map do |name|
|
16
|
+
/^(?<vendor>-\w+(-osx)?-)?(?<property>.+)/ =~ name
|
17
|
+
{ name: name, vendor: vendor, property: property }
|
18
|
+
end
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
{ name: name, vendor: vendor, property: property }
|
18
|
-
end.sort { |a, b| compare_properties(a, b) }
|
19
|
-
.map { |fields| fields[:name] }
|
20
|
+
sorted_props = sortable_prop_info
|
21
|
+
.sort { |a, b| compare_properties(a, b) }
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
add_lint(sortable_props[index])
|
23
|
+
sorted_props.each_with_index do |prop, index|
|
24
|
+
if prop != sortable_prop_info[index]
|
25
|
+
add_lint(sortable_props[index], MESSAGE)
|
25
26
|
break
|
26
27
|
end
|
27
28
|
end
|
@@ -29,13 +30,11 @@ module SCSSLint
|
|
29
30
|
yield # Continue linting children
|
30
31
|
end
|
31
32
|
|
32
|
-
def description
|
33
|
-
'Properties should be sorted in order, with ' <<
|
34
|
-
'vendor-prefixed extensions before the standardized CSS property'
|
35
|
-
end
|
36
|
-
|
37
33
|
private
|
38
34
|
|
35
|
+
MESSAGE = 'Properties should be sorted in order, with vendor-prefixed ' <<
|
36
|
+
'extensions before the standardized CSS property'
|
37
|
+
|
39
38
|
# Compares two properties which can contain a vendor prefix. It allows for a
|
40
39
|
# sort order like:
|
41
40
|
#
|
@@ -52,23 +51,31 @@ module SCSSLint
|
|
52
51
|
# are ordered amongst themselves by vendor prefix.
|
53
52
|
def compare_properties(a, b)
|
54
53
|
if a[:property] == b[:property]
|
55
|
-
|
56
|
-
a[:vendor] <=> b[:vendor]
|
57
|
-
elsif a[:vendor]
|
58
|
-
-1
|
59
|
-
elsif b[:vendor]
|
60
|
-
1
|
61
|
-
else
|
62
|
-
0
|
63
|
-
end
|
54
|
+
compare_by_vendor(a, b)
|
64
55
|
else
|
65
56
|
if config['order']
|
66
|
-
(config['order']
|
67
|
-
(config['order'].index(b[:property]) || Float::INFINITY)
|
57
|
+
compare_by_order(a, b, config['order'])
|
68
58
|
else
|
69
59
|
a[:property] <=> b[:property]
|
70
60
|
end
|
71
61
|
end
|
72
62
|
end
|
63
|
+
|
64
|
+
def compare_by_vendor(a, b)
|
65
|
+
if a[:vendor] && b[:vendor]
|
66
|
+
a[:vendor] <=> b[:vendor]
|
67
|
+
elsif a[:vendor]
|
68
|
+
-1
|
69
|
+
elsif b[:vendor]
|
70
|
+
1
|
71
|
+
else
|
72
|
+
0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def compare_by_order(a, b, order)
|
77
|
+
(order.index(a[:property]) || Float::INFINITY) <=>
|
78
|
+
(order.index(b[:property]) || Float::INFINITY)
|
79
|
+
end
|
73
80
|
end
|
74
81
|
end
|
@@ -63,19 +63,27 @@ module SCSSLint
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def condensed_shorthand(top, right, bottom = nil, left = nil)
|
66
|
-
if top
|
66
|
+
if can_condense_to_one_value(top, right, bottom, left)
|
67
67
|
[top]
|
68
|
-
elsif top
|
69
|
-
[top]
|
70
|
-
elsif top == bottom && right == left
|
68
|
+
elsif can_condense_to_two_values(top, right, bottom, left)
|
71
69
|
[top, right]
|
72
|
-
elsif top == bottom && left.nil?
|
73
|
-
top == right ? [top] : [top, right]
|
74
70
|
elsif right == left
|
75
71
|
[top, right, bottom]
|
76
72
|
else
|
77
73
|
[top, right, bottom, left].compact
|
78
74
|
end
|
79
75
|
end
|
76
|
+
|
77
|
+
def can_condense_to_one_value(top, right, bottom, left)
|
78
|
+
if top == right
|
79
|
+
top == bottom && (bottom == left || left.nil?) ||
|
80
|
+
bottom.nil? && left.nil?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def can_condense_to_two_values(top, right, bottom, left)
|
85
|
+
top == bottom && right == left ||
|
86
|
+
top == bottom && left.nil? && top != right
|
87
|
+
end
|
80
88
|
end
|
81
89
|
end
|
@@ -6,13 +6,9 @@ module SCSSLint
|
|
6
6
|
def visit_root(node)
|
7
7
|
engine.lines.each_with_index do |line, index|
|
8
8
|
line.scan /[^"#](?<![^ ] )\{/ do |match|
|
9
|
-
|
9
|
+
add_lint(index + 1, 'Opening curly braces ({) should be preceded by one space')
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
def description
|
15
|
-
'Opening curly braces ({) should be preceded by one space'
|
16
|
-
end
|
17
13
|
end
|
18
14
|
end
|
@@ -53,8 +53,8 @@ module SCSSLint
|
|
53
53
|
add_lint(node, 'Prefer single quoted strings') if string !~ /'/
|
54
54
|
else
|
55
55
|
if string =~ /(?<! \\) \\"/x && string !~ /'/
|
56
|
-
add_lint(node, 'Use single-quoted strings when writing double
|
57
|
-
'to avoid having to escape the double quotes')
|
56
|
+
add_lint(node, 'Use single-quoted strings when writing double ' <<
|
57
|
+
'quotes to avoid having to escape the double quotes')
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -62,8 +62,8 @@ module SCSSLint
|
|
62
62
|
def check_single_quotes(node, string)
|
63
63
|
if config['style'] == 'single_quotes'
|
64
64
|
if string =~ /(?<! \\) \\'/x && string !~ /"/
|
65
|
-
add_lint(node, 'Use double-quoted strings when writing single
|
66
|
-
'to avoid having to escape the single quotes')
|
65
|
+
add_lint(node, 'Use double-quoted strings when writing single ' <<
|
66
|
+
'quotes to avoid having to escape the single quotes')
|
67
67
|
elsif string =~ /(?<! \\) \\"/x
|
68
68
|
add_lint(node, "Don't escape double quotes in single-quoted strings")
|
69
69
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module SCSSLint
|
4
|
+
# Checks the format of URLs for unnecessary protocols or domains.
|
5
|
+
class Linter::UrlFormat < Linter
|
6
|
+
include LinterRegistry
|
7
|
+
|
8
|
+
def visit_script_funcall(node)
|
9
|
+
return unless node.name == 'url'
|
10
|
+
|
11
|
+
if url_string?(node.args[0])
|
12
|
+
url = node.args[0].value.value.to_s
|
13
|
+
check_url(url, node)
|
14
|
+
end
|
15
|
+
|
16
|
+
yield
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit_prop(node)
|
20
|
+
if url_literal?(node.value)
|
21
|
+
url = node.value.to_sass.gsub(/^url\((.*)\)$/, '\\1')
|
22
|
+
check_url(url, node)
|
23
|
+
end
|
24
|
+
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def url_literal?(prop_value)
|
31
|
+
return unless prop_value.is_a?(Sass::Script::Tree::Literal)
|
32
|
+
return unless prop_value.value.is_a?(Sass::Script::Value::String)
|
33
|
+
return unless prop_value.value.type == :identifier
|
34
|
+
|
35
|
+
prop_value.to_sass.match(/^url\(/)
|
36
|
+
end
|
37
|
+
|
38
|
+
def url_string?(arg)
|
39
|
+
return unless arg.is_a?(Sass::Script::Tree::Literal)
|
40
|
+
return unless arg.value.is_a?(Sass::Script::Value::String)
|
41
|
+
|
42
|
+
arg.value.type == :string
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_url(url, node)
|
46
|
+
uri = URI(url)
|
47
|
+
|
48
|
+
if uri.scheme || uri.host
|
49
|
+
add_lint(node, "URL `#{url}` should not contain protocol or domain")
|
50
|
+
end
|
51
|
+
rescue URI::Error => ex
|
52
|
+
add_lint(node, "Invalid URL `#{url}`: #{ex}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,13 +1,11 @@
|
|
1
|
-
require 'colorize'
|
2
|
-
|
3
1
|
module SCSSLint
|
4
2
|
# Reports a single line per lint.
|
5
3
|
class Reporter::DefaultReporter < Reporter
|
6
4
|
def report_lints
|
7
5
|
if lints.any?
|
8
6
|
lints.map do |lint|
|
9
|
-
type = lint.error? ? '[E]'.red : '[W]'.yellow
|
10
|
-
"#{lint.filename.cyan}:" << "#{lint.line}".magenta <<
|
7
|
+
type = lint.error? ? '[E]'.color(:red) : '[W]'.color(:yellow)
|
8
|
+
"#{lint.filename.color(:cyan)}:" << "#{lint.line}".color(:magenta) <<
|
11
9
|
" #{type} #{lint.description}"
|
12
10
|
end.join("\n") + "\n"
|
13
11
|
end
|
data/lib/scss_lint/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scss-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Causes Engineering
|
@@ -9,22 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rainbow
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0
|
20
|
+
version: '2.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0
|
27
|
+
version: '2.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: sass
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,30 +43,30 @@ dependencies:
|
|
43
43
|
name: nokogiri
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ~>
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 1.6.
|
48
|
+
version: 1.6.0
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 1.6.
|
55
|
+
version: 1.6.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: rspec
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 2.
|
62
|
+
version: '2.0'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 2.
|
69
|
+
version: '2.0'
|
70
70
|
description: Configurable tool for writing clean and consistent SCSS
|
71
71
|
email:
|
72
72
|
- eng@causes.com
|
@@ -78,55 +78,56 @@ extra_rdoc_files: []
|
|
78
78
|
files:
|
79
79
|
- config/default.yml
|
80
80
|
- data/properties.txt
|
81
|
-
- lib/scss_lint/
|
81
|
+
- lib/scss_lint/cli.rb
|
82
|
+
- lib/scss_lint/config.rb
|
82
83
|
- lib/scss_lint/constants.rb
|
83
|
-
- lib/scss_lint/
|
84
|
-
- lib/scss_lint/reporter/files_reporter.rb
|
85
|
-
- lib/scss_lint/reporter/xml_reporter.rb
|
86
|
-
- lib/scss_lint/reporter/default_reporter.rb
|
87
|
-
- lib/scss_lint/runner.rb
|
88
|
-
- lib/scss_lint/reporter.rb
|
84
|
+
- lib/scss_lint/engine.rb
|
89
85
|
- lib/scss_lint/lint.rb
|
90
|
-
- lib/scss_lint/linter.rb
|
91
|
-
- lib/scss_lint/rake_task.rb
|
92
|
-
- lib/scss_lint/selector_visitor.rb
|
93
|
-
- lib/scss_lint/sass/tree.rb
|
94
|
-
- lib/scss_lint/sass/script.rb
|
95
|
-
- lib/scss_lint/config.rb
|
96
|
-
- lib/scss_lint/linter/compass.rb
|
97
|
-
- lib/scss_lint/linter/space_after_comma.rb
|
98
|
-
- lib/scss_lint/linter/space_before_brace.rb
|
86
|
+
- lib/scss_lint/linter/border_zero.rb
|
99
87
|
- lib/scss_lint/linter/capitalization_in_selector.rb
|
100
|
-
- lib/scss_lint/linter/
|
101
|
-
- lib/scss_lint/linter/
|
102
|
-
- lib/scss_lint/linter/shorthand.rb
|
103
|
-
- lib/scss_lint/linter/id_with_extraneous_selector.rb
|
104
|
-
- lib/scss_lint/linter/empty_line_between_blocks.rb
|
105
|
-
- lib/scss_lint/linter/declaration_order.rb
|
106
|
-
- lib/scss_lint/linter/zero_unit.rb
|
107
|
-
- lib/scss_lint/linter/placeholder_in_extend.rb
|
108
|
-
- lib/scss_lint/linter/selector_depth.rb
|
88
|
+
- lib/scss_lint/linter/color_keyword.rb
|
89
|
+
- lib/scss_lint/linter/comment.rb
|
109
90
|
- lib/scss_lint/linter/compass/property_with_mixin.rb
|
110
|
-
- lib/scss_lint/linter/
|
111
|
-
- lib/scss_lint/linter/property_spelling.rb
|
112
|
-
- lib/scss_lint/linter/url_quotes.rb
|
113
|
-
- lib/scss_lint/linter/name_format.rb
|
114
|
-
- lib/scss_lint/linter/space_between_parens.rb
|
115
|
-
- lib/scss_lint/linter/border_zero.rb
|
116
|
-
- lib/scss_lint/linter/space_after_property_colon.rb
|
91
|
+
- lib/scss_lint/linter/compass.rb
|
117
92
|
- lib/scss_lint/linter/debug_statement.rb
|
93
|
+
- lib/scss_lint/linter/declaration_order.rb
|
118
94
|
- lib/scss_lint/linter/duplicate_property.rb
|
119
|
-
- lib/scss_lint/linter/
|
95
|
+
- lib/scss_lint/linter/empty_line_between_blocks.rb
|
96
|
+
- lib/scss_lint/linter/empty_rule.rb
|
120
97
|
- lib/scss_lint/linter/hex_format.rb
|
121
|
-
- lib/scss_lint/linter/
|
122
|
-
- lib/scss_lint/linter/
|
98
|
+
- lib/scss_lint/linter/id_with_extraneous_selector.rb
|
99
|
+
- lib/scss_lint/linter/indentation.rb
|
123
100
|
- lib/scss_lint/linter/leading_zero.rb
|
124
|
-
- lib/scss_lint/linter/
|
125
|
-
- lib/scss_lint/linter/
|
101
|
+
- lib/scss_lint/linter/name_format.rb
|
102
|
+
- lib/scss_lint/linter/placeholder_in_extend.rb
|
103
|
+
- lib/scss_lint/linter/property_sort_order.rb
|
104
|
+
- lib/scss_lint/linter/property_spelling.rb
|
105
|
+
- lib/scss_lint/linter/selector_depth.rb
|
106
|
+
- lib/scss_lint/linter/shorthand.rb
|
126
107
|
- lib/scss_lint/linter/single_line_per_selector.rb
|
127
|
-
- lib/scss_lint/
|
128
|
-
- lib/scss_lint/
|
108
|
+
- lib/scss_lint/linter/space_after_comma.rb
|
109
|
+
- lib/scss_lint/linter/space_after_property_colon.rb
|
110
|
+
- lib/scss_lint/linter/space_after_property_name.rb
|
111
|
+
- lib/scss_lint/linter/space_before_brace.rb
|
112
|
+
- lib/scss_lint/linter/space_between_parens.rb
|
113
|
+
- lib/scss_lint/linter/string_quotes.rb
|
114
|
+
- lib/scss_lint/linter/trailing_semicolon_after_property_value.rb
|
115
|
+
- lib/scss_lint/linter/url_format.rb
|
116
|
+
- lib/scss_lint/linter/url_quotes.rb
|
117
|
+
- lib/scss_lint/linter/zero_unit.rb
|
118
|
+
- lib/scss_lint/linter.rb
|
129
119
|
- lib/scss_lint/linter_registry.rb
|
120
|
+
- lib/scss_lint/rake_task.rb
|
121
|
+
- lib/scss_lint/reporter/default_reporter.rb
|
122
|
+
- lib/scss_lint/reporter/files_reporter.rb
|
123
|
+
- lib/scss_lint/reporter/xml_reporter.rb
|
124
|
+
- lib/scss_lint/reporter.rb
|
125
|
+
- lib/scss_lint/runner.rb
|
126
|
+
- lib/scss_lint/sass/script.rb
|
127
|
+
- lib/scss_lint/sass/tree.rb
|
128
|
+
- lib/scss_lint/selector_visitor.rb
|
129
|
+
- lib/scss_lint/utils.rb
|
130
|
+
- lib/scss_lint/version.rb
|
130
131
|
- lib/scss_lint.rb
|
131
132
|
- bin/scss-lint
|
132
133
|
homepage: https://github.com/causes/scss-lint
|