scss-lint 0.10.1 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69f5645967ac2ed4c054af95508d25ffb88328f7
4
- data.tar.gz: b8d83cdd575da8e42307dedfdeb32d2bb264a210
3
+ metadata.gz: 62980ca32775a70ec7170fc8b7399eb13b304c7b
4
+ data.tar.gz: 76fa2ea621edad2ad9ebc9d0e2b302b57c43a70d
5
5
  SHA512:
6
- metadata.gz: 4cd037b4f7b02d0b011e2fc0db246cdfafa8f69a78dc2ad49e66d81df3e470f07731b4d23c115fc700426fc2c5f4dd41578be8b937a8449e4a977ef308944a40
7
- data.tar.gz: dffa479078fac884d6ead1759882a9d23b1f1212618418b89a78b9fce1b2e0cf061817a26f9b523ae246bb7bb16a6b2ec7da52107b1487cc560822f38e2ac778
6
+ metadata.gz: ce7dfa08c1c68044da63de6f376a3ce483e5145eaa7854668b616dbd0b1596c983e7dbc5f510c8cdbf3d27f47658b21cebe5f0caa63b9c9a888ef0d0df772729
7
+ data.tar.gz: dae5b62b186b24c851394b7e18c16e45f4f1281a2046c7f6a00513deb94d8300df30e8a5e7e1d3845c77f9efe68f1fef5c9e4f059239499b55e56cf4ff24f0c4
@@ -1,12 +1,58 @@
1
- # Contains extensions of Sass::Script::Nodes to add support for accessing
2
- # various parts of the parse tree not provided out-of-the-box.
3
1
  module Sass::Script
4
- class Variable
5
- # When accessing keyword arguments, the Sass parser treats the underscored
6
- # name as canonical. Since this only matters during the compilation step, we
7
- # can safely override the behaviour to return the original name.
8
- def underscored_name
9
- @name
2
+ # Redefine some of the lexer helpers in order to store the original string
3
+ # with the created object so that the original string can be inspected rather
4
+ # than a typically normalized version.
5
+ class Lexer
6
+ def color
7
+ return unless color_string = scan(REGULAR_EXPRESSIONS[:color])
8
+
9
+ unless [4, 7].include?(color_string.length)
10
+ raise ::Sass::SyntaxError,
11
+ "Colors must have either three or six digits: '#{color_string}'"
12
+ end
13
+
14
+ [:color, Value::Color.from_string(color_string)]
15
+ end
16
+
17
+ def number
18
+ return unless scan(REGULAR_EXPRESSIONS[:number])
19
+ value = @scanner[2] ? @scanner[2].to_f : @scanner[3].to_i
20
+ value = -value if @scanner[1]
21
+
22
+ number = Value::Number.new(value, Array(@scanner[4])).tap do |num|
23
+ num.original_string = @scanner[0]
24
+ end
25
+ [:number, number]
26
+ end
27
+ end
28
+
29
+ class Parser
30
+ # We redefine the ident parser to specially handle color keywords.
31
+ def ident
32
+ return funcall unless @lexer.peek && @lexer.peek.type == :ident
33
+ return if @stop_at && @stop_at.include?(@lexer.peek.value)
34
+
35
+ name = @lexer.next
36
+ if (color = Value::Color::COLOR_NAMES[name.value.downcase])
37
+ return literal_node(Value::Color.from_string(name.value, color), name.source_range)
38
+ end
39
+ literal_node(Value::String.new(name.value, :identifier), name.source_range)
40
+ end
41
+ end
42
+
43
+ class Value::Base
44
+ attr_accessor :node_parent
45
+
46
+ def children
47
+ []
48
+ end
49
+
50
+ def line
51
+ @line || (node_parent && node_parent.line)
52
+ end
53
+
54
+ def source_range
55
+ @source_range || (node_parent && node_parent.source_range)
10
56
  end
11
57
  end
12
58
 
@@ -14,8 +60,8 @@ module Sass::Script
14
60
  # color string. This adds an attribute to the Color to keep track of the
15
61
  # original string and provides a method which the modified lexer can use to
16
62
  # set it.
17
- class Color
18
- attr_accessor :original
63
+ class Value::Color
64
+ attr_accessor :original_string
19
65
 
20
66
  def self.from_string(string, rgb = nil)
21
67
  unless rgb
@@ -24,41 +70,29 @@ module Sass::Script
24
70
  map { |hex| hex.ljust(2, hex).to_i(16) }
25
71
  end
26
72
 
27
- color = Color.new(rgb, false)
28
- color.original = string
73
+ color = new(rgb, false)
74
+ color.original_string = string
29
75
  color
30
76
  end
31
77
  end
32
78
 
33
- class Lexer
34
- # We redefine the color lexer to store the original string with the created
35
- # `Color` object so that we can inspect the original string before it is
36
- # normalized.
37
- #
38
- # This is an adapted version from the original Sass source code.
39
- def color
40
- return unless color_string = scan(REGULAR_EXPRESSIONS[:color])
41
-
42
- unless [4, 7].include?(color_string.length)
43
- raise ::Sass::SyntaxError,
44
- "Colors must have either three or six digits: '#{color_string}'"
45
- end
46
-
47
- [:color, Color.from_string(color_string)]
48
- end
79
+ class Value::Number
80
+ attr_accessor :original_string
49
81
  end
50
82
 
51
- class Parser
52
- # We redefine the ident parser to specially handle color keywords.
53
- def ident
54
- return funcall unless @lexer.peek && @lexer.peek.type == :ident
55
- return if @stop_at && @stop_at.include?(@lexer.peek.value)
83
+ # Contains extensions of Sass::Script::Tree::Nodes to add support for
84
+ # accessing various parts of the parse tree not provided out-of-the-box.
85
+ module Tree
86
+ class Node
87
+ attr_accessor :node_parent
88
+ end
56
89
 
57
- name = @lexer.next
58
- if color = Color::COLOR_NAMES[name.value.downcase]
59
- return node(Color.from_string(name.value, color))
90
+ class Literal
91
+ # Literals wrap their underlying values. For sake of convenience, consider
92
+ # the wrapped value a child of the Literal.
93
+ def children
94
+ [value]
60
95
  end
61
- node(Sass::Script::String.new(name.value, :identifier))
62
96
  end
63
97
  end
64
98
  end
@@ -5,6 +5,9 @@
5
5
  module Sass::Tree
6
6
  # Define some common helper code for use in the various monkey patchings.
7
7
  class Node
8
+ # Stores node for which this node is a direct child
9
+ attr_accessor :node_parent
10
+
8
11
  # The `args` field of some Sass::Tree::Node classes returns
9
12
  # Sass::Script::Variable nodes with no line numbers. This adds the line
10
13
  # numbers back in so lint reporting works for those nodes.
@@ -17,7 +20,7 @@ module Sass::Tree
17
20
  # The Sass parser sometimes doesn't assign line numbers in cases where it
18
21
  # should. This is a helper to easily correct that.
19
22
  def add_line_number(node)
20
- node.line ||= line if node.is_a?(Sass::Script::Node)
23
+ node.line ||= line if node.is_a?(::Sass::Script::Tree::Node)
21
24
  node
22
25
  end
23
26
 
@@ -25,7 +28,7 @@ module Sass::Tree
25
28
  # the name of the variable. This helper takes that name and turns it back
26
29
  # into a Sass::Script::Variable that supports lint reporting.
27
30
  def create_variable(var_name)
28
- Sass::Script::Variable.new(var_name).tap do |v|
31
+ ::Sass::Script::Tree::Variable.new(var_name).tap do |v|
29
32
  v.line = line # Use line number of the containing parse tree node
30
33
  end
31
34
  end
@@ -34,7 +37,7 @@ module Sass::Tree
34
37
  # Sass::Script::Nodes interspersed within them. This returns a filtered list
35
38
  # of just those nodes.
36
39
  def extract_script_nodes(list)
37
- list.select { |item| item.is_a? Sass::Script::Node }
40
+ list.select { |item| item.is_a?(::Sass::Script::Tree::Node) }
38
41
  end
39
42
 
40
43
  # Takes a list of arguments, be they arrays or individual objects, and
@@ -70,7 +73,9 @@ module Sass::Tree
70
73
 
71
74
  class EachNode
72
75
  def children
73
- concat_expr_lists super, create_variable(var), list
76
+ loop_vars = vars.map { |var| create_variable(var) }
77
+
78
+ concat_expr_lists super, loop_vars, list
74
79
  end
75
80
  end
76
81
 
@@ -114,9 +119,9 @@ module Sass::Tree
114
119
 
115
120
  # Keyword mapping is String -> Expr, so convert the string to a variable
116
121
  # node that supports lint reporting
117
- keyword_exprs = keywords.map do |var_name, var_expr|
122
+ keyword_exprs = keywords.as_stored.map do |var_name, var_expr|
118
123
  [create_variable(var_name), var_expr]
119
- end
124
+ end if keywords.any?
120
125
 
121
126
  concat_expr_lists super, args, keyword_exprs, splat
122
127
  end
@@ -1,11 +1,16 @@
1
1
  module SCSSLint
2
2
  class Lint
3
- attr_reader :filename, :line, :description
3
+ attr_reader :filename, :line, :description, :severity
4
4
 
5
- def initialize(filename, line, description)
5
+ def initialize(filename, line, description, severity = :warning)
6
6
  @filename = filename
7
7
  @line = line
8
8
  @description = description
9
+ @severity = severity
10
+ end
11
+
12
+ def error?
13
+ severity == :error
9
14
  end
10
15
  end
11
16
  end
@@ -20,17 +20,20 @@ module SCSSLint
20
20
  end
21
21
 
22
22
  # Helper for creating lint from a parse tree node
23
- def add_lint(node, message = nil)
23
+ def add_lint(node_or_line, message = nil)
24
+ line = node_or_line.respond_to?(:line) ? node_or_line.line : node_or_line
25
+
24
26
  @lints << Lint.new(engine.filename,
25
- node.line,
27
+ line,
26
28
  message || description)
27
29
  end
28
30
 
29
31
  # Monkey-patched implementation that adds support for traversing
30
32
  # Sass::Script::Nodes (original implementation only supports
31
33
  # Sass::Tree::Nodes).
32
- def node_name(node)
33
- if node.is_a?(Sass::Script::Node)
34
+ def self.node_name(node)
35
+ case node
36
+ when Sass::Script::Tree::Node, Sass::Script::Value::Base
34
37
  "script_#{node.class.name.gsub(/.*::(.*?)$/, '\\1').downcase}"
35
38
  else
36
39
  super
@@ -46,5 +49,13 @@ module SCSSLint
46
49
 
47
50
  super
48
51
  end
52
+
53
+ # Redefine so we can set the `node_parent` of each node
54
+ def visit_children(parent)
55
+ parent.children.each do |child|
56
+ child.node_parent = parent
57
+ visit(child)
58
+ end
59
+ end
49
60
  end
50
61
  end
@@ -3,7 +3,7 @@ module SCSSLint
3
3
  include LinterRegistry
4
4
 
5
5
  def visit_script_color(node)
6
- add_color_lint(node, node.original) if color_keyword?(node.original)
6
+ add_color_lint(node, node.original_string) if color_keyword?(node.original_string)
7
7
  end
8
8
 
9
9
  def visit_script_string(node)
@@ -17,28 +17,21 @@ module SCSSLint
17
17
  private
18
18
 
19
19
  def add_color_lint(node, original)
20
- hex_form = Sass::Script::Color.new(color_rgb(original)).inspect
20
+ hex_form = Sass::Script::Value::Color.new(color_rgb(original)).tap do |color|
21
+ color.options = {} # `inspect` requires options to be set
22
+ end.inspect
23
+
21
24
  add_lint(node,
22
25
  "Color `#{original}` should be written in hexadecimal form " <<
23
26
  "as `#{shortest_hex_form(hex_form)}`")
24
27
  end
25
28
 
26
29
  def color_keyword?(string)
27
- !!color_rgb(string)
30
+ !!color_rgb(string) && string != 'transparent'
28
31
  end
29
32
 
30
33
  def color_rgb(string)
31
- Sass::Script::Color::COLOR_NAMES[string]
32
- end
33
-
34
- # Takes a string like `hello "world" 'how are' you` and turns it into:
35
- # `hello you`.
36
- # This is useful for scanning for keywords in shorthand properties or lists
37
- # which can contain quoted strings but for which you don't want to inspect
38
- # quoted strings (e.g. you care about the actual color keyword `red`, not
39
- # the string "red").
40
- def remove_quoted_strings(string)
41
- string.gsub(/"[^"]*"|'[^']*'/, '')
34
+ Sass::Script::Value::Color::COLOR_NAMES[string]
42
35
  end
43
36
  end
44
37
  end
@@ -0,0 +1,23 @@
1
+ module SCSSLint
2
+ class Linter::DuplicateProperty < Linter
3
+ include LinterRegistry
4
+
5
+ def visit_rule(node)
6
+ properties = node.children
7
+ .select { |child| child.is_a?(Sass::Tree::PropNode) }
8
+ .reject { |prop| prop.name.any? { |item| item.is_a?(Sass::Script::Node) } }
9
+
10
+ prop_names = {}
11
+
12
+ properties.each do |prop|
13
+ name = prop.name.join
14
+
15
+ if existing_prop = prop_names[name]
16
+ add_lint(prop, "Property '#{name}' already defined on line #{existing_prop.line}")
17
+ else
18
+ prop_names[name] = prop
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,10 +3,10 @@ module SCSSLint
3
3
  include LinterRegistry
4
4
 
5
5
  def visit_script_color(node)
6
- return unless node.original && node.original.match(HEX_REGEX)
6
+ return unless node.original_string && node.original_string.match(HEX_REGEX)
7
7
 
8
- unless valid_hex_format?(node.original[HEX_REGEX, 1])
9
- add_hex_lint(node, node.original)
8
+ unless valid_hex_format?(node.original_string[HEX_REGEX, 1])
9
+ add_hex_lint(node, node.original_string)
10
10
  end
11
11
  end
12
12
 
@@ -0,0 +1,71 @@
1
+ module SCSSLint
2
+ class Linter::Indentation < Linter
3
+ include LinterRegistry
4
+
5
+ def visit_root(node)
6
+ @indent = 0
7
+ yield
8
+ end
9
+
10
+ def check_and_visit_children(node)
11
+ # Don't continue checking children as the moment a parent's indentation is
12
+ # off it's likely the children will be as will. We don't display the child
13
+ # indentation problems as that would likely make the lint too noisy.
14
+ return if check_indentation(node)
15
+
16
+ @indent += INDENT_WIDTH
17
+ yield
18
+ @indent -= INDENT_WIDTH
19
+ end
20
+
21
+ def check_indentation(node)
22
+ return unless node.line
23
+
24
+ # Ignore the case where the node is on the same line as its previous
25
+ # sibling or its parent, as indentation isn't possible
26
+ return if (previous = previous_node(node)) && previous.line == node.line
27
+
28
+ actual_indent = engine.lines[node.line - 1][/^(\s*)/, 1]
29
+
30
+ if actual_indent.length != @indent
31
+ add_lint(node.line,
32
+ "Line should be indented #{@indent} spaces, " <<
33
+ "but was indented #{actual_indent.length} spaces")
34
+ return true
35
+ end
36
+ end
37
+
38
+ # Deal with `else` statements
39
+ def visit_if(node, &block)
40
+ check_and_visit_children(node, &block)
41
+ visit(node.else) if node.else
42
+ end
43
+
44
+ # Define node types that increase indentation level
45
+ alias :visit_directive :check_and_visit_children
46
+ alias :visit_each :check_and_visit_children
47
+ alias :visit_for :check_and_visit_children
48
+ alias :visit_function :check_and_visit_children
49
+ alias :visit_media :check_and_visit_children
50
+ alias :visit_mixin :check_and_visit_children
51
+ alias :visit_mixindef :check_and_visit_children
52
+ alias :visit_prop :check_and_visit_children
53
+ alias :visit_rule :check_and_visit_children
54
+ alias :visit_supports :check_and_visit_children
55
+ alias :visit_while :check_and_visit_children
56
+
57
+ # Define node types to check indentation of (notice comments are left out)
58
+ alias :visit_charset :check_indentation
59
+ alias :visit_content :check_indentation
60
+ alias :visit_cssimport :check_indentation
61
+ alias :visit_extend :check_indentation
62
+ alias :visit_import :check_indentation
63
+ alias :visit_return :check_indentation
64
+ alias :visit_variable :check_indentation
65
+ alias :visit_warn :check_indentation
66
+
67
+ private
68
+
69
+ INDENT_WIDTH = 2
70
+ end
71
+ end
@@ -0,0 +1,32 @@
1
+ module SCSSLint
2
+ class Linter::LeadingZero < Linter
3
+ include LinterRegistry
4
+
5
+ def visit_script_string(node)
6
+ return unless node.type == :identifier
7
+
8
+ non_string_values = remove_quoted_strings(node.value).split
9
+
10
+ non_string_values.each do |value|
11
+ if number = value[/\b(0\.\d+)/, 1]
12
+ add_leading_zero_lint(node, number)
13
+ end
14
+ end
15
+ end
16
+
17
+ def visit_script_number(node)
18
+ if node.original_string =~ /^0\./
19
+ add_leading_zero_lint(node, node.original_string)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def add_leading_zero_lint(node, number)
26
+ trimmed_number = number[/^[^\.]+(.*)$/, 1]
27
+
28
+ add_lint(node, "`#{number}` should be written without a leading zero " <<
29
+ "as `#{trimmed_number}`")
30
+ end
31
+ end
32
+ end
@@ -3,47 +3,67 @@ module SCSSLint
3
3
  include LinterRegistry
4
4
 
5
5
  def visit_prop(node)
6
- return unless SHORTHANDABLE_PROPERTIES.include? node.name.first.to_s
6
+ property_name = node.name.join
7
+ return unless SHORTHANDABLE_PROPERTIES.include?(property_name)
7
8
 
8
9
  case node.value
9
- when Sass::Script::List
10
- items = node.value.children
11
- if (2..4).member?(items.count)
12
- add_lint(node) unless valid_shorthand?(*items.map(&:to_sass))
13
- end
14
- when Sass::Script::String
15
- if node.value.to_sass.strip =~ /\A(\S+\s+\S+(\s+\S+){0,2})\Z/
16
- add_lint(node) unless valid_shorthand?(*$1.split(/\s+/))
17
- end
10
+ when Sass::Script::Tree::Literal
11
+ # HACK: node_parent may not be initialized at this point, so we need to
12
+ # set it ourselves
13
+ node.value.value.node_parent = node.value
14
+ check_script_string(property_name, node.value.value)
15
+ when Sass::Script::Tree::ListLiteral
16
+ check_script_list(property_name, node.value)
18
17
  end
19
18
  end
20
19
 
21
- def description
22
- 'Property values should use the shortest shorthand syntax allowed'
20
+ private
21
+
22
+ SHORTHANDABLE_PROPERTIES = %w[
23
+ border-color
24
+ border-radius
25
+ border-style
26
+ border-width
27
+ margin
28
+ padding
29
+ ]
30
+
31
+ def check_script_list(prop, list)
32
+ check_shorthand(prop, list, list.children.map(&:to_sass))
23
33
  end
24
34
 
25
- private
35
+ def check_script_string(prop, script_string)
36
+ return unless script_string.type == :identifier
37
+
38
+ if values = script_string.value.strip[/\A(\S+\s+\S+(\s+\S+){0,2})\z/, 1]
39
+ check_shorthand(prop, script_string, values.split)
40
+ end
41
+ end
42
+
43
+ def check_shorthand(prop, node, values)
44
+ return unless (2..4).member?(values.count)
26
45
 
27
- SHORTHANDABLE_PROPERTIES = %w[border-color
28
- border-radius
29
- border-style
30
- border-width
31
- margin
32
- padding]
46
+ shortest_form = condensed_shorthand(*values)
47
+ return if values == shortest_form
48
+
49
+ add_lint(node, "Shorthand form for property `#{prop}` should be " <<
50
+ "written more concisely as `#{shortest_form.join(' ')}` " <<
51
+ "instead of `#{values.join(' ')}`")
52
+ end
33
53
 
34
- def valid_shorthand?(top, right, bottom = nil, left = nil)
54
+ def condensed_shorthand(top, right, bottom = nil, left = nil)
35
55
  if top == right && right == bottom && bottom == left
36
- false
56
+ [top]
37
57
  elsif top == right && bottom.nil? && left.nil?
38
- false
58
+ [top]
39
59
  elsif top == bottom && right == left
40
- false
60
+ [top, right]
41
61
  elsif top == bottom && left.nil?
42
- false
62
+ top == right ? [top] : [top, right]
43
63
  elsif right == left
44
- false
64
+ [top, right, bottom]
45
65
  else
46
- true
66
+ [top, right, bottom, left].compact
47
67
  end
48
68
  end
49
69
  end
@@ -2,21 +2,15 @@ module SCSSLint
2
2
  class Linter::ZeroUnit < Linter
3
3
  include LinterRegistry
4
4
 
5
- def visit_prop(node)
6
- if node.value.is_a?(Sass::Script::String) &&
7
- node.value.type == :identifier
8
-
9
- node.value.value.scan(/\b(0[a-z]+)\b/i) do |match|
10
- add_lint(node, MESSAGE_FORMAT % match.first)
11
- end
5
+ def visit_script_string(node)
6
+ node.value.scan(/\b(0[a-z]+)\b/i) do |match|
7
+ add_lint(node, MESSAGE_FORMAT % match.first)
12
8
  end
13
-
14
- yield # Continue visiting children
15
9
  end
16
10
 
17
11
  def visit_script_number(node)
18
12
  if node.value == 0 && !node.unitless?
19
- add_lint(node, MESSAGE_FORMAT % node.original)
13
+ add_lint(node, MESSAGE_FORMAT % node.original_string)
20
14
  end
21
15
  end
22
16
 
@@ -5,7 +5,9 @@ module SCSSLint
5
5
  def report_lints
6
6
  if lints.any?
7
7
  lints.map do |lint|
8
- "#{lint.filename}:".yellow + "#{lint.line} - #{lint.description}"
8
+ type = lint.error? ? '[E]'.red : '[W]'.yellow
9
+ "#{lint.filename.cyan}:" << "#{lint.line}".magenta <<
10
+ " #{type} #{lint.description}"
9
11
  end.join("\n") + "\n"
10
12
  end
11
13
  end
@@ -8,7 +8,9 @@ module SCSSLint
8
8
  output << "<file name='#{filename}'>"
9
9
 
10
10
  file_lints.each do |lint|
11
- output << "<issue line='#{lint.line}' severity='warning' reason='#{lint.description}' />"
11
+ output << "<issue line='#{lint.line}' " <<
12
+ "severity='#{lint.severity}' " <<
13
+ "reason='#{lint.description}' />"
12
14
  end
13
15
 
14
16
  output << '</file>'
@@ -39,7 +39,7 @@ module SCSSLint
39
39
  linter.run(engine)
40
40
  end
41
41
  rescue Sass::SyntaxError => ex
42
- @lints << Lint.new(ex.sass_filename, ex.sass_line, ex.to_s)
42
+ @lints << Lint.new(ex.sass_filename, ex.sass_line, ex.to_s, :error)
43
43
  end
44
44
 
45
45
  def lints?
@@ -34,6 +34,27 @@ module SCSSLint
34
34
  hex[5] == hex[6]
35
35
  end
36
36
 
37
+ # Takes a string like `hello "world" 'how are' you` and turns it into:
38
+ # `hello you`.
39
+ # This is useful for scanning for keywords in shorthand properties or lists
40
+ # which can contain quoted strings but for which you don't want to inspect
41
+ # quoted strings (e.g. you care about the actual color keyword `red`, not
42
+ # the string "red").
43
+ def remove_quoted_strings(string)
44
+ string.gsub(/"[^"]*"|'[^']*'/, '')
45
+ end
46
+
47
+ def previous_node(node)
48
+ return unless node && parent = node.node_parent
49
+ index = parent.children.index(node)
50
+
51
+ if index == 0
52
+ parent
53
+ else
54
+ parent.children[index - 1]
55
+ end
56
+ end
57
+
37
58
  private
38
59
 
39
60
  INVALID_NAME_CHARS = '[_A-Z]'
@@ -1,3 +1,3 @@
1
1
  module SCSSLint
2
- VERSION = '0.10.1'
2
+ VERSION = '0.11.1'
3
3
  end
metadata CHANGED
@@ -1,71 +1,72 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scss-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Causes Engineering
8
+ - Shane da Silva
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-09-21 00:00:00.000000000 Z
12
+ date: 2013-10-21 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: colorize
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - '>='
18
+ - - '='
18
19
  - !ruby/object:Gem::Version
19
- version: '0'
20
+ version: 0.5.8
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - '>='
25
+ - - '='
25
26
  - !ruby/object:Gem::Version
26
- version: '0'
27
+ version: 0.5.8
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: sass
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
32
  - - '='
32
33
  - !ruby/object:Gem::Version
33
- version: 3.2.10
34
+ version: 3.3.0.rc.1
34
35
  type: :runtime
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
39
  - - '='
39
40
  - !ruby/object:Gem::Version
40
- version: 3.2.10
41
+ version: 3.3.0.rc.1
41
42
  - !ruby/object:Gem::Dependency
42
43
  name: nokogiri
43
44
  requirement: !ruby/object:Gem::Requirement
44
45
  requirements:
45
- - - '>='
46
+ - - '='
46
47
  - !ruby/object:Gem::Version
47
- version: '0'
48
+ version: 1.6.0
48
49
  type: :development
49
50
  prerelease: false
50
51
  version_requirements: !ruby/object:Gem::Requirement
51
52
  requirements:
52
- - - '>='
53
+ - - '='
53
54
  - !ruby/object:Gem::Version
54
- version: '0'
55
+ version: 1.6.0
55
56
  - !ruby/object:Gem::Dependency
56
57
  name: rspec
57
58
  requirement: !ruby/object:Gem::Requirement
58
59
  requirements:
59
- - - '>='
60
+ - - '='
60
61
  - !ruby/object:Gem::Version
61
- version: '0'
62
+ version: 2.13.0
62
63
  type: :development
63
64
  prerelease: false
64
65
  version_requirements: !ruby/object:Gem::Requirement
65
66
  requirements:
66
- - - '>='
67
+ - - '='
67
68
  - !ruby/object:Gem::Version
68
- version: '0'
69
+ version: 2.13.0
69
70
  description: Opinionated tool to help write clean and consistent SCSS
70
71
  email:
71
72
  - eng@causes.com
@@ -87,19 +88,21 @@ files:
87
88
  - lib/scss_lint/linter/property_format.rb
88
89
  - lib/scss_lint/linter/space_before_brace.rb
89
90
  - lib/scss_lint/linter/capitalization_in_selector.rb
91
+ - lib/scss_lint/linter/indentation.rb
90
92
  - lib/scss_lint/linter/declared_name.rb
91
93
  - lib/scss_lint/linter/sorted_properties.rb
92
94
  - lib/scss_lint/linter/shorthand.rb
93
95
  - lib/scss_lint/linter/id_with_extraneous_selector.rb
94
96
  - lib/scss_lint/linter/declaration_order.rb
95
- - lib/scss_lint/linter/no_zero_before_decimal.rb
96
97
  - lib/scss_lint/linter/zero_unit.rb
97
98
  - lib/scss_lint/linter/placeholder_in_extend.rb
98
99
  - lib/scss_lint/linter/usage_name.rb
99
100
  - lib/scss_lint/linter/border_zero.rb
100
101
  - lib/scss_lint/linter/debug_statement.rb
102
+ - lib/scss_lint/linter/duplicate_property.rb
101
103
  - lib/scss_lint/linter/hex_format.rb
102
104
  - lib/scss_lint/linter/color_keyword.rb
105
+ - lib/scss_lint/linter/leading_zero.rb
103
106
  - lib/scss_lint/linter/comment.rb
104
107
  - lib/scss_lint/linter/empty_rule.rb
105
108
  - lib/scss_lint/linter/single_line_per_selector.rb
@@ -1,22 +0,0 @@
1
- module SCSSLint
2
- class Linter::NoZeroBeforeDecimal < Linter
3
- include LinterRegistry
4
-
5
- def visit_prop(node)
6
- # Misleading, but anything that isn't Sass Script is considered an
7
- # `identifier` in the context of a Sass::Script::String.
8
- return unless node.value.is_a?(Sass::Script::String) && node.value.type == :identifier
9
-
10
- # Remove string chunks (e.g. `"hello" 3 'world'` -> `3`
11
- non_string_values = node.value.value.gsub(/"[^"]*"|'[^']'/, '').split
12
-
13
- non_string_values.each do |value|
14
- add_lint(node) if value =~ /\b0\.\d+/
15
- end
16
- end
17
-
18
- def description
19
- 'Leading zero should be omitted in fractional values'
20
- end
21
- end
22
- end