erb_lint 0.7.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed317d0bcb868320c088c8788e5b14ba9f8224aab3e6ae2e4952e34df8fdefc4
4
- data.tar.gz: 21fe3cfccf4d30225d11fa2f397186b5274bbb8d1fe6ff5bf593ac225bb327a9
3
+ metadata.gz: 0eabdfa71b2841fc684663a79233451981e21fcffb175c3ae7a1e0bd8afdc8e4
4
+ data.tar.gz: c609b033d3354e27c938ef1972b1ac16c654b1900115bb4f6d6595c384d1cfb5
5
5
  SHA512:
6
- metadata.gz: d281ca485b9763dc2d7e3b3297b429c2fa08f1f043e557b7a9ad9ab65c5e0e422d5ccabbd66f40e3da43088bc1b580dd9dab5213dca39a894a7b0da82c0e113c
7
- data.tar.gz: 9907b4b4089693f5787c96b0e5cef7b1c9bd49b6831d6e6c42757fb69911a0905b395f468fab7c0339d3b0e166b6962d1a4db772476f669d659f6380e88a90c4
6
+ metadata.gz: f3686f39426c32119e8a725b8320143b31c48f98969bb6f0135827c5ff7c260d5674cfad5190c2bc75111fd5a76d881e47d7aa18b6b48f3f903f698719601623
7
+ data.tar.gz: 727473a64473dad0adb3912bc7f7b7e5c84d51c60374f72e93f380d378635848a240e8f1f3f16ec8f88874290e5e16821e8445b882c09cec4c78081db9eb2bda
data/lib/erb_lint/cli.rb CHANGED
@@ -162,7 +162,7 @@ module ERBLint
162
162
  runner.run(processed_source)
163
163
  break unless autocorrect? && runner.offenses.any?
164
164
 
165
- corrector = correct(processed_source, runner.offenses)
165
+ corrector = corrector(processed_source, runner.offenses)
166
166
  break if corrector.corrections.empty?
167
167
  break if processed_source.file_content == corrector.corrected_content
168
168
 
@@ -202,10 +202,8 @@ module ERBLint
202
202
  $stdin.binmode.read.force_encoding(Encoding::UTF_8)
203
203
  end
204
204
 
205
- def correct(processed_source, offenses)
206
- corrector = ERBLint::Corrector.new(processed_source, offenses)
207
- failure!(corrector.diagnostics.join(", ")) if corrector.diagnostics.any?
208
- corrector
205
+ def corrector(processed_source, offenses)
206
+ ERBLint::Corrector.new(processed_source, offenses)
209
207
  end
210
208
 
211
209
  def config_filename
@@ -7,6 +7,8 @@ module ERBLint
7
7
  def initialize(processed_source, offenses)
8
8
  @processed_source = processed_source
9
9
  @offenses = offenses
10
+ corrector = RuboCop::Cop::Corrector.new(@processed_source.source_buffer)
11
+ correct!(corrector)
10
12
  @corrected_content = corrector.rewrite
11
13
  end
12
14
 
@@ -16,22 +18,9 @@ module ERBLint
16
18
  end.compact
17
19
  end
18
20
 
19
- def corrector
20
- BASE.new(@processed_source.source_buffer, corrections)
21
- end
22
-
23
- if ::RuboCop::Version::STRING.to_f >= 0.87
24
- require "rubocop/cop/legacy/corrector"
25
- BASE = ::RuboCop::Cop::Legacy::Corrector
26
-
27
- def diagnostics
28
- []
29
- end
30
- else
31
- BASE = ::RuboCop::Cop::Corrector
32
-
33
- def diagnostics
34
- corrector.diagnostics
21
+ def correct!(corrector)
22
+ corrections.each do |correction|
23
+ correction.call(corrector)
35
24
  end
36
25
  end
37
26
  end
@@ -9,14 +9,8 @@ module ERBLint
9
9
  @base_path = base_path
10
10
  end
11
11
 
12
- if RUBY_VERSION >= "2.6"
13
- def yaml(filename)
14
- YAML.safe_load(read_content(filename), permitted_classes: [Regexp, Symbol], filename: filename) || {}
15
- end
16
- else
17
- def yaml(filename)
18
- YAML.safe_load(read_content(filename), [Regexp, Symbol], [], false, filename) || {}
19
- end
12
+ def yaml(filename)
13
+ YAML.safe_load(read_content(filename), permitted_classes: [Regexp, Symbol], filename: filename) || {}
20
14
  end
21
15
 
22
16
  private
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "better_html"
4
4
  require "tempfile"
5
- require "erb_lint/utils/offset_corrector"
6
5
 
7
6
  module ERBLint
8
7
  module Linters
@@ -36,30 +35,14 @@ module ERBLint
36
35
  end
37
36
  end
38
37
 
39
- if ::RuboCop::Version::STRING.to_f >= 0.87
40
- def autocorrect(_processed_source, offense)
41
- return unless offense.context
38
+ def autocorrect(_processed_source, offense)
39
+ return unless offense.context
42
40
 
43
- rubocop_correction = offense.context[:rubocop_correction]
44
- return unless rubocop_correction
41
+ rubocop_correction = offense.context[:rubocop_correction]
42
+ return unless rubocop_correction
45
43
 
46
- lambda do |corrector|
47
- corrector.import!(rubocop_correction, offset: offense.context[:offset])
48
- end
49
- end
50
- else
51
- def autocorrect(processed_source, offense)
52
- return unless offense.context
53
-
54
- lambda do |corrector|
55
- passthrough = Utils::OffsetCorrector.new(
56
- processed_source,
57
- corrector,
58
- offense.context[:offset],
59
- offense.context[:bound_range],
60
- )
61
- offense.context[:rubocop_correction].call(passthrough)
62
- end
44
+ lambda do |corrector|
45
+ corrector.import!(rubocop_correction, offset: offense.context[:offset])
63
46
  end
64
47
  end
65
48
 
@@ -85,39 +68,18 @@ module ERBLint
85
68
  activate_team(processed_source, source, offset, code_node, build_team)
86
69
  end
87
70
 
88
- if ::RuboCop::Version::STRING.to_f >= 0.87
89
- def activate_team(processed_source, source, offset, code_node, team)
90
- report = team.investigate(source)
91
- report.offenses.each do |rubocop_offense|
92
- next if rubocop_offense.disabled?
71
+ def activate_team(processed_source, source, offset, code_node, team)
72
+ report = team.investigate(source)
73
+ report.offenses.each do |rubocop_offense|
74
+ next if rubocop_offense.disabled?
93
75
 
94
- correction = rubocop_offense.corrector if rubocop_offense.corrected?
76
+ correction = rubocop_offense.corrector if rubocop_offense.corrected?
95
77
 
96
- offense_range = processed_source
97
- .to_source_range(rubocop_offense.location)
98
- .offset(offset)
78
+ offense_range = processed_source
79
+ .to_source_range(rubocop_offense.location)
80
+ .offset(offset)
99
81
 
100
- add_offense(rubocop_offense, offense_range, correction, offset, code_node.loc.range)
101
- end
102
- end
103
- else
104
- def activate_team(processed_source, source, offset, code_node, team)
105
- team.inspect_file(source)
106
- team.cops.each do |cop|
107
- correction_offset = 0
108
- cop.offenses.reject(&:disabled?).each do |rubocop_offense|
109
- if rubocop_offense.corrected?
110
- correction = cop.corrections[correction_offset]
111
- correction_offset += 1
112
- end
113
-
114
- offense_range = processed_source
115
- .to_source_range(rubocop_offense.location)
116
- .offset(offset)
117
-
118
- add_offense(rubocop_offense, offense_range, correction, offset, code_node.loc.range)
119
- end
120
- end
82
+ add_offense(rubocop_offense, offense_range, correction, offset, code_node.loc.range)
121
83
  end
122
84
  end
123
85
 
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ERBLint
4
+ module Linters
5
+ # Enforces the use of strict locals in Rails view partial templates.
6
+ class StrictLocals < Linter
7
+ include LinterRegistry
8
+
9
+ STRICT_LOCALS_REGEX = /\s+locals:\s+\((.*)\)/
10
+
11
+ def initialize(file_loader, config)
12
+ super
13
+ end
14
+
15
+ def run(processed_source)
16
+ return unless processed_source.filename.match?(%r{(\A|.*/)_[^/\s]*\.html\.erb\z})
17
+
18
+ file_content = processed_source.file_content
19
+ return if file_content.empty?
20
+
21
+ strict_locals_node = processed_source.ast.descendants(:erb).find do |erb_node|
22
+ indicator_node, _, code_node, _ = *erb_node
23
+
24
+ indicator_node_str = indicator_node&.deconstruct&.last
25
+ next unless indicator_node_str == "#"
26
+
27
+ code_node_str = code_node&.deconstruct&.last
28
+
29
+ code_node_str.match(STRICT_LOCALS_REGEX)
30
+ end
31
+
32
+ unless strict_locals_node
33
+ add_offense(
34
+ processed_source.to_source_range(0...processed_source.file_content.size),
35
+ <<~EOF.chomp,
36
+ Missing strict locals declaration.
37
+ Add <%# locals: () %> at the top of the file to enforce strict locals.
38
+ EOF
39
+ )
40
+ end
41
+ end
42
+
43
+ def autocorrect(_processed_source, offense)
44
+ lambda do |corrector|
45
+ corrector.insert_before(offense.source_range, "<%# locals: () %>\n")
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -4,11 +4,11 @@ module ERBLint
4
4
  module Utils
5
5
  class InlineConfigs
6
6
  def self.rule_disable_comment_for_lines?(rule, lines)
7
- lines.match?(/# erblint:disable (?<rules>.*#{rule}).*/)
7
+ lines.match?(/# erb_?lint:disable (?<rules>.*#{rule}).*/)
8
8
  end
9
9
 
10
10
  def self.disabled_rules(line)
11
- line.match(/# erblint:disable (?<rules>.*) %>/)&.named_captures&.fetch("rules")
11
+ line.match(/# erb_?lint:disable (?<rules>.*) %>/)&.named_captures&.fetch("rules")
12
12
  end
13
13
  end
14
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ERBLint
4
- VERSION = "0.7.0"
4
+ VERSION = "0.9.0"
5
5
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Chan
8
8
  - Shopify Developers
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-10-16 00:00:00.000000000 Z
11
+ date: 2025-01-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
@@ -179,6 +178,7 @@ files:
179
178
  - lib/erb_lint/linters/space_around_erb_tag.rb
180
179
  - lib/erb_lint/linters/space_in_html_tag.rb
181
180
  - lib/erb_lint/linters/space_indentation.rb
181
+ - lib/erb_lint/linters/strict_locals.rb
182
182
  - lib/erb_lint/linters/trailing_whitespace.rb
183
183
  - lib/erb_lint/offense.rb
184
184
  - lib/erb_lint/processed_source.rb
@@ -194,7 +194,6 @@ files:
194
194
  - lib/erb_lint/stats.rb
195
195
  - lib/erb_lint/utils/block_map.rb
196
196
  - lib/erb_lint/utils/inline_configs.rb
197
- - lib/erb_lint/utils/offset_corrector.rb
198
197
  - lib/erb_lint/utils/ruby_to_erb.rb
199
198
  - lib/erb_lint/utils/severity_levels.rb
200
199
  - lib/erb_lint/version.rb
@@ -203,7 +202,6 @@ licenses:
203
202
  - MIT
204
203
  metadata:
205
204
  allowed_push_host: https://rubygems.org
206
- post_install_message:
207
205
  rdoc_options: []
208
206
  require_paths:
209
207
  - lib
@@ -218,8 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
216
  - !ruby/object:Gem::Version
219
217
  version: '0'
220
218
  requirements: []
221
- rubygems_version: 3.5.21
222
- signing_key:
219
+ rubygems_version: 3.6.2
223
220
  specification_version: 4
224
221
  summary: ERB lint tool
225
222
  test_files: []
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ERBLint
4
- module Utils
5
- class OffsetCorrector
6
- def initialize(processed_source, corrector, offset, bound_range)
7
- @processed_source = processed_source
8
- @corrector = corrector
9
- @offset = offset
10
- @bound_range = bound_range
11
- end
12
-
13
- def remove(range)
14
- @corrector.remove(range_with_offset(range))
15
- end
16
-
17
- def insert_before(range, content)
18
- @corrector.insert_before(range_with_offset(range), content)
19
- end
20
-
21
- def insert_after(range, content)
22
- @corrector.insert_after(range_with_offset(range), content)
23
- end
24
-
25
- def replace(range, content)
26
- @corrector.replace(range_with_offset(range), content)
27
- end
28
-
29
- def remove_preceding(range, size)
30
- @corrector.remove_preceding(range_with_offset(range), size)
31
- end
32
-
33
- def remove_leading(range, size)
34
- @corrector.remove_leading(range_with_offset(range), size)
35
- end
36
-
37
- def remove_trailing(range, size)
38
- @corrector.remove_trailing(range_with_offset(range), size)
39
- end
40
-
41
- def range_with_offset(node_or_range)
42
- range = to_range(node_or_range)
43
-
44
- @processed_source.to_source_range(
45
- bound(@offset + range.begin_pos)..bound(@offset + (range.end_pos - 1)),
46
- )
47
- end
48
-
49
- def bound(pos)
50
- pos.clamp(@bound_range.min, @bound_range.max)
51
- end
52
-
53
- private
54
-
55
- def to_range(node_or_range)
56
- case node_or_range
57
- when ::RuboCop::AST::Node, ::Parser::Source::Comment
58
- node_or_range.loc.expression
59
- when ::Parser::Source::Range
60
- node_or_range
61
- else
62
- raise TypeError,
63
- "Expected a Parser::Source::Range, Comment or " \
64
- "Rubocop::AST::Node, got #{node_or_range.class}"
65
- end
66
- end
67
- end
68
- end
69
- end