erb_lint 0.0.37 → 0.1.2

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/exe/erblint +1 -1
  3. data/lib/erb_lint/all.rb +26 -0
  4. data/lib/erb_lint/cli.rb +75 -29
  5. data/lib/erb_lint/corrector.rb +1 -1
  6. data/lib/erb_lint/linter.rb +5 -5
  7. data/lib/erb_lint/linter_config.rb +5 -3
  8. data/lib/erb_lint/linter_registry.rb +2 -2
  9. data/lib/erb_lint/linters/allowed_script_type.rb +9 -8
  10. data/lib/erb_lint/linters/closing_erb_tag_indent.rb +2 -2
  11. data/lib/erb_lint/linters/deprecated_classes.rb +8 -7
  12. data/lib/erb_lint/linters/erb_safety.rb +2 -2
  13. data/lib/erb_lint/linters/extra_newline.rb +1 -1
  14. data/lib/erb_lint/linters/final_newline.rb +2 -2
  15. data/lib/erb_lint/linters/hard_coded_string.rb +39 -16
  16. data/lib/erb_lint/linters/no_javascript_tag_helper.rb +11 -9
  17. data/lib/erb_lint/linters/partial_instance_variable.rb +23 -0
  18. data/lib/erb_lint/linters/require_input_autocomplete.rb +121 -0
  19. data/lib/erb_lint/linters/require_script_nonce.rb +92 -0
  20. data/lib/erb_lint/linters/right_trim.rb +1 -1
  21. data/lib/erb_lint/linters/rubocop.rb +13 -11
  22. data/lib/erb_lint/linters/rubocop_text.rb +1 -1
  23. data/lib/erb_lint/linters/self_closing_tag.rb +6 -7
  24. data/lib/erb_lint/linters/space_around_erb_tag.rb +8 -7
  25. data/lib/erb_lint/linters/space_in_html_tag.rb +7 -6
  26. data/lib/erb_lint/linters/space_indentation.rb +1 -1
  27. data/lib/erb_lint/linters/trailing_whitespace.rb +1 -1
  28. data/lib/erb_lint/offense.rb +8 -4
  29. data/lib/erb_lint/reporter.rb +4 -2
  30. data/lib/erb_lint/reporters/compact_reporter.rb +17 -4
  31. data/lib/erb_lint/reporters/json_reporter.rb +72 -0
  32. data/lib/erb_lint/reporters/multiline_reporter.rb +2 -1
  33. data/lib/erb_lint/runner.rb +3 -2
  34. data/lib/erb_lint/runner_config.rb +9 -7
  35. data/lib/erb_lint/runner_config_resolver.rb +5 -4
  36. data/lib/erb_lint/stats.rb +13 -6
  37. data/lib/erb_lint/utils/block_map.rb +3 -2
  38. data/lib/erb_lint/utils/offset_corrector.rb +2 -2
  39. data/lib/erb_lint/utils/ruby_to_erb.rb +6 -5
  40. data/lib/erb_lint/utils/severity_levels.rb +16 -0
  41. data/lib/erb_lint/version.rb +1 -1
  42. data/lib/erb_lint.rb +1 -24
  43. metadata +23 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20ce12719e17ebfc24ca522965e85985fe665c0cbec1d9751320b1a779ec8c9c
4
- data.tar.gz: 536222d32134c71f72083c5083f575e8422024f8f5e26e0daf9b9eadd181d3e9
3
+ metadata.gz: 97583caf4e48c7c5b8a6d2e1bf4c17add7bac9693ef6032be0fb22f9d46f4fa4
4
+ data.tar.gz: 3d1dba73d37680a0339936a12a6c2a048b473a7c9077518f54edd1aa037c4ce5
5
5
  SHA512:
6
- metadata.gz: 44f138dfdfff77b04d03f293f3b48f90744bbf3fcbcfeadc1cf3b5f0d47cae5c933b18b0e7273d64cdf549170e2a2aa33c5110cbc0aa62c84855e6e29a5f67ae
7
- data.tar.gz: 1fe70e0ddb97e0930b2645b0942d5ed08e74c5b40a41af1b6b9c7b9219b4be136495a5f3a0991363e8877aaef7bab5da2eb1f4162dc85f64b2f17d6ae2ca1184
6
+ metadata.gz: a043d8859ef059100dd809112f8768908f2ec8df59a52991c09ea995d2181aeabf06c105b3d12eef13ddbbed15d220edbdd88941fe6a55a23fd5c600aa55623d
7
+ data.tar.gz: 805102e771aac93e6a75017dde3f88deee018dceff3c8c57f2ddcdea88f97f241980efc17885999989733952e771e0538a75eaf67566499e61534c9e64476f75
data/exe/erblint CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  $LOAD_PATH.unshift("#{__dir__}/../lib")
5
5
 
6
- require 'erb_lint/cli'
6
+ require "erb_lint/cli"
7
7
 
8
8
  cli = ERBLint::CLI.new
9
9
  exit(cli.run)
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ require "erb_lint"
6
+ require "erb_lint/corrector"
7
+ require "erb_lint/file_loader"
8
+ require "erb_lint/linter_config"
9
+ require "erb_lint/linter_registry"
10
+ require "erb_lint/linter"
11
+ require "erb_lint/offense"
12
+ require "erb_lint/processed_source"
13
+ require "erb_lint/runner_config"
14
+ require "erb_lint/runner"
15
+ require "erb_lint/stats"
16
+ require "erb_lint/reporter"
17
+
18
+ # Load linters
19
+ Dir[File.expand_path("linters/**/*.rb", __dir__)].each do |file|
20
+ require file
21
+ end
22
+
23
+ # Load reporters
24
+ Dir[File.expand_path("reporters/**/*.rb", __dir__)].each do |file|
25
+ require file
26
+ end
data/lib/erb_lint/cli.rb CHANGED
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb_lint'
4
- require 'active_support'
5
- require 'active_support/inflector'
6
- require 'optparse'
7
- require 'psych'
8
- require 'yaml'
9
- require 'rainbow'
3
+ require "erb_lint/all"
4
+ require "active_support"
5
+ require "active_support/inflector"
6
+ require "optparse"
7
+ require "psych"
8
+ require "yaml"
9
+ require "rainbow"
10
+ require "erb_lint/utils/severity_levels"
10
11
 
11
12
  module ERBLint
12
13
  class CLI
13
- DEFAULT_CONFIG_FILENAME = '.erb-lint.yml'
14
+ include Utils::SeverityLevels
15
+
16
+ DEFAULT_CONFIG_FILENAME = ".erb-lint.yml"
14
17
  DEFAULT_LINT_ALL_GLOB = "**/*.html{+*,}.erb"
15
18
 
16
19
  class ExitWithFailure < RuntimeError; end
@@ -27,7 +30,7 @@ module ERBLint
27
30
  def run(args = ARGV)
28
31
  dupped_args = args.dup
29
32
  load_options(dupped_args)
30
- @files = dupped_args
33
+ @files = @options[:stdin] || dupped_args
31
34
 
32
35
  load_config
33
36
 
@@ -40,25 +43,28 @@ module ERBLint
40
43
  ensure_files_exist(lint_files)
41
44
 
42
45
  if enabled_linter_classes.empty?
43
- failure!('no linter available with current configuration')
46
+ failure!("no linter available with current configuration")
44
47
  end
45
48
 
46
49
  @options[:format] ||= :multiline
50
+ @options[:fail_level] ||= severity_level_for_name(:refactor)
47
51
  @stats.files = lint_files.size
48
52
  @stats.linters = enabled_linter_classes.size
53
+ @stats.autocorrectable_linters = enabled_linter_classes.count(&:support_autocorrect?)
49
54
 
50
55
  reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?)
51
56
  reporter.preview
52
57
 
53
58
  runner = ERBLint::Runner.new(file_loader, @config)
59
+ file_content = nil
54
60
 
55
61
  lint_files.each do |filename|
56
62
  runner.clear_offenses
57
63
  begin
58
- run_with_corrections(runner, filename)
64
+ file_content = run_with_corrections(runner, filename)
59
65
  rescue => e
60
66
  @stats.exceptions += 1
61
- puts "Exception occured when processing: #{relative_filename(filename)}"
67
+ puts "Exception occurred when processing: #{relative_filename(filename)}"
62
68
  puts "If this file cannot be processed by erb-lint, "\
63
69
  "you can exclude it in your configuration file."
64
70
  puts e.message
@@ -69,6 +75,12 @@ module ERBLint
69
75
 
70
76
  reporter.show
71
77
 
78
+ if stdin? && autocorrect?
79
+ # When running from stdin, we only lint a single file
80
+ puts "================ #{lint_files.first} ==================\n"
81
+ puts file_content
82
+ end
83
+
72
84
  @stats.found == 0 && @stats.exceptions == 0
73
85
  rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, ExitWithFailure => e
74
86
  warn(Rainbow(e.message).red)
@@ -88,7 +100,7 @@ module ERBLint
88
100
  end
89
101
 
90
102
  def run_with_corrections(runner, filename)
91
- file_content = File.read(filename, encoding: Encoding::UTF_8)
103
+ file_content = read_content(filename)
92
104
 
93
105
  7.times do
94
106
  processed_source = ERBLint::ProcessedSource.new(filename, file_content)
@@ -101,8 +113,11 @@ module ERBLint
101
113
 
102
114
  @stats.corrected += corrector.corrections.size
103
115
 
104
- File.open(filename, "wb") do |file|
105
- file.write(corrector.corrected_content)
116
+ # Don't overwrite the file if the input comes from stdin
117
+ unless stdin?
118
+ File.open(filename, "wb") do |file|
119
+ file.write(corrector.corrected_content)
120
+ end
106
121
  end
107
122
 
108
123
  file_content = corrector.corrected_content
@@ -111,14 +126,27 @@ module ERBLint
111
126
  offenses_filename = relative_filename(filename)
112
127
  offenses = runner.offenses || []
113
128
 
114
- @stats.found += offenses.size
129
+ @stats.ignored, @stats.found = offenses.partition do |offense|
130
+ severity_level_for_name(offense.severity) < @options[:fail_level]
131
+ end.map(&:size)
132
+ .zip([@stats.ignored, @stats.found])
133
+ .map(&:sum)
134
+
115
135
  @stats.processed_files[offenses_filename] ||= []
116
136
  @stats.processed_files[offenses_filename] |= offenses
137
+
138
+ file_content
139
+ end
140
+
141
+ def read_content(filename)
142
+ return File.read(filename, encoding: Encoding::UTF_8) unless stdin?
143
+
144
+ $stdin.binmode.read.force_encoding(Encoding::UTF_8)
117
145
  end
118
146
 
119
147
  def correct(processed_source, offenses)
120
148
  corrector = ERBLint::Corrector.new(processed_source, offenses)
121
- failure!(corrector.diagnostics.join(', ')) if corrector.diagnostics.any?
149
+ failure!(corrector.diagnostics.join(", ")) if corrector.diagnostics.any?
122
150
  corrector
123
151
  end
124
152
 
@@ -156,7 +184,7 @@ module ERBLint
156
184
  else
157
185
  @files
158
186
  .map { |f| Dir.exist?(f) ? Dir[File.join(f, glob)] : f }
159
- .map { |f| f.include?('*') ? Dir[f] : f }
187
+ .map { |f| f.include?("*") ? Dir[f] : f }
160
188
  .flatten
161
189
  .map { |f| File.expand_path(f, Dir.pwd) }
162
190
  .select { |filename| !excluded?(filename) }
@@ -169,7 +197,8 @@ module ERBLint
169
197
 
170
198
  def excluded?(filename)
171
199
  @config.global_exclude.any? do |path|
172
- File.fnmatch?(path, filename)
200
+ expanded_path = File.expand_path(path, Dir.pwd)
201
+ File.fnmatch?(expanded_path, filename)
173
202
  end
174
203
  end
175
204
 
@@ -204,22 +233,18 @@ module ERBLint
204
233
 
205
234
  def enabled_linter_classes
206
235
  @enabled_linter_classes ||= ERBLint::LinterRegistry.linters
207
- .select { |klass| linter_can_run?(klass) && enabled_linter_names.include?(klass.simple_name.underscore) }
208
- end
209
-
210
- def linter_can_run?(klass)
211
- !autocorrect? || klass.support_autocorrect?
236
+ .select { |klass| enabled_linter_names.include?(klass.simple_name.underscore) }
212
237
  end
213
238
 
214
239
  def relative_filename(filename)
215
- filename.sub("#{File.expand_path('.', Dir.pwd)}/", '')
240
+ filename.sub("#{File.expand_path(".", Dir.pwd)}/", "")
216
241
  end
217
242
 
218
243
  def runner_config_override
219
244
  RunnerConfig.new(
220
245
  linters: {}.tap do |linters|
221
246
  ERBLint::LinterRegistry.linters.map do |klass|
222
- linters[klass.simple_name] = { 'enabled' => enabled_linter_classes.include?(klass) }
247
+ linters[klass.simple_name] = { "enabled" => enabled_linter_classes.include?(klass) }
223
248
  end
224
249
  end
225
250
  )
@@ -255,19 +280,36 @@ module ERBLint
255
280
  end
256
281
 
257
282
  opts.on("--enable-linters LINTER[,LINTER,...]", Array,
258
- "Only use specified linter", "Known linters are: #{known_linter_names.join(', ')}") do |linters|
283
+ "Only use specified linter", "Known linters are: #{known_linter_names.join(", ")}") do |linters|
259
284
  linters.each do |linter|
260
285
  unless known_linter_names.include?(linter)
261
- failure!("#{linter}: not a valid linter name (#{known_linter_names.join(', ')})")
286
+ failure!("#{linter}: not a valid linter name (#{known_linter_names.join(", ")})")
262
287
  end
263
288
  end
264
289
  @options[:enabled_linters] = linters
265
290
  end
266
291
 
292
+ opts.on("--fail-level SEVERITY", "Minimum severity for exit with error code") do |level|
293
+ parsed_severity = SEVERITY_CODE_TABLE[level.upcase.to_sym] || (SEVERITY_NAMES & [level.downcase]).first
294
+
295
+ if parsed_severity.nil?
296
+ failure!("#{level}: not a valid failure level (#{SEVERITY_NAMES.join(", ")})")
297
+ end
298
+ @options[:fail_level] = severity_level_for_name(parsed_severity)
299
+ end
300
+
267
301
  opts.on("-a", "--autocorrect", "Correct offenses automatically if possible (default: false)") do |config|
268
302
  @options[:autocorrect] = config
269
303
  end
270
304
 
305
+ opts.on(
306
+ "-sFILE",
307
+ "--stdin FILE",
308
+ "Pipe source from STDIN. Takes the path to be used to check which rules to apply."
309
+ ) do |file|
310
+ @options[:stdin] = [file]
311
+ end
312
+
271
313
  opts.on_tail("-h", "--help", "Show this message") do
272
314
  success!(opts)
273
315
  end
@@ -280,12 +322,16 @@ module ERBLint
280
322
 
281
323
  def format_options_help
282
324
  "Report offenses in the given format: "\
283
- "(#{Reporter.available_formats.join(', ')}) (default: multiline)"
325
+ "(#{Reporter.available_formats.join(", ")}) (default: multiline)"
284
326
  end
285
327
 
286
328
  def invalid_format_error_message(given_format)
287
329
  formats = Reporter.available_formats.map { |format| " - #{format}\n" }
288
330
  "#{given_format}: is not a valid format. Available formats:\n#{formats.join}"
289
331
  end
332
+
333
+ def stdin?
334
+ @options[:stdin].present?
335
+ end
290
336
  end
291
337
  end
@@ -21,7 +21,7 @@ module ERBLint
21
21
  end
22
22
 
23
23
  if ::RuboCop::Version::STRING.to_f >= 0.87
24
- require 'rubocop/cop/legacy/corrector'
24
+ require "rubocop/cop/legacy/corrector"
25
25
  BASE = ::RuboCop::Cop::Legacy::Corrector
26
26
 
27
27
  def diagnostics
@@ -15,9 +15,9 @@ module ERBLint
15
15
  # `ERBLint::Linters::Compass::Bar.simple_name` #=> "Compass::Bar"
16
16
  def inherited(linter)
17
17
  super
18
- linter.simple_name = if linter.name.start_with?('ERBLint::Linters::')
19
- name_parts = linter.name.split('::')
20
- name_parts[2..-1].join('::')
18
+ linter.simple_name = if linter.name.start_with?("ERBLint::Linters::")
19
+ name_parts = linter.name.split("::")
20
+ name_parts[2..-1].join("::")
21
21
  else
22
22
  linter.name
23
23
  end
@@ -53,8 +53,8 @@ module ERBLint
53
53
  raise NotImplementedError, "must implement ##{__method__}"
54
54
  end
55
55
 
56
- def add_offense(source_range, message, context = nil)
57
- @offenses << Offense.new(self, source_range, message, context)
56
+ def add_offense(source_range, message, context = nil, severity = nil)
57
+ @offenses << Offense.new(self, source_range, message, context, severity)
58
58
  end
59
59
 
60
60
  def clear_offenses
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support'
4
- require 'smart_properties'
3
+ require "active_support"
4
+ require "smart_properties"
5
5
 
6
6
  module ERBLint
7
7
  class LinterConfig
@@ -27,8 +27,9 @@ module ERBLint
27
27
  allowed_keys = self.class.properties.keys.map(&:to_s)
28
28
  given_keys = config.keys
29
29
  if (extra_keys = given_keys - allowed_keys).any?
30
- raise Error, "Given key is not allowed: #{extra_keys.join(', ')}"
30
+ raise Error, "Given key is not allowed: #{extra_keys.join(", ")}"
31
31
  end
32
+
32
33
  super(config)
33
34
  rescue SmartProperties::InitializationError => e
34
35
  raise Error, "The following properties are required to be set: #{e.properties}"
@@ -40,6 +41,7 @@ module ERBLint
40
41
  unless self.class.properties.key?(name)
41
42
  raise Error, "No such property: #{name}"
42
43
  end
44
+
43
45
  super
44
46
  end
45
47
 
@@ -3,7 +3,7 @@
3
3
  module ERBLint
4
4
  # Stores all linters available to the application.
5
5
  module LinterRegistry
6
- CUSTOM_LINTERS_DIR = '.erb-linters'
6
+ CUSTOM_LINTERS_DIR = ".erb-linters"
7
7
  @loaded_linters = []
8
8
 
9
9
  class << self
@@ -27,7 +27,7 @@ module ERBLint
27
27
  end
28
28
 
29
29
  def load_custom_linters(directory = CUSTOM_LINTERS_DIR)
30
- ruby_files = Dir.glob(File.expand_path(File.join(directory, '**', '*.rb')))
30
+ ruby_files = Dir.glob(File.expand_path(File.join(directory, "**", "*.rb")))
31
31
  ruby_files.each { |file| require file }
32
32
  end
33
33
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html'
4
- require 'better_html/tree/tag'
3
+ require "better_html"
4
+ require "better_html/tree/tag"
5
5
 
6
6
  module ERBLint
7
7
  module Linters
@@ -13,7 +13,7 @@ module ERBLint
13
13
 
14
14
  class ConfigSchema < LinterConfig
15
15
  property :allowed_types, accepts: array_of?(String),
16
- default: -> { ['text/javascript'] }
16
+ default: -> { ["text/javascript"] }
17
17
  property :allow_blank, accepts: [true, false], default: true, reader: :allow_blank?
18
18
  property :disallow_inline_scripts, accepts: [true, false], default: false, reader: :disallow_inline_scripts?
19
19
  end
@@ -24,19 +24,19 @@ module ERBLint
24
24
  parser.nodes_with_type(:tag).each do |tag_node|
25
25
  tag = BetterHtml::Tree::Tag.from_node(tag_node)
26
26
  next if tag.closing?
27
- next unless tag.name == 'script'
27
+ next unless tag.name == "script"
28
28
 
29
29
  if @config.disallow_inline_scripts?
30
30
  name_node = tag_node.to_a[1]
31
31
  add_offense(
32
32
  name_node.loc,
33
33
  "Avoid using inline `<script>` tags altogether. "\
34
- "Instead, move javascript code into a static file."
34
+ "Instead, move javascript code into a static file."
35
35
  )
36
36
  next
37
37
  end
38
38
 
39
- type_attribute = tag.attributes['type']
39
+ type_attribute = tag.attributes["type"]
40
40
  type_present = type_attribute.present? && type_attribute.value_node.present?
41
41
 
42
42
  if !type_present && !@config.allow_blank?
@@ -50,8 +50,8 @@ module ERBLint
50
50
  add_offense(
51
51
  type_attribute.loc,
52
52
  "Avoid using #{type_attribute.value.inspect} as type for `<script>` tag. "\
53
- "Must be one of: #{@config.allowed_types.join(', ')}"\
54
- "#{' (or no type attribute)' if @config.allow_blank?}."
53
+ "Must be one of: #{@config.allowed_types.join(", ")}"\
54
+ "#{" (or no type attribute)" if @config.allow_blank?}."
55
55
  )
56
56
  end
57
57
  end
@@ -59,6 +59,7 @@ module ERBLint
59
59
 
60
60
  def autocorrect(_processed_source, offense)
61
61
  return unless offense.context
62
+
62
63
  lambda do |corrector|
63
64
  type_attribute, = *offense.context
64
65
  if type_attribute.nil?
@@ -25,7 +25,7 @@ module ERBLint
25
25
  add_offense(
26
26
  code_node.loc.end.adjust(begin_pos: -end_spaces.size),
27
27
  "Remove newline before `%>` to match start of tag.",
28
- ' '
28
+ " "
29
29
  )
30
30
  elsif start_with_newline && !end_with_newline
31
31
  add_offense(
@@ -39,7 +39,7 @@ module ERBLint
39
39
  add_offense(
40
40
  code_node.loc.end.adjust(begin_pos: -current_indent.size),
41
41
  "Indent `%>` on column #{erb_node.loc.column} to match start of tag.",
42
- ' ' * erb_node.loc.column
42
+ " " * erb_node.loc.column
43
43
  )
44
44
  end
45
45
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html'
4
- require 'better_html/parser'
3
+ require "better_html"
4
+ require "better_html/parser"
5
5
 
6
6
  module ERBLint
7
7
  module Linters
@@ -11,7 +11,7 @@ module ERBLint
11
11
 
12
12
  class RuleSet
13
13
  include SmartProperties
14
- property :suggestion, accepts: String, default: ''
14
+ property :suggestion, accepts: String, default: ""
15
15
  property :deprecated, accepts: LinterConfig.array_of?(String), default: -> { [] }
16
16
  end
17
17
 
@@ -57,9 +57,10 @@ module ERBLint
57
57
  def class_name_with_loc(processed_source)
58
58
  Enumerator.new do |yielder|
59
59
  tags(processed_source).each do |tag|
60
- class_value = tag.attributes['class']&.value
60
+ class_value = tag.attributes["class"]&.value
61
61
  next unless class_value
62
- class_value.split(' ').each do |class_name|
62
+
63
+ class_value.split(" ").each do |class_name|
63
64
  yielder.yield(class_name, tag.loc)
64
65
  end
65
66
  end
@@ -69,7 +70,7 @@ module ERBLint
69
70
  def text_tags_content(processed_source)
70
71
  Enumerator.new do |yielder|
71
72
  script_tags(processed_source)
72
- .select { |tag| tag.attributes['type']&.value == 'text/html' }
73
+ .select { |tag| tag.attributes["type"]&.value == "text/html" }
73
74
  .each do |tag|
74
75
  index = processed_source.ast.to_a.find_index(tag.node)
75
76
  next_node = processed_source.ast.to_a[index + 1]
@@ -80,7 +81,7 @@ module ERBLint
80
81
  end
81
82
 
82
83
  def script_tags(processed_source)
83
- tags(processed_source).select { |tag| tag.name == 'script' }
84
+ tags(processed_source).select { |tag| tag.name == "script" }
84
85
  end
85
86
 
86
87
  def tags(processed_source)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html'
4
- require 'better_html/test_helper/safe_erb_tester'
3
+ require "better_html"
4
+ require "better_html/test_helper/safe_erb_tester"
5
5
 
6
6
  module ERBLint
7
7
  module Linters
@@ -22,7 +22,7 @@ module ERBLint
22
22
 
23
23
  def autocorrect(_processed_source, offense)
24
24
  lambda do |corrector|
25
- corrector.replace(offense.source_range, '')
25
+ corrector.replace(offense.source_range, "")
26
26
  end
27
27
  end
28
28
  end
@@ -28,7 +28,7 @@ module ERBLint
28
28
  if final_newline.empty?
29
29
  add_offense(
30
30
  processed_source.to_source_range(file_content.size...file_content.size),
31
- 'Missing a trailing newline at the end of the file.',
31
+ "Missing a trailing newline at the end of the file.",
32
32
  :insert
33
33
  )
34
34
  else
@@ -36,7 +36,7 @@ module ERBLint
36
36
  processed_source.to_source_range(
37
37
  (file_content.size - final_newline.size + 1)...file_content.size
38
38
  ),
39
- 'Remove multiple trailing newline at the end of the file.',
39
+ "Remove multiple trailing newline at the end of the file.",
40
40
  :remove
41
41
  )
42
42
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "set"
3
- require 'better_html/tree/tag'
4
- require 'active_support/core_ext/string/inflections'
4
+ require "better_html/tree/tag"
5
+ require "active_support/core_ext/string/inflections"
5
6
 
6
7
  module ERBLint
7
8
  module Linters
@@ -13,17 +14,37 @@ module ERBLint
13
14
  MissingCorrector = Class.new(StandardError)
14
15
  MissingI18nLoadPath = Class.new(StandardError)
15
16
 
16
- ALLOWED_CORRECTORS = %w(
17
- I18nCorrector
18
- RuboCop::Corrector::I18n::HardCodedString
19
- )
20
-
21
- NON_TEXT_TAGS = Set.new(%w(script style xmp iframe noembed noframes listing))
22
- BLACK_LISTED_TEXT = Set.new(%w(&nbsp; &ensp; &emsp; &thinsp;))
17
+ ALLOWED_CORRECTORS = ["I18nCorrector", "RuboCop::Corrector::I18n::HardCodedString"]
18
+
19
+ NON_TEXT_TAGS = Set.new(["script", "style", "xmp", "iframe", "noembed", "noframes", "listing"])
20
+ TEXT_NOT_ALLOWED = Set.new([
21
+ "&nbsp;",
22
+ "&amp;",
23
+ "&lt;",
24
+ "&gt;",
25
+ "&quot;",
26
+ "&copy;",
27
+ "&reg;",
28
+ "&trade;",
29
+ "&hellip;",
30
+ "&mdash;",
31
+ "&bull;",
32
+ "&ldquo;",
33
+ "&rdquo;",
34
+ "&lsquo;",
35
+ "&rsquo;",
36
+ "&larr;",
37
+ "&rarr;",
38
+ "&darr;",
39
+ "&uarr;",
40
+ "&ensp;",
41
+ "&emsp;",
42
+ "&thinsp;",
43
+ ])
23
44
 
24
45
  class ConfigSchema < LinterConfig
25
46
  property :corrector, accepts: Hash, required: false, default: -> { {} }
26
- property :i18n_load_path, accepts: String, required: false, default: ''
47
+ property :i18n_load_path, accepts: String, required: false, default: ""
27
48
  end
28
49
  self.config_schema = ConfigSchema
29
50
 
@@ -63,9 +84,10 @@ module ERBLint
63
84
  string = offense.source_range.source
64
85
  return unless (klass = load_corrector)
65
86
  return unless string.strip.length > 1
87
+
66
88
  node = ::RuboCop::AST::StrNode.new(:str, [string])
67
89
  corrector = klass.new(node, processed_source.filename, corrector_i18n_load_path, offense.source_range)
68
- corrector.autocorrect(tag_start: '<%= ', tag_end: ' %>')
90
+ corrector.autocorrect(tag_start: "<%= ", tag_end: " %>")
69
91
  rescue MissingCorrector, MissingI18nLoadPath
70
92
  nil
71
93
  end
@@ -73,20 +95,21 @@ module ERBLint
73
95
  private
74
96
 
75
97
  def check_string?(str)
76
- string = str.gsub(/\s*/, '')
77
- string.length > 1 && !BLACK_LISTED_TEXT.include?(string)
98
+ string = str.gsub(/\s*/, "")
99
+ string.length > 1 && !TEXT_NOT_ALLOWED.include?(string)
78
100
  end
79
101
 
80
102
  def load_corrector
81
- corrector_name = @config['corrector'].fetch('name') { raise MissingCorrector }
103
+ corrector_name = @config["corrector"].fetch("name") { raise MissingCorrector }
82
104
  raise ForbiddenCorrector unless ALLOWED_CORRECTORS.include?(corrector_name)
83
- require @config['corrector'].fetch('path') { raise MissingCorrector }
105
+
106
+ require @config["corrector"].fetch("path") { raise MissingCorrector }
84
107
 
85
108
  corrector_name.safe_constantize
86
109
  end
87
110
 
88
111
  def corrector_i18n_load_path
89
- @config['corrector'].fetch('i18n_load_path') { raise MissingI18nLoadPath }
112
+ @config["corrector"].fetch("i18n_load_path") { raise MissingI18nLoadPath }
90
113
  end
91
114
 
92
115
  def non_text_tag?(processed_source, text_node)