erb_lint 0.1.0 → 0.1.1

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/exe/erblint +1 -1
  3. data/lib/erb_lint.rb +1 -1
  4. data/lib/erb_lint/all.rb +15 -15
  5. data/lib/erb_lint/cli.rb +18 -18
  6. data/lib/erb_lint/corrector.rb +1 -1
  7. data/lib/erb_lint/linter.rb +3 -3
  8. data/lib/erb_lint/linter_config.rb +3 -3
  9. data/lib/erb_lint/linter_registry.rb +2 -2
  10. data/lib/erb_lint/linters/allowed_script_type.rb +7 -7
  11. data/lib/erb_lint/linters/closing_erb_tag_indent.rb +2 -2
  12. data/lib/erb_lint/linters/deprecated_classes.rb +7 -7
  13. data/lib/erb_lint/linters/erb_safety.rb +2 -2
  14. data/lib/erb_lint/linters/extra_newline.rb +1 -1
  15. data/lib/erb_lint/linters/final_newline.rb +2 -2
  16. data/lib/erb_lint/linters/hard_coded_string.rb +36 -36
  17. data/lib/erb_lint/linters/no_javascript_tag_helper.rb +8 -8
  18. data/lib/erb_lint/linters/require_input_autocomplete.rb +6 -8
  19. data/lib/erb_lint/linters/require_script_nonce.rb +8 -8
  20. data/lib/erb_lint/linters/right_trim.rb +1 -1
  21. data/lib/erb_lint/linters/rubocop.rb +10 -10
  22. data/lib/erb_lint/linters/rubocop_text.rb +1 -1
  23. data/lib/erb_lint/linters/self_closing_tag.rb +5 -7
  24. data/lib/erb_lint/linters/space_around_erb_tag.rb +5 -5
  25. data/lib/erb_lint/linters/space_in_html_tag.rb +6 -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/reporter.rb +2 -2
  29. data/lib/erb_lint/reporters/compact_reporter.rb +1 -1
  30. data/lib/erb_lint/reporters/multiline_reporter.rb +1 -1
  31. data/lib/erb_lint/runner.rb +1 -1
  32. data/lib/erb_lint/runner_config.rb +7 -7
  33. data/lib/erb_lint/runner_config_resolver.rb +4 -4
  34. data/lib/erb_lint/stats.rb +6 -6
  35. data/lib/erb_lint/utils/block_map.rb +2 -2
  36. data/lib/erb_lint/utils/offset_corrector.rb +1 -1
  37. data/lib/erb_lint/utils/ruby_to_erb.rb +5 -5
  38. data/lib/erb_lint/utils/severity_levels.rb +2 -2
  39. data/lib/erb_lint/version.rb +1 -1
  40. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c54cf59770c0719d8cae0376d27a685ba2159d0e8884c00a472b0217d1ca2e6
4
- data.tar.gz: c644e23a805c04e02daf4218f8548a167a90cc8d0b2bf0fd73acbbdbbaec237c
3
+ metadata.gz: b98507494f8af2a33e0e6fcbf28c48a2d91c78f42273a3cc6c1206578f3a55b0
4
+ data.tar.gz: c090a633a9d041a6d4d71bc292b1525b3a74dccd61311e0224bc1cbb0d8fea33
5
5
  SHA512:
6
- metadata.gz: '07718e5eed2bfb8246a529615c3950645c0d51e376475c6cea7eb60bedfc17af42c4f24f3aba7e8184e842087027b3c0e033afb6c1d01eceb5b84e7c0da8bb74'
7
- data.tar.gz: 6bda3b3ad2b03a0812a6bb796c0f6f2d03545fcdc44a6130dc7e3b2135d523e8decb395e3fd7599d9121045c840585de3c4ced6c9c8fb642d1865d263e978dad
6
+ metadata.gz: b2ac77d88b7be36010d69c072e3ee72c370edefa1fc3b68135593b5b494da8b0f9eac79e9b5408d10155a007d94948ae6a4b3b279de2541be66f0576abc964a8
7
+ data.tar.gz: f0be6a75c5060b49a8b7c5e5a5d19adb3222fb580a11c2e2e488e5b83ada00db0c4daee25e99ba5538057c749f5937b80d25a96bda1ed967e6d1baeddf787965
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)
data/lib/erb_lint.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb_lint/version'
3
+ require "erb_lint/version"
data/lib/erb_lint/all.rb CHANGED
@@ -1,26 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubocop'
3
+ require "rubocop"
4
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'
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
17
 
18
18
  # Load linters
19
- Dir[File.expand_path('linters/**/*.rb', __dir__)].each do |file|
19
+ Dir[File.expand_path("linters/**/*.rb", __dir__)].each do |file|
20
20
  require file
21
21
  end
22
22
 
23
23
  # Load reporters
24
- Dir[File.expand_path('reporters/**/*.rb', __dir__)].each do |file|
24
+ Dir[File.expand_path("reporters/**/*.rb", __dir__)].each do |file|
25
25
  require file
26
26
  end
data/lib/erb_lint/cli.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
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'
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"
11
11
 
12
12
  module ERBLint
13
13
  class CLI
14
14
  include Utils::SeverityLevels
15
15
 
16
- DEFAULT_CONFIG_FILENAME = '.erb-lint.yml'
16
+ DEFAULT_CONFIG_FILENAME = ".erb-lint.yml"
17
17
  DEFAULT_LINT_ALL_GLOB = "**/*.html{+*,}.erb"
18
18
 
19
19
  class ExitWithFailure < RuntimeError; end
@@ -43,7 +43,7 @@ module ERBLint
43
43
  ensure_files_exist(lint_files)
44
44
 
45
45
  if enabled_linter_classes.empty?
46
- failure!('no linter available with current configuration')
46
+ failure!("no linter available with current configuration")
47
47
  end
48
48
 
49
49
  @options[:format] ||= :multiline
@@ -145,7 +145,7 @@ module ERBLint
145
145
 
146
146
  def correct(processed_source, offenses)
147
147
  corrector = ERBLint::Corrector.new(processed_source, offenses)
148
- failure!(corrector.diagnostics.join(', ')) if corrector.diagnostics.any?
148
+ failure!(corrector.diagnostics.join(", ")) if corrector.diagnostics.any?
149
149
  corrector
150
150
  end
151
151
 
@@ -183,7 +183,7 @@ module ERBLint
183
183
  else
184
184
  @files
185
185
  .map { |f| Dir.exist?(f) ? Dir[File.join(f, glob)] : f }
186
- .map { |f| f.include?('*') ? Dir[f] : f }
186
+ .map { |f| f.include?("*") ? Dir[f] : f }
187
187
  .flatten
188
188
  .map { |f| File.expand_path(f, Dir.pwd) }
189
189
  .select { |filename| !excluded?(filename) }
@@ -240,14 +240,14 @@ module ERBLint
240
240
  end
241
241
 
242
242
  def relative_filename(filename)
243
- filename.sub("#{File.expand_path('.', Dir.pwd)}/", '')
243
+ filename.sub("#{File.expand_path(".", Dir.pwd)}/", "")
244
244
  end
245
245
 
246
246
  def runner_config_override
247
247
  RunnerConfig.new(
248
248
  linters: {}.tap do |linters|
249
249
  ERBLint::LinterRegistry.linters.map do |klass|
250
- linters[klass.simple_name] = { 'enabled' => enabled_linter_classes.include?(klass) }
250
+ linters[klass.simple_name] = { "enabled" => enabled_linter_classes.include?(klass) }
251
251
  end
252
252
  end
253
253
  )
@@ -283,10 +283,10 @@ module ERBLint
283
283
  end
284
284
 
285
285
  opts.on("--enable-linters LINTER[,LINTER,...]", Array,
286
- "Only use specified linter", "Known linters are: #{known_linter_names.join(', ')}") do |linters|
286
+ "Only use specified linter", "Known linters are: #{known_linter_names.join(", ")}") do |linters|
287
287
  linters.each do |linter|
288
288
  unless known_linter_names.include?(linter)
289
- failure!("#{linter}: not a valid linter name (#{known_linter_names.join(', ')})")
289
+ failure!("#{linter}: not a valid linter name (#{known_linter_names.join(", ")})")
290
290
  end
291
291
  end
292
292
  @options[:enabled_linters] = linters
@@ -296,7 +296,7 @@ module ERBLint
296
296
  parsed_severity = SEVERITY_CODE_TABLE[level.upcase.to_sym] || (SEVERITY_NAMES & [level.downcase]).first
297
297
 
298
298
  if parsed_severity.nil?
299
- failure!("#{level}: not a valid failure level (#{SEVERITY_NAMES.join(', ')})")
299
+ failure!("#{level}: not a valid failure level (#{SEVERITY_NAMES.join(", ")})")
300
300
  end
301
301
  @options[:fail_level] = severity_level_for_name(parsed_severity)
302
302
  end
@@ -325,7 +325,7 @@ module ERBLint
325
325
 
326
326
  def format_options_help
327
327
  "Report offenses in the given format: "\
328
- "(#{Reporter.available_formats.join(', ')}) (default: multiline)"
328
+ "(#{Reporter.available_formats.join(", ")}) (default: multiline)"
329
329
  end
330
330
 
331
331
  def invalid_format_error_message(given_format)
@@ -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
@@ -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,7 +27,7 @@ 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
  super(config)
33
33
  rescue SmartProperties::InitializationError => e
@@ -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,7 +24,7 @@ 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]
@@ -36,7 +36,7 @@ module ERBLint
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
@@ -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,9 @@ 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
+ class_value.split(" ").each do |class_name|
63
63
  yielder.yield(class_name, tag.loc)
64
64
  end
65
65
  end
@@ -69,7 +69,7 @@ module ERBLint
69
69
  def text_tags_content(processed_source)
70
70
  Enumerator.new do |yielder|
71
71
  script_tags(processed_source)
72
- .select { |tag| tag.attributes['type']&.value == 'text/html' }
72
+ .select { |tag| tag.attributes["type"]&.value == "text/html" }
73
73
  .each do |tag|
74
74
  index = processed_source.ast.to_a.find_index(tag.node)
75
75
  next_node = processed_source.ast.to_a[index + 1]
@@ -80,7 +80,7 @@ module ERBLint
80
80
  end
81
81
 
82
82
  def script_tags(processed_source)
83
- tags(processed_source).select { |tag| tag.name == 'script' }
83
+ tags(processed_source).select { |tag| tag.name == "script" }
84
84
  end
85
85
 
86
86
  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,7 @@
1
1
  # frozen_string_literal: true
2
2
  require "set"
3
- require 'better_html/tree/tag'
4
- require 'active_support/core_ext/string/inflections'
3
+ require "better_html/tree/tag"
4
+ require "active_support/core_ext/string/inflections"
5
5
 
6
6
  module ERBLint
7
7
  module Linters
@@ -13,37 +13,37 @@ module ERBLint
13
13
  MissingCorrector = Class.new(StandardError)
14
14
  MissingI18nLoadPath = Class.new(StandardError)
15
15
 
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(
23
- &nbsp;
24
- &amp;
25
- &lt;
26
- &gt;
27
- &quot;
28
- &copy;
29
- &reg;
30
- &trade;
31
- &hellip;
32
- &mdash;
33
- &bull;
34
- &ldquo;
35
- &rdquo;
36
- &lsquo;
37
- &rsquo;
38
- &larr;
39
- &rarr;
40
- &darr;
41
- &uarr;
42
- ))
16
+ ALLOWED_CORRECTORS = ["I18nCorrector", "RuboCop::Corrector::I18n::HardCodedString"]
17
+
18
+ NON_TEXT_TAGS = Set.new(["script", "style", "xmp", "iframe", "noembed", "noframes", "listing"])
19
+ TEXT_NOT_ALLOWED = Set.new([
20
+ "&nbsp;",
21
+ "&amp;",
22
+ "&lt;",
23
+ "&gt;",
24
+ "&quot;",
25
+ "&copy;",
26
+ "&reg;",
27
+ "&trade;",
28
+ "&hellip;",
29
+ "&mdash;",
30
+ "&bull;",
31
+ "&ldquo;",
32
+ "&rdquo;",
33
+ "&lsquo;",
34
+ "&rsquo;",
35
+ "&larr;",
36
+ "&rarr;",
37
+ "&darr;",
38
+ "&uarr;",
39
+ "&ensp;",
40
+ "&emsp;",
41
+ "&thinsp;",
42
+ ])
43
43
 
44
44
  class ConfigSchema < LinterConfig
45
45
  property :corrector, accepts: Hash, required: false, default: -> { {} }
46
- property :i18n_load_path, accepts: String, required: false, default: ''
46
+ property :i18n_load_path, accepts: String, required: false, default: ""
47
47
  end
48
48
  self.config_schema = ConfigSchema
49
49
 
@@ -85,7 +85,7 @@ module ERBLint
85
85
  return unless string.strip.length > 1
86
86
  node = ::RuboCop::AST::StrNode.new(:str, [string])
87
87
  corrector = klass.new(node, processed_source.filename, corrector_i18n_load_path, offense.source_range)
88
- corrector.autocorrect(tag_start: '<%= ', tag_end: ' %>')
88
+ corrector.autocorrect(tag_start: "<%= ", tag_end: " %>")
89
89
  rescue MissingCorrector, MissingI18nLoadPath
90
90
  nil
91
91
  end
@@ -93,20 +93,20 @@ module ERBLint
93
93
  private
94
94
 
95
95
  def check_string?(str)
96
- string = str.gsub(/\s*/, '')
97
- string.length > 1 && !BLACK_LISTED_TEXT.include?(string)
96
+ string = str.gsub(/\s*/, "")
97
+ string.length > 1 && !TEXT_NOT_ALLOWED.include?(string)
98
98
  end
99
99
 
100
100
  def load_corrector
101
- corrector_name = @config['corrector'].fetch('name') { raise MissingCorrector }
101
+ corrector_name = @config["corrector"].fetch("name") { raise MissingCorrector }
102
102
  raise ForbiddenCorrector unless ALLOWED_CORRECTORS.include?(corrector_name)
103
- require @config['corrector'].fetch('path') { raise MissingCorrector }
103
+ require @config["corrector"].fetch("path") { raise MissingCorrector }
104
104
 
105
105
  corrector_name.safe_constantize
106
106
  end
107
107
 
108
108
  def corrector_i18n_load_path
109
- @config['corrector'].fetch('i18n_load_path') { raise MissingI18nLoadPath }
109
+ @config["corrector"].fetch("i18n_load_path") { raise MissingI18nLoadPath }
110
110
  end
111
111
 
112
112
  def non_text_tag?(processed_source, text_node)
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'better_html'
4
- require 'better_html/ast/node'
5
- require 'better_html/test_helper/ruby_node'
6
- require 'erb_lint/utils/block_map'
7
- require 'erb_lint/utils/ruby_to_erb'
3
+ require "better_html"
4
+ require "better_html/ast/node"
5
+ require "better_html/test_helper/ruby_node"
6
+ require "erb_lint/utils/block_map"
7
+ require "erb_lint/utils/ruby_to_erb"
8
8
 
9
9
  module ERBLint
10
10
  module Linters
@@ -21,7 +21,7 @@ module ERBLint
21
21
  parser.ast.descendants(:erb).each do |erb_node|
22
22
  indicator_node, _, code_node, _ = *erb_node
23
23
  indicator = indicator_node&.loc&.source
24
- next if indicator == '#'
24
+ next if indicator == "#"
25
25
  source = code_node.loc.source
26
26
 
27
27
  ruby_node =
@@ -63,10 +63,10 @@ module ERBLint
63
63
  return unless (0..2).cover?(argument_nodes.size)
64
64
 
65
65
  script_content = unless argument_nodes.first&.type?(:hash)
66
- Utils::RubyToERB.ruby_to_erb(argument_nodes.first, '==')
66
+ Utils::RubyToERB.ruby_to_erb(argument_nodes.first, "==")
67
67
  end
68
68
  arguments = if argument_nodes.last&.type?(:hash)
69
- ' ' + Utils::RubyToERB.html_options_to_tag_attributes(argument_nodes.last)
69
+ " " + Utils::RubyToERB.html_options_to_tag_attributes(argument_nodes.last)
70
70
  end
71
71
 
72
72
  return if end_node && script_content
@@ -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)
@@ -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)
@@ -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)
@@ -79,7 +79,7 @@ module ERBLint
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)
@@ -68,13 +68,13 @@ module ERBLint
68
68
 
69
69
  def inspect_content(processed_source, erb_node)
70
70
  indicator, _, code_node, = *erb_node
71
- return if indicator&.children&.first == '#'
71
+ return if indicator&.children&.first == "#"
72
72
 
73
73
  original_source = code_node.loc.source
74
- trimmed_source = original_source.sub(BLOCK_EXPR, '').sub(SUFFIX_EXPR, '')
74
+ trimmed_source = original_source.sub(BLOCK_EXPR, "").sub(SUFFIX_EXPR, "")
75
75
  alignment_column = code_node.loc.column
76
76
  offset = code_node.loc.begin_pos - alignment_column
77
- aligned_source = "#{' ' * alignment_column}#{trimmed_source}"
77
+ aligned_source = "#{" " * alignment_column}#{trimmed_source}"
78
78
 
79
79
  source = rubocop_processed_source(aligned_source, processed_source.filename)
80
80
  return unless source.valid_syntax?
@@ -156,10 +156,10 @@ module ERBLint
156
156
  end
157
157
 
158
158
  def config_from_hash(hash)
159
- inherit_from = hash&.delete('inherit_from')
159
+ inherit_from = hash&.delete("inherit_from")
160
160
  resolve_inheritance(hash, inherit_from)
161
161
 
162
- tempfile_from('.erblint-rubocop', hash.to_yaml) do |tempfile|
162
+ tempfile_from(".erblint-rubocop", hash.to_yaml) do |tempfile|
163
163
  ::RuboCop::ConfigLoader.load_file(tempfile.path)
164
164
  end
165
165
  end
@@ -174,7 +174,7 @@ module ERBLint
174
174
  end
175
175
 
176
176
  def base_configs(inherit_from)
177
- regex = URI::DEFAULT_PARSER.make_regexp(%w(http https))
177
+ regex = URI::DEFAULT_PARSER.make_regexp(["http", "https"])
178
178
  configs = Array(inherit_from).compact.map do |base_name|
179
179
  if base_name =~ /\A#{regex}\z/
180
180
  ::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,7 +32,7 @@ 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
 
@@ -43,7 +41,7 @@ module ERBLint
43
41
  add_offense(
44
42
  end_solidus.loc,
45
43
  "Tag `#{tag.name}` is a void element, it must end with `>` and not `/>`.",
46
- ''
44
+ ""
47
45
  )
48
46
  end
49
47
  end
@@ -15,7 +15,7 @@ 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
  code = code_node.children.first
20
20
 
21
21
  start_spaces = code.match(START_SPACES)&.captures&.first || ""
@@ -23,8 +23,8 @@ module ERBLint
23
23
  add_offense(
24
24
  code_node.loc.resize(start_spaces.size),
25
25
  "Use 1 space after `<%#{indicator}#{ltrim&.loc&.source}` "\
26
- "instead of #{start_spaces.size} space#{'s' if start_spaces.size > 1}.",
27
- ' '
26
+ "instead of #{start_spaces.size} space#{"s" if start_spaces.size > 1}.",
27
+ " "
28
28
  )
29
29
  elsif start_spaces.count("\n") > 1
30
30
  lines = start_spaces.split("\n", -1)
@@ -41,8 +41,8 @@ module ERBLint
41
41
  add_offense(
42
42
  code_node.loc.end.adjust(begin_pos: -end_spaces.size),
43
43
  "Use 1 space before `#{rtrim&.loc&.source}%>` "\
44
- "instead of #{end_spaces.size} space#{'s' if start_spaces.size > 1}.",
45
- ' '
44
+ "instead of #{end_spaces.size} space#{"s" if start_spaces.size > 1}.",
45
+ " "
46
46
  )
47
47
  elsif end_spaces.count("\n") > 1
48
48
  lines = end_spaces.split("\n", -1)
@@ -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
@@ -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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/core_ext/class'
3
- require 'active_support/core_ext/module/delegation'
2
+ require "active_support/core_ext/class"
3
+ require "active_support/core_ext/module/delegation"
4
4
 
5
5
  module ERBLint
6
6
  class Reporter
@@ -5,7 +5,7 @@ module ERBLint
5
5
  class CompactReporter < Reporter
6
6
  def preview
7
7
  puts "Linting #{stats.files} files with "\
8
- "#{stats.linters} #{'autocorrectable ' if autocorrect}linters..."
8
+ "#{stats.linters} #{"autocorrectable " if autocorrect}linters..."
9
9
  end
10
10
 
11
11
  def show
@@ -9,7 +9,7 @@ module ERBLint
9
9
  def format_offense(filename, offense)
10
10
  <<~EOF
11
11
 
12
- #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect}
12
+ #{offense.message}#{Rainbow(" (not autocorrected)").red if autocorrect}
13
13
  In file: #{filename}:#{offense.line_number}
14
14
  EOF
15
15
  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,7 +24,7 @@ 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
@@ -32,7 +32,7 @@ module ERBLint
32
32
  end
33
33
 
34
34
  def global_exclude
35
- @config['exclude'] || []
35
+ @config["exclude"] || []
36
36
  end
37
37
 
38
38
  def merge(other_config)
@@ -75,13 +75,13 @@ module ERBLint
75
75
  private
76
76
 
77
77
  def linters_config
78
- @config['linters'] || {}
78
+ @config["linters"] || {}
79
79
  end
80
80
 
81
81
  def config_hash_for_linter(klass_name)
82
82
  config_hash = linters_config[klass_name] || {}
83
- config_hash['exclude'] ||= []
84
- config_hash['exclude'].concat(global_exclude) if config_hash['exclude'].is_a?(Array)
83
+ config_hash["exclude"] ||= []
84
+ config_hash["exclude"].concat(global_exclude) if config_hash["exclude"].is_a?(Array)
85
85
  config_hash
86
86
  end
87
87
 
@@ -24,7 +24,7 @@
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)
@@ -36,12 +36,12 @@ module ERBLint
36
36
 
37
37
  def resolve_inheritance_from_gems(hash, gems)
38
38
  (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'
39
+ raise(ArgumentError, "can't inherit configuration from the erb-lint gem") if gem_name == "erb-lint"
40
40
 
41
- hash['inherit_from'] = Array(hash['inherit_from'])
41
+ hash["inherit_from"] = Array(hash["inherit_from"])
42
42
  Array(config_path).reverse_each do |path|
43
43
  # Put gem configuration first so local configuration overrides it.
44
- hash['inherit_from'].unshift(gem_config_path(gem_name, path))
44
+ hash["inherit_from"].unshift(gem_config_path(gem_name, path))
45
45
  end
46
46
  end
47
47
  end
@@ -2,12 +2,12 @@
2
2
  module ERBLint
3
3
  class Stats
4
4
  attr_accessor :ignored,
5
- :found,
6
- :corrected,
7
- :exceptions,
8
- :linters,
9
- :files,
10
- :processed_files
5
+ :found,
6
+ :corrected,
7
+ :exceptions,
8
+ :linters,
9
+ :files,
10
+ :processed_files
11
11
 
12
12
  def initialize(
13
13
  ignored: 0,
@@ -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
@@ -63,7 +63,7 @@ module ERBLint
63
63
  node_or_range
64
64
  else
65
65
  raise TypeError,
66
- 'Expected a Parser::Source::Range, Comment or ' \
66
+ "Expected a Parser::Source::Range, Comment or " \
67
67
  "Rubocop::AST::Node, got #{node_or_range.class}"
68
68
  end
69
69
  end
@@ -9,10 +9,10 @@ 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)
@@ -43,7 +43,7 @@ module ERBLint
43
43
  end
44
44
 
45
45
  def escape_quote(str)
46
- str.gsub('"', '&quot;')
46
+ str.gsub('"', "&quot;")
47
47
  end
48
48
  end
49
49
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ERBLint
4
- VERSION = '0.1.0'
4
+ VERSION = "0.1.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Chan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-26 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: better_html