erb_lint 0.1.0 → 0.1.3

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/exe/erblint +1 -1
  3. data/lib/erb_lint/all.rb +15 -15
  4. data/lib/erb_lint/cli.rb +20 -23
  5. data/lib/erb_lint/corrector.rb +1 -1
  6. data/lib/erb_lint/linter.rb +4 -4
  7. data/lib/erb_lint/linter_config.rb +10 -5
  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 -36
  16. data/lib/erb_lint/linters/no_javascript_tag_helper.rb +11 -9
  17. data/lib/erb_lint/linters/partial_instance_variable.rb +1 -1
  18. data/lib/erb_lint/linters/require_input_autocomplete.rb +8 -10
  19. data/lib/erb_lint/linters/require_script_nonce.rb +10 -10
  20. data/lib/erb_lint/linters/right_trim.rb +1 -1
  21. data/lib/erb_lint/linters/rubocop.rb +12 -10
  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 +1 -0
  29. data/lib/erb_lint/reporter.rb +4 -2
  30. data/lib/erb_lint/reporters/compact_reporter.rb +9 -2
  31. data/lib/erb_lint/reporters/multiline_reporter.rb +2 -1
  32. data/lib/erb_lint/runner.rb +1 -1
  33. data/lib/erb_lint/runner_config.rb +8 -7
  34. data/lib/erb_lint/runner_config_resolver.rb +5 -4
  35. data/lib/erb_lint/stats.rb +10 -6
  36. data/lib/erb_lint/utils/block_map.rb +3 -2
  37. data/lib/erb_lint/utils/offset_corrector.rb +2 -2
  38. data/lib/erb_lint/utils/ruby_to_erb.rb +6 -5
  39. data/lib/erb_lint/utils/severity_levels.rb +2 -2
  40. data/lib/erb_lint/version.rb +1 -1
  41. data/lib/erb_lint.rb +1 -1
  42. metadata +17 -17
@@ -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,6 @@ module ERBLint
13
13
  "date",
14
14
  "datetime-local",
15
15
  "email",
16
- "hidden",
17
16
  "month",
18
17
  "number",
19
18
  "password",
@@ -33,7 +32,6 @@ module ERBLint
33
32
  :text_field_tag,
34
33
  :utf8_enforcer_tag,
35
34
  :month_field_tag,
36
- :hidden_field_tag,
37
35
  :number_field_tag,
38
36
  :password_field_tag,
39
37
  :search_field_tag,
@@ -56,8 +54,8 @@ module ERBLint
56
54
  parser.nodes_with_type(:tag).each do |tag_node|
57
55
  tag = BetterHtml::Tree::Tag.from_node(tag_node)
58
56
 
59
- autocomplete_attribute = tag.attributes['autocomplete']
60
- type_attribute = tag.attributes['type']
57
+ autocomplete_attribute = tag.attributes["autocomplete"]
58
+ type_attribute = tag.attributes["type"]
61
59
 
62
60
  next if !html_input_tag?(tag) || autocomplete_present?(autocomplete_attribute)
63
61
  next unless html_type_requires_autocomplete_attribute?(type_attribute)
@@ -65,7 +63,7 @@ module ERBLint
65
63
  add_offense(
66
64
  tag_node.to_a[1].loc,
67
65
  "Input tag is missing an autocomplete attribute. If no "\
68
- "autocomplete behaviour is desired, use the value `off` or `nope`.",
66
+ "autocomplete behaviour is desired, use the value `off` or `nope`.",
69
67
  [autocomplete_attribute]
70
68
  )
71
69
  end
@@ -76,7 +74,7 @@ module ERBLint
76
74
  end
77
75
 
78
76
  def html_input_tag?(tag)
79
- !tag.closing? && tag.name == 'input'
77
+ !tag.closing? && tag.name == "input"
80
78
  end
81
79
 
82
80
  def html_type_requires_autocomplete_attribute?(type_attribute)
@@ -99,7 +97,7 @@ module ERBLint
99
97
  add_offense(
100
98
  erb_node.loc,
101
99
  "Input field helper is missing an autocomplete attribute. If no "\
102
- "autocomplete behaviour is desired, use the value `off` or `nope`.",
100
+ "autocomplete behaviour is desired, use the value `off` or `nope`.",
103
101
  [erb_node, send_node]
104
102
  )
105
103
  end
@@ -110,7 +108,7 @@ module ERBLint
110
108
  end
111
109
 
112
110
  def code_comment?(indicator_node)
113
- indicator_node&.loc&.source == '#'
111
+ indicator_node&.loc&.source == "#"
114
112
  end
115
113
 
116
114
  def extract_ruby_node(source)
@@ -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
@@ -22,7 +22,7 @@ module ERBLint
22
22
  def find_html_script_tags(parser)
23
23
  parser.nodes_with_type(:tag).each do |tag_node|
24
24
  tag = BetterHtml::Tree::Tag.from_node(tag_node)
25
- nonce_attribute = tag.attributes['nonce']
25
+ nonce_attribute = tag.attributes["nonce"]
26
26
 
27
27
  next if !html_javascript_tag?(tag) || nonce_present?(nonce_attribute)
28
28
 
@@ -40,16 +40,16 @@ module ERBLint
40
40
 
41
41
  def html_javascript_tag?(tag)
42
42
  !tag.closing? &&
43
- (tag.name == 'script' && !html_javascript_type_attribute?(tag))
43
+ (tag.name == "script" && !html_javascript_type_attribute?(tag))
44
44
  end
45
45
 
46
46
  def html_javascript_type_attribute?(tag)
47
- type_attribute = tag.attributes['type']
47
+ type_attribute = tag.attributes["type"]
48
48
 
49
49
  type_attribute &&
50
50
  type_attribute.value_node.present? &&
51
- type_attribute.value_node.to_a[1] != 'text/javascript' &&
52
- type_attribute.value_node.to_a[1] != 'application/javascript'
51
+ type_attribute.value_node.to_a[1] != "text/javascript" &&
52
+ type_attribute.value_node.to_a[1] != "application/javascript"
53
53
  end
54
54
 
55
55
  def find_rails_helper_script_tags(parser)
@@ -74,12 +74,12 @@ module ERBLint
74
74
 
75
75
  def tag_helper?(send_node)
76
76
  send_node&.method_name?(:javascript_tag) ||
77
- send_node&.method_name?(:javascript_include_tag) ||
78
- send_node&.method_name?(:javascript_pack_tag)
77
+ send_node&.method_name?(:javascript_include_tag) ||
78
+ send_node&.method_name?(:javascript_pack_tag)
79
79
  end
80
80
 
81
81
  def code_comment?(indicator_node)
82
- indicator_node&.loc&.source == '#'
82
+ indicator_node&.loc&.source == "#"
83
83
  end
84
84
 
85
85
  def extract_ruby_node(source)
@@ -8,7 +8,7 @@ module ERBLint
8
8
  include LinterRegistry
9
9
 
10
10
  class ConfigSchema < LinterConfig
11
- property :enforced_style, accepts: ['-', '='], default: '-'
11
+ property :enforced_style, accepts: ["-", "="], default: "-"
12
12
  end
13
13
  self.config_schema = ConfigSchema
14
14
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html'
4
- require 'tempfile'
5
- require 'erb_lint/utils/offset_corrector'
3
+ require "better_html"
4
+ require "tempfile"
5
+ require "erb_lint/utils/offset_corrector"
6
6
 
7
7
  module ERBLint
8
8
  module Linters
@@ -25,7 +25,7 @@ module ERBLint
25
25
  super
26
26
  @only_cops = @config.only
27
27
  custom_config = config_from_hash(@config.rubocop_config)
28
- @rubocop_config = ::RuboCop::ConfigLoader.merge_with_default(custom_config, '')
28
+ @rubocop_config = ::RuboCop::ConfigLoader.merge_with_default(custom_config, "")
29
29
  end
30
30
 
31
31
  def run(processed_source)
@@ -37,6 +37,7 @@ module ERBLint
37
37
  if ::RuboCop::Version::STRING.to_f >= 0.87
38
38
  def autocorrect(_processed_source, offense)
39
39
  return unless offense.context
40
+
40
41
  rubocop_correction = offense.context[:rubocop_correction]
41
42
  return unless rubocop_correction
42
43
 
@@ -68,13 +69,13 @@ module ERBLint
68
69
 
69
70
  def inspect_content(processed_source, erb_node)
70
71
  indicator, _, code_node, = *erb_node
71
- return if indicator&.children&.first == '#'
72
+ return if indicator&.children&.first == "#"
72
73
 
73
74
  original_source = code_node.loc.source
74
- trimmed_source = original_source.sub(BLOCK_EXPR, '').sub(SUFFIX_EXPR, '')
75
+ trimmed_source = original_source.sub(BLOCK_EXPR, "").sub(SUFFIX_EXPR, "")
75
76
  alignment_column = code_node.loc.column
76
77
  offset = code_node.loc.begin_pos - alignment_column
77
- aligned_source = "#{' ' * alignment_column}#{trimmed_source}"
78
+ aligned_source = "#{" " * alignment_column}#{trimmed_source}"
78
79
 
79
80
  source = rubocop_processed_source(aligned_source, processed_source.filename)
80
81
  return unless source.valid_syntax?
@@ -150,16 +151,17 @@ module ERBLint
150
151
  @rubocop_config,
151
152
  extra_details: true,
152
153
  display_cop_names: true,
154
+ autocorrect: true,
153
155
  auto_correct: true,
154
156
  stdin: "",
155
157
  )
156
158
  end
157
159
 
158
160
  def config_from_hash(hash)
159
- inherit_from = hash&.delete('inherit_from')
161
+ inherit_from = hash&.delete("inherit_from")
160
162
  resolve_inheritance(hash, inherit_from)
161
163
 
162
- tempfile_from('.erblint-rubocop', hash.to_yaml) do |tempfile|
164
+ tempfile_from(".erblint-rubocop", hash.to_yaml) do |tempfile|
163
165
  ::RuboCop::ConfigLoader.load_file(tempfile.path)
164
166
  end
165
167
  end
@@ -174,7 +176,7 @@ module ERBLint
174
176
  end
175
177
 
176
178
  def base_configs(inherit_from)
177
- regex = URI::DEFAULT_PARSER.make_regexp(%w(http https))
179
+ regex = URI::DEFAULT_PARSER.make_regexp(["http", "https"])
178
180
  configs = Array(inherit_from).compact.map do |base_name|
179
181
  if base_name =~ /\A#{regex}\z/
180
182
  ::RuboCop::ConfigLoader.load_file(::RuboCop::RemoteConfig.new(base_name, Dir.pwd))
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'rubocop'
3
+ require_relative "rubocop"
4
4
 
5
5
  module ERBLint
6
6
  module Linters
@@ -11,10 +11,8 @@ module ERBLint
11
11
  end
12
12
  self.config_schema = ConfigSchema
13
13
 
14
- SELF_CLOSING_TAGS = %w(
15
- area base br col command embed hr input keygen
16
- link menuitem meta param source track wbr img
17
- )
14
+ SELF_CLOSING_TAGS = ["area", "base", "br", "col", "command", "embed", "hr", "input", "keygen", "link",
15
+ "menuitem", "meta", "param", "source", "track", "wbr", "img",]
18
16
 
19
17
  def run(processed_source)
20
18
  processed_source.ast.descendants(:tag).each do |tag_node|
@@ -26,7 +24,7 @@ module ERBLint
26
24
  add_offense(
27
25
  start_solidus.loc,
28
26
  "Tag `#{tag.name}` is a void element, it must not start with `</`.",
29
- ''
27
+ ""
30
28
  )
31
29
  end
32
30
 
@@ -34,16 +32,17 @@ module ERBLint
34
32
  add_offense(
35
33
  tag_node.loc.end.offset(-1),
36
34
  "Tag `#{tag.name}` is self-closing, it must end with `/>`.",
37
- '/'
35
+ "/"
38
36
  )
39
37
  end
40
38
 
41
39
  next unless @config.enforced_style == :never && tag.self_closing?
40
+
42
41
  end_solidus = tag_node.children.last
43
42
  add_offense(
44
43
  end_solidus.loc,
45
44
  "Tag `#{tag.name}` is a void element, it must end with `>` and not `/>`.",
46
- ''
45
+ ""
47
46
  )
48
47
  end
49
48
  end
@@ -15,7 +15,8 @@ module ERBLint
15
15
  processed_source.ast.descendants(:erb).each do |erb_node|
16
16
  indicator_node, ltrim, code_node, rtrim = *erb_node
17
17
  indicator = indicator_node&.loc&.source
18
- next if indicator == '#' || indicator == '%'
18
+ next if indicator == "#" || indicator == "%"
19
+
19
20
  code = code_node.children.first
20
21
 
21
22
  start_spaces = code.match(START_SPACES)&.captures&.first || ""
@@ -23,15 +24,15 @@ module ERBLint
23
24
  add_offense(
24
25
  code_node.loc.resize(start_spaces.size),
25
26
  "Use 1 space after `<%#{indicator}#{ltrim&.loc&.source}` "\
26
- "instead of #{start_spaces.size} space#{'s' if start_spaces.size > 1}.",
27
- ' '
27
+ "instead of #{start_spaces.size} space#{"s" if start_spaces.size > 1}.",
28
+ " "
28
29
  )
29
30
  elsif start_spaces.count("\n") > 1
30
31
  lines = start_spaces.split("\n", -1)
31
32
  add_offense(
32
33
  code_node.loc.resize(start_spaces.size),
33
34
  "Use 1 newline after `<%#{indicator&.loc&.source}#{ltrim&.loc&.source}` "\
34
- "instead of #{start_spaces.count("\n")}.",
35
+ "instead of #{start_spaces.count("\n")}.",
35
36
  "#{lines.first}\n#{lines.last}"
36
37
  )
37
38
  end
@@ -41,15 +42,15 @@ module ERBLint
41
42
  add_offense(
42
43
  code_node.loc.end.adjust(begin_pos: -end_spaces.size),
43
44
  "Use 1 space before `#{rtrim&.loc&.source}%>` "\
44
- "instead of #{end_spaces.size} space#{'s' if start_spaces.size > 1}.",
45
- ' '
45
+ "instead of #{end_spaces.size} space#{"s" if start_spaces.size > 1}.",
46
+ " "
46
47
  )
47
48
  elsif end_spaces.count("\n") > 1
48
49
  lines = end_spaces.split("\n", -1)
49
50
  add_offense(
50
51
  code_node.loc.end.adjust(begin_pos: -end_spaces.size),
51
52
  "Use 1 newline before `#{rtrim&.loc&.source}%>` "\
52
- "instead of #{end_spaces.count("\n")}.",
53
+ "instead of #{end_spaces.count("\n")}.",
53
54
  "#{lines.first}\n#{lines.last}"
54
55
  )
55
56
  end
@@ -50,7 +50,7 @@ module ERBLint
50
50
  add_offense(
51
51
  processed_source.to_source_range(range),
52
52
  "Extra space detected where there should be no space.",
53
- ''
53
+ ""
54
54
  )
55
55
  end
56
56
 
@@ -60,24 +60,24 @@ module ERBLint
60
60
 
61
61
  def single_space(processed_source, range, accept_newline: false)
62
62
  chars = processed_source.file_content[range]
63
- return if chars == ' '
63
+ return if chars == " "
64
64
 
65
65
  newlines = chars.include?("\n")
66
- expected = newlines && accept_newline ? "\n#{chars.split("\n", -1).last}" : ' '
66
+ expected = newlines && accept_newline ? "\n#{chars.split("\n", -1).last}" : " "
67
67
  non_space = chars.match(/([^[[:space:]]])/m)
68
68
 
69
69
  if non_space && !non_space.captures.empty?
70
70
  add_offense(
71
71
  processed_source.to_source_range(range),
72
72
  "Non-whitespace character(s) detected: "\
73
- "#{non_space.captures.map(&:inspect).join(', ')}.",
73
+ "#{non_space.captures.map(&:inspect).join(", ")}.",
74
74
  expected
75
75
  )
76
76
  elsif newlines && accept_newline
77
77
  if expected != chars
78
78
  add_offense(
79
79
  processed_source.to_source_range(range),
80
- "#{chars.empty? ? 'No' : 'Extra'} space detected where there should be "\
80
+ "#{chars.empty? ? "No" : "Extra"} space detected where there should be "\
81
81
  "a single space or a single line break.",
82
82
  expected
83
83
  )
@@ -85,7 +85,7 @@ module ERBLint
85
85
  else
86
86
  add_offense(
87
87
  processed_source.to_source_range(range),
88
- "#{chars.empty? ? 'No' : 'Extra'} space detected where there should be a single space.",
88
+ "#{chars.empty? ? "No" : "Extra"} space detected where there should be a single space.",
89
89
  expected
90
90
  )
91
91
  end
@@ -98,6 +98,7 @@ module ERBLint
98
98
  no_space(processed_source, equal.loc.end_pos...value.loc.begin_pos) if equal && value
99
99
 
100
100
  next if index >= attributes.children.size - 1
101
+
101
102
  next_attribute = attributes.children[index + 1]
102
103
 
103
104
  single_space_or_newline(
@@ -23,7 +23,7 @@ module ERBLint
23
23
  add_offense(
24
24
  processed_source.to_source_range(document_pos...(document_pos + spaces.length)),
25
25
  "Indent with spaces instead of tabs.",
26
- spaces.gsub("\t", ' ' * @config.tab_width)
26
+ spaces.gsub("\t", " " * @config.tab_width)
27
27
  )
28
28
  end
29
29
 
@@ -25,7 +25,7 @@ module ERBLint
25
25
 
26
26
  def autocorrect(_processed_source, offense)
27
27
  lambda do |corrector|
28
- corrector.replace(offense.source_range, '')
28
+ corrector.replace(offense.source_range, "")
29
29
  end
30
30
  end
31
31
  end
@@ -9,6 +9,7 @@ module ERBLint
9
9
  unless source_range.is_a?(Parser::Source::Range)
10
10
  raise ArgumentError, "expected Parser::Source::Range for arg 2"
11
11
  end
12
+
12
13
  @linter = linter
13
14
  @source_range = source_range
14
15
  @message = message
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/core_ext/class'
3
- require 'active_support/core_ext/module/delegation'
2
+
3
+ require "active_support/core_ext/class"
4
+ require "active_support/core_ext/module/delegation"
4
5
 
5
6
  module ERBLint
6
7
  class Reporter
@@ -34,6 +35,7 @@ module ERBLint
34
35
  private
35
36
 
36
37
  attr_reader :stats, :autocorrect
38
+
37
39
  delegate :processed_files, to: :stats
38
40
  end
39
41
  end
@@ -4,8 +4,7 @@ module ERBLint
4
4
  module Reporters
5
5
  class CompactReporter < Reporter
6
6
  def preview
7
- puts "Linting #{stats.files} files with "\
8
- "#{stats.linters} #{'autocorrectable ' if autocorrect}linters..."
7
+ puts "#{linting} #{stats.files} files with #{linters}..."
9
8
  end
10
9
 
11
10
  def show
@@ -21,6 +20,14 @@ module ERBLint
21
20
 
22
21
  private
23
22
 
23
+ def linting
24
+ "Linting" + (autocorrect ? " and autocorrecting" : "")
25
+ end
26
+
27
+ def linters
28
+ "#{stats.linters} linters" + (autocorrect ? " (#{stats.autocorrectable_linters} autocorrectable)" : "")
29
+ end
30
+
24
31
  def format_offense(filename, offense)
25
32
  [
26
33
  "#{filename}:",
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "compact_reporter"
3
4
 
4
5
  module ERBLint
@@ -9,7 +10,7 @@ module ERBLint
9
10
  def format_offense(filename, offense)
10
11
  <<~EOF
11
12
 
12
- #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect}
13
+ #{offense.message}#{Rainbow(" (not autocorrected)").red if autocorrect}
13
14
  In file: #{filename}:#{offense.line_number}
14
15
  EOF
15
16
  end
@@ -8,7 +8,7 @@ module ERBLint
8
8
  def initialize(file_loader, config)
9
9
  @file_loader = file_loader
10
10
  @config = config || RunnerConfig.default
11
- raise ArgumentError, 'expect `config` to be a RunnerConfig instance' unless @config.is_a?(RunnerConfig)
11
+ raise ArgumentError, "expect `config` to be a RunnerConfig instance" unless @config.is_a?(RunnerConfig)
12
12
 
13
13
  linter_classes = LinterRegistry.linters.select { |klass| @config.for_linter(klass).enabled? }
14
14
  @linters = linter_classes.map do |linter_class|
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb_lint/runner_config_resolver'
3
+ require "erb_lint/runner_config_resolver"
4
4
 
5
5
  module ERBLint
6
6
  class RunnerConfig
@@ -9,7 +9,7 @@ module ERBLint
9
9
  def initialize(config = nil, file_loader = nil)
10
10
  @config = (config || {}).dup.deep_stringify_keys
11
11
 
12
- resolver.resolve_inheritance_from_gems(@config, @config.delete('inherit_gem'))
12
+ resolver.resolve_inheritance_from_gems(@config, @config.delete("inherit_gem"))
13
13
  resolver.resolve_inheritance(@config, file_loader) if file_loader
14
14
  @config.delete("inherit_from")
15
15
  end
@@ -24,15 +24,16 @@ module ERBLint
24
24
  elsif klass.is_a?(Class) && klass <= ERBLint::Linter
25
25
  klass.simple_name
26
26
  else
27
- raise ArgumentError, 'expected String or linter class'
27
+ raise ArgumentError, "expected String or linter class"
28
28
  end
29
29
  linter_klass = LinterRegistry.find_by_name(klass_name)
30
30
  raise Error, "#{klass_name}: linter not found (is it loaded?)" unless linter_klass
31
+
31
32
  linter_klass.config_schema.new(config_hash_for_linter(klass_name))
32
33
  end
33
34
 
34
35
  def global_exclude
35
- @config['exclude'] || []
36
+ @config["exclude"] || []
36
37
  end
37
38
 
38
39
  def merge(other_config)
@@ -75,13 +76,13 @@ module ERBLint
75
76
  private
76
77
 
77
78
  def linters_config
78
- @config['linters'] || {}
79
+ @config["linters"] || {}
79
80
  end
80
81
 
81
82
  def config_hash_for_linter(klass_name)
82
83
  config_hash = linters_config[klass_name] || {}
83
- config_hash['exclude'] ||= []
84
- config_hash['exclude'].concat(global_exclude) if config_hash['exclude'].is_a?(Array)
84
+ config_hash["exclude"] ||= []
85
+ config_hash["exclude"].concat(global_exclude) if config_hash["exclude"].is_a?(Array)
85
86
  config_hash
86
87
  end
87
88
 
@@ -24,10 +24,11 @@
24
24
  module ERBLint
25
25
  class RunnerConfigResolver
26
26
  def resolve_inheritance(hash, file_loader)
27
- inherited_files = Array(hash['inherit_from'])
27
+ inherited_files = Array(hash["inherit_from"])
28
28
  base_configs(file_loader, inherited_files).reverse_each do |base_config|
29
29
  base_config.each do |k, v|
30
30
  next unless v.is_a?(Hash)
31
+
31
32
  v = v.deep_merge(hash[k]) if hash.key?(k)
32
33
  hash[k] = v
33
34
  end
@@ -36,12 +37,12 @@ module ERBLint
36
37
 
37
38
  def resolve_inheritance_from_gems(hash, gems)
38
39
  (gems || {}).each_pair do |gem_name, config_path|
39
- raise(ArgumentError, "can't inherit configuration from the erb-lint gem") if gem_name == 'erb-lint'
40
+ raise(ArgumentError, "can't inherit configuration from the erb-lint gem") if gem_name == "erb-lint"
40
41
 
41
- hash['inherit_from'] = Array(hash['inherit_from'])
42
+ hash["inherit_from"] = Array(hash["inherit_from"])
42
43
  Array(config_path).reverse_each do |path|
43
44
  # Put gem configuration first so local configuration overrides it.
44
- hash['inherit_from'].unshift(gem_config_path(gem_name, path))
45
+ hash["inherit_from"].unshift(gem_config_path(gem_name, path))
45
46
  end
46
47
  end
47
48
  end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ERBLint
3
4
  class Stats
4
5
  attr_accessor :ignored,
5
- :found,
6
- :corrected,
7
- :exceptions,
8
- :linters,
9
- :files,
10
- :processed_files
6
+ :found,
7
+ :corrected,
8
+ :exceptions,
9
+ :linters,
10
+ :autocorrectable_linters,
11
+ :files,
12
+ :processed_files
11
13
 
12
14
  def initialize(
13
15
  ignored: 0,
@@ -15,6 +17,7 @@ module ERBLint
15
17
  corrected: 0,
16
18
  exceptions: 0,
17
19
  linters: 0,
20
+ autocorrectable_linters: 0,
18
21
  files: 0,
19
22
  processed_files: {}
20
23
  )
@@ -23,6 +26,7 @@ module ERBLint
23
26
  @corrected = corrected
24
27
  @exceptions = exceptions
25
28
  @linters = linters
29
+ @autocorrectable_linters = autocorrectable_linters
26
30
  @files = files
27
31
  @processed_files = processed_files
28
32
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html/ast/node'
4
- require 'better_html/test_helper/ruby_node'
3
+ require "better_html/ast/node"
4
+ require "better_html/test_helper/ruby_node"
5
5
 
6
6
  module ERBLint
7
7
  module Utils
@@ -194,6 +194,7 @@ module ERBLint
194
194
 
195
195
  def find_entry(range)
196
196
  return unless range
197
+
197
198
  @entries.find do |entry|
198
199
  entry.contains_ruby_range?(Range.new(range.begin_pos, range.end_pos))
199
200
  end
@@ -63,8 +63,8 @@ module ERBLint
63
63
  node_or_range
64
64
  else
65
65
  raise TypeError,
66
- 'Expected a Parser::Source::Range, Comment or ' \
67
- "Rubocop::AST::Node, got #{node_or_range.class}"
66
+ "Expected a Parser::Source::Range, Comment or " \
67
+ "Rubocop::AST::Node, got #{node_or_range.class}"
68
68
  end
69
69
  end
70
70
  end
@@ -9,14 +9,15 @@ module ERBLint
9
9
  def html_options_to_tag_attributes(hash_node)
10
10
  hash_node.children.map do |pair_node|
11
11
  key_node, value_node = *pair_node
12
- key = ruby_to_erb(key_node, '=') { |s| s.tr('_', '-') }
13
- value = ruby_to_erb(value_node, '=') { |s| escape_quote(s) }
14
- [key, "\"#{value}\""].join('=')
15
- end.join(' ')
12
+ key = ruby_to_erb(key_node, "=") { |s| s.tr("_", "-") }
13
+ value = ruby_to_erb(value_node, "=") { |s| escape_quote(s) }
14
+ [key, "\"#{value}\""].join("=")
15
+ end.join(" ")
16
16
  end
17
17
 
18
18
  def ruby_to_erb(node, indicator = nil, &block)
19
19
  return node if node.nil? || node.is_a?(String)
20
+
20
21
  case node.type
21
22
  when :str, :sym
22
23
  s = node.children.first.to_s
@@ -43,7 +44,7 @@ module ERBLint
43
44
  end
44
45
 
45
46
  def escape_quote(str)
46
- str.gsub('"', '&quot;')
47
+ str.gsub('"', "&quot;")
47
48
  end
48
49
  end
49
50
  end
@@ -3,10 +3,10 @@
3
3
  module ERBLint
4
4
  module Utils
5
5
  module SeverityLevels
6
- SEVERITY_NAMES = %i[info refactor convention warning error fatal].freeze
6
+ SEVERITY_NAMES = [:info, :refactor, :convention, :warning, :error, :fatal].freeze
7
7
 
8
8
  SEVERITY_CODE_TABLE = { I: :info, R: :refactor, C: :convention,
9
- W: :warning, E: :error, F: :fatal }.freeze
9
+ W: :warning, E: :error, F: :fatal, }.freeze
10
10
 
11
11
  def severity_level_for_name(name)
12
12
  SEVERITY_NAMES.index(name || :error) + 1