erb_lint 0.3.1 → 0.4.0

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
  SHA256:
3
- metadata.gz: 1bd25c794b1028b09ecec8ce3b5e77600d36364d59b85f2e4b24a18d6bb08853
4
- data.tar.gz: e41f353e930401a024d880fc6973beb1e462f2f5372edb094523eacde0030d72
3
+ metadata.gz: 9b3cff2cda3a196df2b19ff70f2999cea11a467b57bfa9a95fc031354752c6f1
4
+ data.tar.gz: 7e85499590c4d58c8f2cd4af0d12d49ffe7fb27f219fdb610c777c2a5b3e2100
5
5
  SHA512:
6
- metadata.gz: 94ed5b3479803ff2b51af6390c0e39c2fb37ef98e23fc2523ac204b638d8ff043665926081794ff27d77a60faae8ee7747cb4ef3d04125b7b3f7c2ae55ea268f
7
- data.tar.gz: 9b423110f202bb9728ec57dbd60f04aa86e2901ecfa915d9ddc49fd58fac27b3daddea78780612c3f474ece4c41c01977bea72ad8353a9a113d5cee8c4a51914
6
+ metadata.gz: 23c04a0063e05a08c9d3b376542c6cc1f97659d700a4ba7fa5a50997231a485bb8971ba240b25cc998235c1ff5b138e3e4a5fa648351603f06061339c71ec75a
7
+ data.tar.gz: 538c54359e677e2a56ae558b3d2f5527138c9f82485a943c9f4c5e06d6a3ebd6d6107f2285913920c7d3d1213e1353162f55b257bf1b7eb6da238af8487d142d
data/lib/erb_lint/cli.rb CHANGED
@@ -69,6 +69,7 @@ module ERBLint
69
69
 
70
70
  @options[:format] ||= :multiline
71
71
  @options[:fail_level] ||= severity_level_for_name(:refactor)
72
+ @options[:disable_inline_configs] ||= false
72
73
  @stats.files = lint_files.size
73
74
  @stats.linters = enabled_linter_classes.size
74
75
  @stats.autocorrectable_linters = enabled_linter_classes.count(&:support_autocorrect?)
@@ -76,7 +77,7 @@ module ERBLint
76
77
  reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?)
77
78
  reporter.preview
78
79
 
79
- runner = ERBLint::Runner.new(file_loader, @config)
80
+ runner = ERBLint::Runner.new(file_loader, @config, @options[:disable_inline_configs])
80
81
  file_content = nil
81
82
 
82
83
  lint_files.each do |filename|
@@ -221,7 +222,7 @@ module ERBLint
221
222
  rescue Psych::SyntaxError => e
222
223
  failure!("error parsing config: #{e.message}")
223
224
  ensure
224
- @config.merge!(runner_config_override)
225
+ @config&.merge!(runner_config_override)
225
226
  end
226
227
 
227
228
  def file_loader
@@ -374,6 +375,10 @@ module ERBLint
374
375
  @options[:allow_no_files] = config
375
376
  end
376
377
 
378
+ opts.on("--disable-inline-configs", "Report all offenses while ignoring inline disable comments") do
379
+ @options[:disable_inline_configs] = true
380
+ end
381
+
377
382
  opts.on(
378
383
  "-sFILE",
379
384
  "--stdin FILE",
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "erb_lint/utils/inline_configs"
4
+
3
5
  module ERBLint
4
6
  # Defines common functionality available to all linters.
5
7
  class Linter
@@ -53,6 +55,13 @@ module ERBLint
53
55
  raise NotImplementedError, "must implement ##{__method__}"
54
56
  end
55
57
 
58
+ def run_and_update_offense_status(processed_source, enable_inline_configs = true)
59
+ run(processed_source)
60
+ if @offenses.any? && enable_inline_configs
61
+ update_offense_status(processed_source)
62
+ end
63
+ end
64
+
56
65
  def add_offense(source_range, message, context = nil, severity = nil)
57
66
  @offenses << Offense.new(self, source_range, message, context, severity)
58
67
  end
@@ -60,5 +69,22 @@ module ERBLint
60
69
  def clear_offenses
61
70
  @offenses = []
62
71
  end
72
+
73
+ private
74
+
75
+ def update_offense_status(processed_source)
76
+ @offenses.each do |offense|
77
+ offense_line_range = offense.source_range.line_range
78
+ offense_lines = source_for_line_range(processed_source, offense_line_range)
79
+
80
+ if Utils::InlineConfigs.rule_disable_comment_for_lines?(self.class.simple_name, offense_lines)
81
+ offense.disabled = true
82
+ end
83
+ end
84
+ end
85
+
86
+ def source_for_line_range(processed_source, line_range)
87
+ processed_source.source_buffer.source_lines[line_range.first - 1..line_range.last - 1].join
88
+ end
63
89
  end
64
90
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb_lint/utils/inline_configs"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Checks for unused disable comments.
8
+ class NoUnusedDisable < Linter
9
+ include LinterRegistry
10
+
11
+ def run(processed_source, offenses)
12
+ disabled_rules_and_line_number = {}
13
+
14
+ processed_source.source_buffer.source_lines.each_with_index do |line, index|
15
+ rule_disables = Utils::InlineConfigs.disabled_rules(line)
16
+ next unless rule_disables
17
+
18
+ rule_disables.split(",").each do |rule|
19
+ disabled_rules_and_line_number[rule.strip] =
20
+ (disabled_rules_and_line_number[rule.strip] ||= []).push(index + 1)
21
+ end
22
+ end
23
+
24
+ offenses.each do |offense|
25
+ rule_name = offense.linter.class.simple_name
26
+ line_numbers = disabled_rules_and_line_number[rule_name]
27
+ next unless line_numbers
28
+
29
+ line_numbers.reject do |line_number|
30
+ if (offense.source_range.line_span.first..offense.source_range.line_span.last).include?(line_number)
31
+ disabled_rules_and_line_number[rule_name].delete(line_number)
32
+ end
33
+ end
34
+ end
35
+
36
+ disabled_rules_and_line_number.each do |rule, line_numbers|
37
+ line_numbers.each do |line_number|
38
+ add_offense(processed_source.source_buffer.line_range(line_number),
39
+ "Unused erblint:disable comment for #{rule}")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -15,6 +15,7 @@ module ERBLint
15
15
  @message = message
16
16
  @context = context
17
17
  @severity = severity
18
+ @disabled = false
18
19
  end
19
20
 
20
21
  def to_cached_offense_hash
@@ -44,6 +45,12 @@ module ERBLint
44
45
  line_range.begin
45
46
  end
46
47
 
48
+ attr_writer :disabled
49
+
50
+ def disabled?
51
+ @disabled
52
+ end
53
+
47
54
  def column
48
55
  source_range.column
49
56
  end
@@ -5,15 +5,19 @@ module ERBLint
5
5
  class Runner
6
6
  attr_reader :offenses
7
7
 
8
- def initialize(file_loader, config)
8
+ def initialize(file_loader, config, disable_inline_configs = false)
9
9
  @file_loader = file_loader
10
10
  @config = config || RunnerConfig.default
11
11
  raise ArgumentError, "expect `config` to be a RunnerConfig instance" unless @config.is_a?(RunnerConfig)
12
12
 
13
- linter_classes = LinterRegistry.linters.select { |klass| @config.for_linter(klass).enabled? }
13
+ linter_classes = LinterRegistry.linters.select do |klass|
14
+ @config.for_linter(klass).enabled? && klass != ERBLint::Linters::NoUnusedDisable
15
+ end
14
16
  @linters = linter_classes.map do |linter_class|
15
17
  linter_class.new(@file_loader, @config.for_linter(linter_class))
16
18
  end
19
+ @no_unused_disable = nil
20
+ @disable_inline_configs = disable_inline_configs
17
21
  @offenses = []
18
22
  end
19
23
 
@@ -21,18 +25,43 @@ module ERBLint
21
25
  @linters
22
26
  .reject { |linter| linter.excludes_file?(processed_source.filename) }
23
27
  .each do |linter|
24
- linter.run(processed_source)
28
+ linter.run_and_update_offense_status(processed_source, enable_inline_configs?)
25
29
  @offenses.concat(linter.offenses)
26
30
  end
31
+ report_unused_disable(processed_source)
32
+ @offenses = @offenses.reject(&:disabled?)
27
33
  end
28
34
 
29
35
  def clear_offenses
30
36
  @offenses = []
31
37
  @linters.each(&:clear_offenses)
38
+ @no_unused_disable&.clear_offenses
32
39
  end
33
40
 
34
41
  def restore_offenses(offenses)
35
42
  @offenses.concat(offenses)
36
43
  end
44
+
45
+ private
46
+
47
+ def enable_inline_configs?
48
+ !@disable_inline_configs
49
+ end
50
+
51
+ def no_unused_disable_enabled?
52
+ LinterRegistry.linters.include?(ERBLint::Linters::NoUnusedDisable) &&
53
+ @config.for_linter(ERBLint::Linters::NoUnusedDisable).enabled?
54
+ end
55
+
56
+ def report_unused_disable(processed_source)
57
+ if no_unused_disable_enabled? && enable_inline_configs?
58
+ @no_unused_disable = ERBLint::Linters::NoUnusedDisable.new(
59
+ @file_loader,
60
+ @config.for_linter(ERBLint::Linters::NoUnusedDisable)
61
+ )
62
+ @no_unused_disable.run(processed_source, @offenses)
63
+ @offenses.concat(@no_unused_disable.offenses)
64
+ end
65
+ end
37
66
  end
38
67
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ERBLint
4
+ module Utils
5
+ class InlineConfigs
6
+ def self.rule_disable_comment_for_lines?(rule, lines)
7
+ lines.match?(/# erblint:disable (?<rules>.*#{rule}).*/)
8
+ end
9
+
10
+ def self.disabled_rules(line)
11
+ line.match(/# erblint:disable (?<rules>.*) %>/)&.named_captures&.fetch("rules")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ERBLint
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Chan
8
+ - Shopify Developers
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2022-11-10 00:00:00.000000000 Z
12
+ date: 2023-03-27 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
@@ -138,7 +139,7 @@ dependencies:
138
139
  version: '0'
139
140
  description: ERB Linter tool.
140
141
  email:
141
- - justin.the.c@gmail.com
142
+ - ruby@shopify.com
142
143
  executables:
143
144
  - erblint
144
145
  extensions: []
@@ -164,6 +165,7 @@ files:
164
165
  - lib/erb_lint/linters/final_newline.rb
165
166
  - lib/erb_lint/linters/hard_coded_string.rb
166
167
  - lib/erb_lint/linters/no_javascript_tag_helper.rb
168
+ - lib/erb_lint/linters/no_unused_disable.rb
167
169
  - lib/erb_lint/linters/parser_errors.rb
168
170
  - lib/erb_lint/linters/partial_instance_variable.rb
169
171
  - lib/erb_lint/linters/require_input_autocomplete.rb
@@ -187,6 +189,7 @@ files:
187
189
  - lib/erb_lint/runner_config_resolver.rb
188
190
  - lib/erb_lint/stats.rb
189
191
  - lib/erb_lint/utils/block_map.rb
192
+ - lib/erb_lint/utils/inline_configs.rb
190
193
  - lib/erb_lint/utils/offset_corrector.rb
191
194
  - lib/erb_lint/utils/ruby_to_erb.rb
192
195
  - lib/erb_lint/utils/severity_levels.rb
@@ -211,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
214
  - !ruby/object:Gem::Version
212
215
  version: '0'
213
216
  requirements: []
214
- rubygems_version: 3.3.3
217
+ rubygems_version: 3.4.9
215
218
  signing_key:
216
219
  specification_version: 4
217
220
  summary: ERB lint tool