scss-lint 0.30.0 → 0.31.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/bin/scss-lint +1 -4
  3. data/config/default.yml +5 -4
  4. data/data/property-sort-orders/recess.txt +149 -0
  5. data/data/property-sort-orders/smacss.txt +138 -0
  6. data/lib/scss_lint.rb +1 -0
  7. data/lib/scss_lint/cli.rb +93 -153
  8. data/lib/scss_lint/config.rb +16 -13
  9. data/lib/scss_lint/control_comment_processor.rb +83 -0
  10. data/lib/scss_lint/engine.rb +21 -5
  11. data/lib/scss_lint/exceptions.rb +6 -0
  12. data/lib/scss_lint/linter.rb +6 -2
  13. data/lib/scss_lint/linter/bang_format.rb +20 -9
  14. data/lib/scss_lint/linter/duplicate_property.rb +35 -30
  15. data/lib/scss_lint/linter/empty_line_between_blocks.rb +1 -1
  16. data/lib/scss_lint/linter/id_selector.rb +10 -0
  17. data/lib/scss_lint/linter/indentation.rb +2 -1
  18. data/lib/scss_lint/linter/leading_zero.rb +6 -6
  19. data/lib/scss_lint/linter/name_format.rb +11 -0
  20. data/lib/scss_lint/linter/selector_format.rb +0 -4
  21. data/lib/scss_lint/linter/single_line_per_property.rb +13 -7
  22. data/lib/scss_lint/linter/single_line_per_selector.rb +19 -11
  23. data/lib/scss_lint/linter/trailing_semicolon.rb +5 -3
  24. data/lib/scss_lint/linter/trailing_zero.rb +4 -4
  25. data/lib/scss_lint/options.rb +113 -0
  26. data/lib/scss_lint/reporter/default_reporter.rb +15 -7
  27. data/lib/scss_lint/reporter/json_reporter.rb +15 -8
  28. data/lib/scss_lint/reporter/xml_reporter.rb +12 -6
  29. data/lib/scss_lint/runner.rb +4 -5
  30. data/lib/scss_lint/version.rb +1 -1
  31. data/spec/scss_lint/cli_spec.rb +9 -229
  32. data/spec/scss_lint/linter/bang_format_spec.rb +20 -0
  33. data/spec/scss_lint/linter/duplicate_property_spec.rb +13 -0
  34. data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +12 -11
  35. data/spec/scss_lint/linter/id_selector_spec.rb +62 -0
  36. data/spec/scss_lint/linter/indentation_spec.rb +11 -0
  37. data/spec/scss_lint/linter/name_format_spec.rb +147 -117
  38. data/spec/scss_lint/linter/selector_format_spec.rb +3 -66
  39. data/spec/scss_lint/linter/trailing_semicolon_spec.rb +20 -0
  40. data/spec/scss_lint/linter_spec.rb +248 -0
  41. data/spec/scss_lint/options_spec.rb +42 -0
  42. data/spec/spec_helper.rb +1 -1
  43. metadata +177 -183
  44. data/lib/scss_lint/linter/id_with_extraneous_selector.rb +0 -20
  45. data/spec/scss_lint/linter/id_with_extraneous_selector_spec.rb +0 -139
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63daef837600174964f65634095dac45b13a1bb2
4
- data.tar.gz: 8b8e1fdebc6d40d577c02a0092c092212f0d46ee
3
+ metadata.gz: 67663cf8293192d8f0962e8fe04c86d2b2dafddb
4
+ data.tar.gz: 92271e0c11e57a9088be1bd94437b7c07c31e205
5
5
  SHA512:
6
- metadata.gz: 6ed4cbb25cacdfdf0645ea476ccc86032ae8032c22fdb1b3cf8fdd6934601bdc075aa4ed71fa1a05d2dec08785ceb591d53eeb2c6541b5567f434ff4ce161d20
7
- data.tar.gz: 07a85bc0d214819857e179babe4b465193adf01391f7eecadd25611264c28605e0990911e1eb6dd75ed79b65b0cb50b6529187513e6842674e5c5abeafeca5f2
6
+ metadata.gz: 7048b50c46c68b5d7cae9dea14a37791e550a40092b7d3443d266076fb5bfebf1d858b66eb8f6d8c147a75f54deafcbc3d72eb03740ed51f1b79a9406e925217
7
+ data.tar.gz: e89a5be79049adc3e1aa69e761a961ba711cab010843a54031e7ecdfc546c12c5647ff7b407f875be6577c3d22e817976cdb71fd39f3dc0d7f4bd045e2dfdca1
@@ -3,7 +3,4 @@
3
3
  require 'scss_lint'
4
4
  require 'scss_lint/cli'
5
5
 
6
- SCSSLint::CLI.new(ARGV).tap do |cli|
7
- cli.parse_arguments
8
- cli.run
9
- end
6
+ exit SCSSLint::CLI.new.run(ARGV)
@@ -52,7 +52,7 @@ linters:
52
52
  HexValidation:
53
53
  enabled: true
54
54
 
55
- IdWithExtraneousSelector:
55
+ IdSelector:
56
56
  enabled: true
57
57
 
58
58
  ImportPath:
@@ -75,6 +75,7 @@ linters:
75
75
 
76
76
  NameFormat:
77
77
  enabled: true
78
+ allow_leading_underscore: true
78
79
  convention: hyphenated_lowercase # or 'BEM', or a regex pattern
79
80
 
80
81
  NestingDepth:
@@ -94,9 +95,9 @@ linters:
94
95
 
95
96
  QualifyingElement:
96
97
  enabled: true
97
- allow_with_attribute: false
98
- allow_with_class: false
99
- allow_with_id: false
98
+ allow_element_with_attribute: false
99
+ allow_element_with_class: false
100
+ allow_element_with_id: false
100
101
 
101
102
  SelectorDepth:
102
103
  enabled: true
@@ -0,0 +1,149 @@
1
+ # RECESS Property Order
2
+ # https://github.com/twitter/recess
3
+
4
+ position
5
+ top
6
+ right
7
+ bottom
8
+ left
9
+ z-index
10
+ display
11
+ float
12
+ width
13
+ height
14
+ max-width
15
+ max-height
16
+ min-width
17
+ min-height
18
+ padding
19
+ padding-top
20
+ padding-right
21
+ padding-bottom
22
+ padding-left
23
+ margin
24
+ margin-top
25
+ margin-right
26
+ margin-bottom
27
+ margin-left
28
+ margin-collapse
29
+ margin-top-collapse
30
+ margin-right-collapse
31
+ margin-bottom-collapse
32
+ margin-left-collapse
33
+ overflow
34
+ overflow-x
35
+ overflow-y
36
+ clip
37
+ clear
38
+ font
39
+ font-family
40
+ font-size
41
+ font-smoothing
42
+ osx-font-smoothing
43
+ font-style
44
+ font-weight
45
+ hyphens
46
+ src
47
+ line-height
48
+ letter-spacing
49
+ word-spacing
50
+ color
51
+ text-align
52
+ text-decoration
53
+ text-indent
54
+ text-overflow
55
+ text-rendering
56
+ text-size-adjust
57
+ text-shadow
58
+ text-transform
59
+ word-break
60
+ word-wrap
61
+ white-space
62
+ vertical-align
63
+ list-style
64
+ list-style-type
65
+ list-style-position
66
+ list-style-image
67
+ pointer-events
68
+ cursor
69
+ background
70
+ background-attachment
71
+ background-color
72
+ background-image
73
+ background-position
74
+ background-repeat
75
+ background-size
76
+ border
77
+ border-collapse
78
+ border-top
79
+ border-right
80
+ border-bottom
81
+ border-left
82
+ border-color
83
+ border-image
84
+ border-top-color
85
+ border-right-color
86
+ border-bottom-color
87
+ border-left-color
88
+ border-spacing
89
+ border-style
90
+ border-top-style
91
+ border-right-style
92
+ border-bottom-style
93
+ border-left-style
94
+ border-width
95
+ border-top-width
96
+ border-right-width
97
+ border-bottom-width
98
+ border-left-width
99
+ border-radius
100
+ border-top-right-radius
101
+ border-bottom-right-radius
102
+ border-bottom-left-radius
103
+ border-top-left-radius
104
+ border-radius-topright
105
+ border-radius-bottomright
106
+ border-radius-bottomleft
107
+ border-radius-topleft
108
+ content
109
+ quotes
110
+ outline
111
+ outline-offset
112
+ opacity
113
+ filter
114
+ visibility
115
+ size
116
+ zoom
117
+ transform
118
+ box-align
119
+ box-flex
120
+ box-orient
121
+ box-pack
122
+ box-shadow
123
+ box-sizing
124
+ table-layout
125
+ animation
126
+ animation-delay
127
+ animation-duration
128
+ animation-iteration-count
129
+ animation-name
130
+ animation-play-state
131
+ animation-timing-function
132
+ animation-fill-mode
133
+ transition
134
+ transition-delay
135
+ transition-duration
136
+ transition-property
137
+ transition-timing-function
138
+ background-clip
139
+ backface-visibility
140
+ resize
141
+ appearance
142
+ user-select
143
+ interpolation-mode
144
+ direction
145
+ marks
146
+ page
147
+ set-link-source
148
+ unicode-bidi
149
+ speak
@@ -0,0 +1,138 @@
1
+ # SMACSS Property Order
2
+ # http://smacss.com/book/formatting
3
+
4
+ # Box
5
+
6
+ display
7
+ position
8
+ top
9
+ right
10
+ bottom
11
+ left
12
+
13
+ width
14
+ min-width
15
+ max-width
16
+
17
+ height
18
+ min-height
19
+ max-height
20
+
21
+ margin
22
+ margin-top
23
+ margin-right
24
+ margin-bottom
25
+ margin-left
26
+
27
+ padding
28
+ padding-top
29
+ padding-right
30
+ padding-bottom
31
+ padding-left
32
+
33
+ float
34
+ clear
35
+
36
+ columns
37
+ column-gap
38
+ column-fill
39
+ column-rule
40
+ column-span
41
+ column-count
42
+ column-width
43
+
44
+ transform
45
+ transition
46
+
47
+ # Border
48
+
49
+ border
50
+ border-top
51
+ border-right
52
+ border-bottom
53
+ border-left
54
+ border-width
55
+ border-top-width
56
+ border-right-width
57
+ border-bottom-width
58
+ border-left-width
59
+
60
+ border-style
61
+ border-top-style
62
+ border-right-style
63
+ border-bottom-style
64
+ border-left-style
65
+
66
+ border-radius
67
+ border-top-left-radius
68
+ border-top-right-radius
69
+ border-bottom-left-radius
70
+ border-bottom-right-radius
71
+
72
+ border-color
73
+ border-top-color
74
+ border-right-color
75
+ border-bottom-color
76
+ border-left-color
77
+
78
+ outline
79
+ outline-color
80
+ outline-offset
81
+ outline-style
82
+ outline-width
83
+
84
+ # Background
85
+
86
+ background
87
+ background-color
88
+ background-image
89
+ background-repeat
90
+ background-position
91
+ background-size
92
+ cursor
93
+
94
+ # Text
95
+
96
+ color
97
+
98
+ font
99
+ font-family
100
+ font-size
101
+ font-smoothing
102
+ font-style
103
+ font-variant
104
+ font-weight
105
+
106
+ letter-spacing
107
+ line-height
108
+ list-style
109
+
110
+ text-align
111
+ text-decoration
112
+ text-indent
113
+ text-overflow
114
+ text-rendering
115
+ text-shadow
116
+ text-transform
117
+ text-wrap
118
+
119
+ white-space
120
+ word-spacing
121
+
122
+ # Other
123
+
124
+ border-collapse
125
+ border-spacing
126
+ box-shadow
127
+ caption-side
128
+ content
129
+ cursor
130
+ empty-cells
131
+ opacity
132
+ overflow
133
+ quotes
134
+ speak
135
+ table-layout
136
+ vertical-align
137
+ visibility
138
+ z-index
@@ -7,6 +7,7 @@ require 'scss_lint/lint'
7
7
  require 'scss_lint/linter_registry'
8
8
  require 'scss_lint/runner'
9
9
  require 'scss_lint/selector_visitor'
10
+ require 'scss_lint/control_comment_processor'
10
11
  require 'scss_lint/version'
11
12
  require 'scss_lint/utils'
12
13
 
@@ -1,7 +1,7 @@
1
1
  require 'find'
2
- require 'optparse'
3
2
  require 'rainbow'
4
3
  require 'rainbow/ext/string'
4
+ require 'scss_lint/options'
5
5
 
6
6
  module SCSSLint
7
7
  # Responsible for parsing command-line options and executing the appropriate
@@ -20,151 +20,101 @@ module SCSSLint
20
20
  config: 78, # Configuration error
21
21
  }
22
22
 
23
- DEFAULT_REPORTER = [SCSSLint::Reporter::DefaultReporter, :stdout]
24
-
25
- # @param args [Array]
26
- def initialize(args = [])
27
- @args = args
28
- @options = { reporters: [DEFAULT_REPORTER] }
29
- @config = Config.default
30
- end
31
-
32
- def parse_arguments
33
- begin
34
- options_parser.parse!(@args)
35
-
36
- # Take the rest of the arguments as files/directories
37
-
38
- if @args.empty?
39
- @options[:files] = @config.scss_files
40
- else
41
- @options[:files] = @args
42
- end
43
-
44
- rescue OptionParser::InvalidOption => ex
45
- print_help options_parser.help, ex
46
- end
47
-
48
- begin
49
- setup_configuration
50
- rescue InvalidConfiguration, NoSuchLinter => ex
51
- puts ex.message
52
- halt :config
53
- end
23
+ def run(args)
24
+ options = SCSSLint::Options.new.parse(args)
25
+ act_on_options(options)
26
+ rescue => ex
27
+ handle_runtime_exception(ex)
54
28
  end
55
29
 
56
- # @return [OptionParser]
57
- def options_parser # rubocop:disable MethodLength
58
- @options_parser ||= OptionParser.new do |opts|
59
- opts.banner = "Usage: #{opts.program_name} [options] [scss-files]"
60
-
61
- opts.separator ''
62
- opts.separator 'Common options:'
63
-
64
- opts.on('-c', '--config file', 'Specify configuration file', String) do |file|
65
- @options[:config_file] = file
66
- end
67
-
68
- opts.on('-e', '--exclude file,...', Array,
69
- 'List of file names to exclude') do |files|
70
- @options[:excluded_files] = files
71
- end
72
-
73
- opts.on('-f', '--format Formatter', 'Specify how to display lints', String) do |format|
74
- define_output_format(format)
75
- end
76
-
77
- opts.on('-o', '--out path', 'Write output to a file instead of STDOUT', String) do |path|
78
- define_output_path(path)
79
- end
80
-
81
- opts.on('-r', '--require path', 'Require Ruby file', String) do |path|
82
- require path
83
- end
84
-
85
- opts.on_tail('--show-formatters', 'Shows available formatters') do
86
- print_formatters
87
- end
88
-
89
- opts.on('-i', '--include-linter linter,...', Array,
90
- 'Specify which linters you want to run') do |linters|
91
- @options[:included_linters] = linters
92
- end
93
-
94
- opts.on('-x', '--exclude-linter linter,...', Array,
95
- "Specify which linters you don't want to run") do |linters|
96
- @options[:excluded_linters] = linters
97
- end
98
-
99
- opts.on_tail('--show-linters', 'Shows available linters') do
100
- print_linters
101
- end
30
+ private
102
31
 
103
- opts.on_tail('-h', '--help', 'Show this message') do
104
- print_help opts.help
105
- end
32
+ def act_on_options(options)
33
+ load_required_paths(options)
106
34
 
107
- opts.on_tail('-v', '--version', 'Show version') do
108
- print_version opts.program_name, VERSION
109
- end
35
+ if options[:help]
36
+ print_help(options)
37
+ elsif options[:version]
38
+ print_version
39
+ elsif options[:show_linters]
40
+ print_linters
41
+ elsif options[:show_formatters]
42
+ print_formatters
43
+ else
44
+ config = setup_configuration(options)
45
+ scan_for_lints(options, config)
110
46
  end
111
47
  end
112
48
 
113
- def run # rubocop:disable MethodLength
114
- runner = Runner.new(@config)
115
- runner.run(files_to_lint)
116
- report_lints(runner.lints)
49
+ def scan_for_lints(options, config)
50
+ runner = Runner.new(config)
51
+ runner.run(files_to_lint(options, config))
52
+ report_lints(options, runner.lints)
117
53
 
118
54
  if runner.lints.any?(&:error?)
119
55
  halt :error
120
56
  elsif runner.lints.any?
121
57
  halt :warning
58
+ else
59
+ halt :ok
122
60
  end
123
- rescue InvalidConfiguration => ex
124
- puts ex
125
- halt :config
126
- rescue NoFilesError, Errno::ENOENT => ex
127
- puts ex.message
128
- halt :no_input
129
- rescue NoSuchLinter => ex
130
- puts ex.message
131
- halt :usage
132
- rescue => ex
133
- puts ex.message
134
- puts ex.backtrace
135
- puts 'Report this bug at '.color(:yellow) + BUG_REPORT_URL.color(:cyan)
136
- halt :software
137
61
  end
138
62
 
139
- private
140
-
141
- def setup_configuration
142
- if @options[:config_file]
143
- @config = Config.load(@options[:config_file])
144
- @config.preferred = true
145
- end
63
+ def handle_runtime_exception(exception) # rubocop:disable Metrics/AbcSize
64
+ case exception
65
+ when SCSSLint::Exceptions::InvalidCLIOption
66
+ puts exception.message
67
+ puts 'Run `scss-lint --help` for usage documentation'
68
+ halt :usage
69
+ when SCSSLint::Exceptions::InvalidConfiguration
70
+ puts exception.message
71
+ halt :config
72
+ when NoFilesError, Errno::ENOENT
73
+ puts exception.message
74
+ halt :no_input
75
+ when NoSuchLinter
76
+ puts exception.message
77
+ halt :usage
78
+ else
79
+ puts exception.message
80
+ puts exception.backtrace
81
+ puts 'Report this bug at '.color(:yellow) + BUG_REPORT_URL.color(:cyan)
82
+ halt :software
83
+ end
84
+ end
85
+
86
+ def setup_configuration(options)
87
+ config =
88
+ if options[:config_file]
89
+ Config.load(options[:config_file]).tap do |conf|
90
+ conf.preferred = true
91
+ end
92
+ else
93
+ Config.default
94
+ end
146
95
 
147
- merge_command_line_flags_with_config(@config)
96
+ merge_options_with_config(options, config)
148
97
  end
149
98
 
99
+ # @param options [Hash]
150
100
  # @param config [Config]
151
101
  # @return [Config]
152
- def merge_command_line_flags_with_config(config)
153
- if @options[:excluded_files]
154
- @options[:excluded_files].each do |file|
102
+ def merge_options_with_config(options, config)
103
+ if options[:excluded_files]
104
+ options[:excluded_files].each do |file|
155
105
  config.exclude_file(file)
156
106
  end
157
107
  end
158
108
 
159
- if @options[:included_linters]
109
+ if options[:included_linters]
160
110
  config.disable_all_linters
161
- LinterRegistry.extract_linters_from(@options[:included_linters]).each do |linter|
111
+ LinterRegistry.extract_linters_from(options[:included_linters]).each do |linter|
162
112
  config.enable_linter(linter)
163
113
  end
164
114
  end
165
115
 
166
- if @options[:excluded_linters]
167
- LinterRegistry.extract_linters_from(@options[:excluded_linters]).each do |linter|
116
+ if options[:excluded_linters]
117
+ LinterRegistry.extract_linters_from(options[:excluded_linters]).each do |linter|
168
118
  config.disable_linter(linter)
169
119
  end
170
120
  end
@@ -172,16 +122,20 @@ module SCSSLint
172
122
  config
173
123
  end
174
124
 
175
- def files_to_lint
176
- extract_files_from(@options[:files]).reject do |file|
177
- config =
178
- if !@config.preferred && (config_for_file = Config.for_file(file))
179
- merge_command_line_flags_with_config(config_for_file.dup)
125
+ def files_to_lint(options, config)
126
+ if options[:files].empty?
127
+ options[:files] = config.scss_files
128
+ end
129
+
130
+ extract_files_from(options[:files]).reject do |file|
131
+ actual_config =
132
+ if !config.preferred && (config_for_file = Config.for_file(file))
133
+ merge_options_with_config(options, config_for_file.dup)
180
134
  else
181
- @config
135
+ config
182
136
  end
183
137
 
184
- config.excluded_file?(file)
138
+ actual_config.excluded_file?(file)
185
139
  end
186
140
  end
187
141
 
@@ -205,32 +159,21 @@ module SCSSLint
205
159
  VALID_EXTENSIONS.include?(File.extname(file))
206
160
  end
207
161
 
162
+ # @param options [Hash]
208
163
  # @param lints [Array<Lint>]
209
- def report_lints(lints)
164
+ def report_lints(options, lints)
210
165
  sorted_lints = lints.sort_by { |l| [l.filename, l.location] }
211
- @options.fetch(:reporters).each do |reporter, output|
166
+ options.fetch(:reporters).each do |reporter, output|
212
167
  results = reporter.new(sorted_lints).report_lints
213
168
  io = (output == :stdout ? $stdout : File.new(output, 'w+'))
214
169
  io.print results if results
215
170
  end
216
171
  end
217
172
 
218
- # @param format [String]
219
- def define_output_format(format)
220
- unless @options[:reporters] == [DEFAULT_REPORTER] && format == 'Default'
221
- @options[:reporters].reject! { |i| i == DEFAULT_REPORTER }
222
- reporter = SCSSLint::Reporter.const_get(format + 'Reporter')
223
- @options[:reporters] << [reporter, :stdout]
173
+ def load_required_paths(options)
174
+ Array(options[:required_paths]).each do |path|
175
+ require path
224
176
  end
225
- rescue NameError
226
- puts "Invalid output format specified: #{format}"
227
- halt :config
228
- end
229
-
230
- # @param path [String]
231
- def define_output_path(path)
232
- last_reporter, _output = @options[:reporters].pop
233
- @options[:reporters] << [last_reporter, path]
234
177
  end
235
178
 
236
179
  def print_formatters
@@ -261,25 +204,22 @@ module SCSSLint
261
204
  halt
262
205
  end
263
206
 
264
- # @param help_message [String]
265
- # @param err [Exception]
266
- def print_help(help_message, err = nil)
267
- puts err, '' if err
268
- puts help_message
269
- halt(err ? :usage : :ok)
207
+ # @param options [Hash]
208
+ def print_help(options)
209
+ puts options[:help]
210
+ halt :ok
270
211
  end
271
212
 
272
- # @param program_name [String]
273
- # @param version [String]
274
- def print_version(program_name, version)
275
- puts "#{program_name} #{version}"
276
- halt
213
+ # @param options [Hash]
214
+ def print_version
215
+ puts "scss-lint #{SCSSLint::VERSION}"
216
+ halt :ok
277
217
  end
278
218
 
279
219
  # Used for ease-of testing
280
220
  # @param exit_status [Symbol]
281
221
  def halt(exit_status = :ok)
282
- exit(EXIT_CODES[exit_status])
222
+ EXIT_CODES[exit_status]
283
223
  end
284
224
  end
285
225
  end