erb_lint 0.5.0 → 0.7.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 +4 -4
- data/exe/erb_lint +10 -0
- data/exe/erblint +5 -4
- data/lib/erb_lint/cache.rb +3 -3
- data/lib/erb_lint/cached_offense.rb +1 -1
- data/lib/erb_lint/cli.rb +24 -8
- data/lib/erb_lint/linter.rb +1 -1
- data/lib/erb_lint/linter_registry.rb +11 -1
- data/lib/erb_lint/linters/allowed_script_type.rb +8 -7
- data/lib/erb_lint/linters/closing_erb_tag_indent.rb +3 -3
- data/lib/erb_lint/linters/comment_syntax.rb +1 -1
- data/lib/erb_lint/linters/deprecated_classes.rb +2 -2
- data/lib/erb_lint/linters/erb_safety.rb +1 -1
- data/lib/erb_lint/linters/extra_newline.rb +1 -1
- data/lib/erb_lint/linters/final_newline.rb +4 -4
- data/lib/erb_lint/linters/hard_coded_string.rb +4 -2
- data/lib/erb_lint/linters/no_javascript_tag_helper.rb +6 -4
- data/lib/erb_lint/linters/no_unused_disable.rb +4 -2
- data/lib/erb_lint/linters/parser_errors.rb +1 -1
- data/lib/erb_lint/linters/partial_instance_variable.rb +2 -2
- data/lib/erb_lint/linters/require_input_autocomplete.rb +4 -4
- data/lib/erb_lint/linters/require_script_nonce.rb +2 -2
- data/lib/erb_lint/linters/right_trim.rb +1 -1
- data/lib/erb_lint/linters/rubocop.rb +4 -4
- data/lib/erb_lint/linters/rubocop_text.rb +1 -1
- data/lib/erb_lint/linters/self_closing_tag.rb +22 -5
- data/lib/erb_lint/linters/space_around_erb_tag.rb +8 -8
- data/lib/erb_lint/linters/space_in_html_tag.rb +7 -7
- data/lib/erb_lint/linters/space_indentation.rb +1 -1
- data/lib/erb_lint/linters/trailing_whitespace.rb +1 -1
- data/lib/erb_lint/offense.rb +3 -3
- data/lib/erb_lint/processed_source.rb +1 -1
- data/lib/erb_lint/reporter.rb +3 -2
- data/lib/erb_lint/reporters/compact_reporter.rb +3 -2
- data/lib/erb_lint/reporters/gitlab_reporter.rb +55 -0
- data/lib/erb_lint/reporters/junit_reporter.rb +41 -90
- data/lib/erb_lint/reporters/multiline_reporter.rb +6 -1
- data/lib/erb_lint/runner.rb +1 -1
- data/lib/erb_lint/runner_config_resolver.rb +1 -1
- data/lib/erb_lint/utils/block_map.rb +4 -4
- data/lib/erb_lint/utils/offset_corrector.rb +2 -5
- data/lib/erb_lint/utils/severity_levels.rb +8 -2
- data/lib/erb_lint/version.rb +1 -1
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed317d0bcb868320c088c8788e5b14ba9f8224aab3e6ae2e4952e34df8fdefc4
|
4
|
+
data.tar.gz: 21fe3cfccf4d30225d11fa2f397186b5274bbb8d1fe6ff5bf593ac225bb327a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d281ca485b9763dc2d7e3b3297b429c2fa08f1f043e557b7a9ad9ab65c5e0e422d5ccabbd66f40e3da43088bc1b580dd9dab5213dca39a894a7b0da82c0e113c
|
7
|
+
data.tar.gz: 9907b4b4089693f5787c96b0e5cef7b1c9bd49b6831d6e6c42757fb69911a0905b395f468fab7c0339d3b0e166b6962d1a4db772476f669d659f6380e88a90c4
|
data/exe/erb_lint
ADDED
data/exe/erblint
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
lib_path = File.expand_path("#{__dir__}/../lib")
|
5
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
5
6
|
|
6
|
-
require "
|
7
|
+
require "rainbow"
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
warn(Rainbow("Calling `erblint` is deprecated, please call the renamed executable `erb_lint` instead.").yellow)
|
10
|
+
exec(File.join(__dir__, "erb_lint"), *ARGV)
|
data/lib/erb_lint/cache.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ERBLint
|
4
4
|
class Cache
|
5
|
-
CACHE_DIRECTORY = ".
|
5
|
+
CACHE_DIRECTORY = ".erb_lint_cache"
|
6
6
|
|
7
7
|
def initialize(config, cache_dir = nil)
|
8
8
|
@config = config
|
@@ -16,7 +16,7 @@ module ERBLint
|
|
16
16
|
file_checksum = checksum(filename, file_content)
|
17
17
|
begin
|
18
18
|
cache_file_contents_as_offenses = JSON.parse(
|
19
|
-
File.read(File.join(@cache_dir, file_checksum))
|
19
|
+
File.read(File.join(@cache_dir, file_checksum)),
|
20
20
|
).map do |offense_hash|
|
21
21
|
ERBLint::CachedOffense.new(offense_hash)
|
22
22
|
end
|
@@ -76,7 +76,7 @@ module ERBLint
|
|
76
76
|
mode = File.stat(filename).mode
|
77
77
|
|
78
78
|
digester.update(
|
79
|
-
"#{mode}#{config.to_hash}#{ERBLint::VERSION}#{file_content}"
|
79
|
+
"#{mode}#{config.to_hash}#{ERBLint::VERSION}#{file_content}",
|
80
80
|
)
|
81
81
|
digester.hexdigest
|
82
82
|
rescue Errno::ENOENT
|
data/lib/erb_lint/cli.rb
CHANGED
@@ -13,7 +13,8 @@ module ERBLint
|
|
13
13
|
class CLI
|
14
14
|
include Utils::SeverityLevels
|
15
15
|
|
16
|
-
|
16
|
+
DEPRECATED_CONFIG_FILENAME = ".erb-lint.yml"
|
17
|
+
DEFAULT_CONFIG_FILENAME = ".erb_lint.yml"
|
17
18
|
DEFAULT_LINT_ALL_GLOB = "**/*.html{+*,}.erb"
|
18
19
|
|
19
20
|
class ExitWithFailure < RuntimeError; end
|
@@ -74,7 +75,7 @@ module ERBLint
|
|
74
75
|
@stats.linters = enabled_linter_classes.size
|
75
76
|
@stats.autocorrectable_linters = enabled_linter_classes.count(&:support_autocorrect?)
|
76
77
|
|
77
|
-
reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect
|
78
|
+
reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?, @options[:show_linter_names])
|
78
79
|
reporter.preview
|
79
80
|
|
80
81
|
runner = ERBLint::Runner.new(file_loader, @config, @options[:disable_inline_configs])
|
@@ -87,7 +88,7 @@ module ERBLint
|
|
87
88
|
rescue => e
|
88
89
|
@stats.exceptions += 1
|
89
90
|
puts "Exception occurred when processing: #{relative_filename(filename)}"
|
90
|
-
puts "If this file cannot be processed by
|
91
|
+
puts "If this file cannot be processed by erb_lint, " \
|
91
92
|
"you can exclude it in your configuration file."
|
92
93
|
puts e.message
|
93
94
|
puts Rainbow(e.backtrace.join("\n")).red
|
@@ -215,6 +216,13 @@ module ERBLint
|
|
215
216
|
if File.exist?(config_filename)
|
216
217
|
config = RunnerConfig.new(file_loader.yaml(config_filename), file_loader)
|
217
218
|
@config = RunnerConfig.default_for(config)
|
219
|
+
elsif File.exist?(DEPRECATED_CONFIG_FILENAME)
|
220
|
+
deprecation_message = "The config file has been renamed to `#{DEFAULT_CONFIG_FILENAME}` and " \
|
221
|
+
"`#{DEPRECATED_CONFIG_FILENAME}` is deprecated. " \
|
222
|
+
"Please rename your config file to `#{DEFAULT_CONFIG_FILENAME}`."
|
223
|
+
warn(Rainbow(deprecation_message).yellow)
|
224
|
+
config = RunnerConfig.new(file_loader.yaml(DEPRECATED_CONFIG_FILENAME), file_loader)
|
225
|
+
@config = RunnerConfig.default_for(config)
|
218
226
|
else
|
219
227
|
warn(Rainbow("#{config_filename} not found: using default config").yellow)
|
220
228
|
@config = RunnerConfig.default
|
@@ -303,7 +311,7 @@ module ERBLint
|
|
303
311
|
ERBLint::LinterRegistry.linters.map do |klass|
|
304
312
|
linters[klass.simple_name] = { "enabled" => enabled_linter_classes.include?(klass) }
|
305
313
|
end
|
306
|
-
end
|
314
|
+
end,
|
307
315
|
)
|
308
316
|
end
|
309
317
|
|
@@ -348,8 +356,12 @@ module ERBLint
|
|
348
356
|
@options[:clear_cache] = config
|
349
357
|
end
|
350
358
|
|
351
|
-
opts.on(
|
352
|
-
"
|
359
|
+
opts.on(
|
360
|
+
"--enable-linters LINTER[,LINTER,...]",
|
361
|
+
Array,
|
362
|
+
"Only use specified linter",
|
363
|
+
"Known linters are: #{known_linter_names.join(", ")}",
|
364
|
+
) do |linters|
|
353
365
|
linters.each do |linter|
|
354
366
|
unless known_linter_names.include?(linter)
|
355
367
|
failure!("#{linter}: not a valid linter name (#{known_linter_names.join(", ")})")
|
@@ -371,6 +383,10 @@ module ERBLint
|
|
371
383
|
@options[:autocorrect] = config
|
372
384
|
end
|
373
385
|
|
386
|
+
opts.on("--show-linter-names", "Show linter names") do
|
387
|
+
@options[:show_linter_names] = true
|
388
|
+
end
|
389
|
+
|
374
390
|
opts.on("--allow-no-files", "When no matching files found, exit successfully (default: false)") do |config|
|
375
391
|
@options[:allow_no_files] = config
|
376
392
|
end
|
@@ -382,7 +398,7 @@ module ERBLint
|
|
382
398
|
opts.on(
|
383
399
|
"-sFILE",
|
384
400
|
"--stdin FILE",
|
385
|
-
"Pipe source from STDIN. Takes the path to be used to check which rules to apply."
|
401
|
+
"Pipe source from STDIN. Takes the path to be used to check which rules to apply.",
|
386
402
|
) do |file|
|
387
403
|
@options[:stdin] = [file]
|
388
404
|
end
|
@@ -398,7 +414,7 @@ module ERBLint
|
|
398
414
|
end
|
399
415
|
|
400
416
|
def format_options_help
|
401
|
-
"Report offenses in the given format: "\
|
417
|
+
"Report offenses in the given format: " \
|
402
418
|
"(#{Reporter.available_formats.join(", ")}) (default: multiline)"
|
403
419
|
end
|
404
420
|
|
data/lib/erb_lint/linter.rb
CHANGED
@@ -38,7 +38,7 @@ module ERBLint
|
|
38
38
|
def initialize(file_loader, config)
|
39
39
|
@file_loader = file_loader
|
40
40
|
@config = config
|
41
|
-
raise ArgumentError, "expect `config` to be #{self.class.config_schema} instance, "\
|
41
|
+
raise ArgumentError, "expect `config` to be #{self.class.config_schema} instance, " \
|
42
42
|
"not #{config.class}" unless config.is_a?(self.class.config_schema)
|
43
43
|
@offenses = []
|
44
44
|
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module ERBLint
|
4
4
|
# Stores all linters available to the application.
|
5
5
|
module LinterRegistry
|
6
|
-
|
6
|
+
DEPRECATED_CUSTOM_LINTERS_DIR = ".erb-linters"
|
7
|
+
CUSTOM_LINTERS_DIR = ".erb_linters"
|
7
8
|
@loaded_linters = []
|
8
9
|
|
9
10
|
class << self
|
@@ -28,6 +29,15 @@ module ERBLint
|
|
28
29
|
|
29
30
|
def load_custom_linters(directory = CUSTOM_LINTERS_DIR)
|
30
31
|
ruby_files = Dir.glob(File.expand_path(File.join(directory, "**", "*.rb")))
|
32
|
+
|
33
|
+
deprecated_ruby_files = Dir.glob(File.expand_path(File.join(DEPRECATED_CUSTOM_LINTERS_DIR, "**", "*.rb")))
|
34
|
+
if deprecated_ruby_files.any?
|
35
|
+
deprecation_message = "The '#{DEPRECATED_CUSTOM_LINTERS_DIR}' directory for custom linters is deprecated. " \
|
36
|
+
"Please rename it to '#{CUSTOM_LINTERS_DIR}'"
|
37
|
+
warn(Rainbow(deprecation_message).yellow)
|
38
|
+
ruby_files.concat(deprecated_ruby_files)
|
39
|
+
end
|
40
|
+
|
31
41
|
ruby_files.each { |file| require file }
|
32
42
|
end
|
33
43
|
end
|
@@ -12,7 +12,8 @@ module ERBLint
|
|
12
12
|
include LinterRegistry
|
13
13
|
|
14
14
|
class ConfigSchema < LinterConfig
|
15
|
-
property :allowed_types,
|
15
|
+
property :allowed_types,
|
16
|
+
accepts: array_of?(String),
|
16
17
|
default: -> { ["text/javascript"] }
|
17
18
|
property :allow_blank, accepts: [true, false], default: true, reader: :allow_blank?
|
18
19
|
property :disallow_inline_scripts, accepts: [true, false], default: false, reader: :disallow_inline_scripts?
|
@@ -30,8 +31,8 @@ module ERBLint
|
|
30
31
|
name_node = tag_node.to_a[1]
|
31
32
|
add_offense(
|
32
33
|
name_node.loc,
|
33
|
-
"Avoid using inline `<script>` tags altogether. "\
|
34
|
-
"Instead, move javascript code into a static file."
|
34
|
+
"Avoid using inline `<script>` tags altogether. " \
|
35
|
+
"Instead, move javascript code into a static file.",
|
35
36
|
)
|
36
37
|
next
|
37
38
|
end
|
@@ -44,14 +45,14 @@ module ERBLint
|
|
44
45
|
add_offense(
|
45
46
|
name_node.loc,
|
46
47
|
"Missing a `type=\"text/javascript\"` attribute to `<script>` tag.",
|
47
|
-
[type_attribute]
|
48
|
+
[type_attribute],
|
48
49
|
)
|
49
50
|
elsif type_present && !@config.allowed_types.include?(type_attribute.value)
|
50
51
|
add_offense(
|
51
52
|
type_attribute.loc,
|
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
|
+
"Avoid using #{type_attribute.value.inspect} as type for `<script>` tag. " \
|
54
|
+
"Must be one of: #{@config.allowed_types.join(", ")}" \
|
55
|
+
"#{" (or no type attribute)" if @config.allow_blank?}.",
|
55
56
|
)
|
56
57
|
end
|
57
58
|
end
|
@@ -25,13 +25,13 @@ 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(
|
32
32
|
code_node.loc.end.adjust(begin_pos: -end_spaces.size),
|
33
33
|
"Insert newline before `%>` to match start of tag.",
|
34
|
-
"\n"
|
34
|
+
"\n",
|
35
35
|
)
|
36
36
|
elsif start_with_newline && end_with_newline
|
37
37
|
current_indent = end_spaces.split("\n", -1).last
|
@@ -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
|
@@ -31,7 +31,7 @@ module ERBLint
|
|
31
31
|
|
32
32
|
add_offense(
|
33
33
|
source_range,
|
34
|
-
<<~EOF.chomp
|
34
|
+
<<~EOF.chomp,
|
35
35
|
Bad ERB comment syntax. Should be #{correct_erb_tag} without a space between.
|
36
36
|
Leaving a space between ERB tags and the Ruby comment character can cause parser errors.
|
37
37
|
EOF
|
@@ -49,7 +49,7 @@ module ERBLint
|
|
49
49
|
process_nested_offenses(
|
50
50
|
source: sub_source,
|
51
51
|
offset: offset + content_node.loc.begin_pos,
|
52
|
-
parent_source: parent_source
|
52
|
+
parent_source: parent_source,
|
53
53
|
)
|
54
54
|
end
|
55
55
|
end
|
@@ -99,7 +99,7 @@ module ERBLint
|
|
99
99
|
|
100
100
|
add_offense(
|
101
101
|
range,
|
102
|
-
format(message, class_name, violated_rule[:class_expr], suggestion)
|
102
|
+
format(message, class_name, violated_rule[:class_expr], suggestion),
|
103
103
|
)
|
104
104
|
end
|
105
105
|
end
|
@@ -29,22 +29,22 @@ module ERBLint
|
|
29
29
|
add_offense(
|
30
30
|
processed_source.to_source_range(file_content.size...file_content.size),
|
31
31
|
"Missing a trailing newline at the end of the file.",
|
32
|
-
:insert
|
32
|
+
:insert,
|
33
33
|
)
|
34
34
|
else
|
35
35
|
add_offense(
|
36
36
|
processed_source.to_source_range(
|
37
|
-
(file_content.size - final_newline.size + 1)...file_content.size
|
37
|
+
(file_content.size - final_newline.size + 1)...file_content.size,
|
38
38
|
),
|
39
39
|
"Remove multiple trailing newline at the end of the file.",
|
40
|
-
:remove
|
40
|
+
:remove,
|
41
41
|
)
|
42
42
|
end
|
43
43
|
elsif !@new_lines_should_be_present && !final_newline.empty?
|
44
44
|
add_offense(
|
45
45
|
processed_source.to_source_range(match.begin(0)...match.end(0)),
|
46
46
|
"Remove #{final_newline.size} trailing newline at the end of the file.",
|
47
|
-
:remove
|
47
|
+
:remove,
|
48
48
|
)
|
49
49
|
end
|
50
50
|
end
|
@@ -41,6 +41,8 @@ module ERBLint
|
|
41
41
|
" ",
|
42
42
|
" ",
|
43
43
|
"×",
|
44
|
+
"«",
|
45
|
+
"»",
|
44
46
|
])
|
45
47
|
|
46
48
|
class ConfigSchema < LinterConfig
|
@@ -67,7 +69,7 @@ module ERBLint
|
|
67
69
|
|
68
70
|
add_offense(
|
69
71
|
source_range,
|
70
|
-
message(source_range.source)
|
72
|
+
message(source_range.source),
|
71
73
|
)
|
72
74
|
end
|
73
75
|
end
|
@@ -84,7 +86,7 @@ module ERBLint
|
|
84
86
|
def autocorrect(processed_source, offense)
|
85
87
|
string = offense.source_range.source
|
86
88
|
return unless (klass = load_corrector)
|
87
|
-
return
|
89
|
+
return if string.strip.length <= 1
|
88
90
|
|
89
91
|
node = ::RuboCop::AST::StrNode.new(:str, [string])
|
90
92
|
corrector = klass.new(node, processed_source.filename, corrector_i18n_load_path, offense.source_range)
|
@@ -38,9 +38,9 @@ module ERBLint
|
|
38
38
|
|
39
39
|
add_offense(
|
40
40
|
erb_node.loc,
|
41
|
-
"Avoid using 'javascript_tag do' as it confuses tests "\
|
41
|
+
"Avoid using 'javascript_tag do' as it confuses tests " \
|
42
42
|
"that validate html, use inline <script> instead",
|
43
|
-
[erb_node, send_node]
|
43
|
+
[erb_node, send_node],
|
44
44
|
)
|
45
45
|
end
|
46
46
|
end
|
@@ -82,8 +82,10 @@ module ERBLint
|
|
82
82
|
corrector.replace(end_node.loc, end_content)
|
83
83
|
elsif script_content
|
84
84
|
script_content = "\n//<![CDATA[\n#{script_content}\n//]]>\n" if @config.correction_style == :cdata
|
85
|
-
corrector.replace(
|
86
|
-
|
85
|
+
corrector.replace(
|
86
|
+
begin_node.loc,
|
87
|
+
"<script#{arguments}>#{script_content}</script>",
|
88
|
+
)
|
87
89
|
end
|
88
90
|
rescue Utils::RubyToERB::Error, Utils::BlockMap::ParseError
|
89
91
|
nil
|
@@ -35,8 +35,10 @@ module ERBLint
|
|
35
35
|
|
36
36
|
disabled_rules_and_line_number.each do |rule, line_numbers|
|
37
37
|
line_numbers.each do |line_number|
|
38
|
-
add_offense(
|
39
|
-
|
38
|
+
add_offense(
|
39
|
+
processed_source.source_buffer.line_range(line_number),
|
40
|
+
"Unused erblint:disable comment for #{rule}",
|
41
|
+
)
|
40
42
|
end
|
41
43
|
end
|
42
44
|
end
|
@@ -13,9 +13,9 @@ module ERBLint
|
|
13
13
|
|
14
14
|
add_offense(
|
15
15
|
processed_source.to_source_range(
|
16
|
-
processed_source.file_content =~ instance_variable_regex..processed_source.file_content.size
|
16
|
+
processed_source.file_content =~ instance_variable_regex..processed_source.file_content.size,
|
17
17
|
),
|
18
|
-
"Instance variable detected in partial."
|
18
|
+
"Instance variable detected in partial.",
|
19
19
|
)
|
20
20
|
end
|
21
21
|
end
|
@@ -62,9 +62,9 @@ module ERBLint
|
|
62
62
|
|
63
63
|
add_offense(
|
64
64
|
tag_node.to_a[1].loc,
|
65
|
-
"Input tag is missing an autocomplete attribute. If no "\
|
65
|
+
"Input tag is missing an autocomplete attribute. If no " \
|
66
66
|
"autocomplete behaviour is desired, use the value `off` or `nope`.",
|
67
|
-
[autocomplete_attribute]
|
67
|
+
[autocomplete_attribute],
|
68
68
|
)
|
69
69
|
end
|
70
70
|
end
|
@@ -96,9 +96,9 @@ module ERBLint
|
|
96
96
|
|
97
97
|
add_offense(
|
98
98
|
erb_node.loc,
|
99
|
-
"Input field helper is missing an autocomplete attribute. If no "\
|
99
|
+
"Input field helper is missing an autocomplete attribute. If no " \
|
100
100
|
"autocomplete behaviour is desired, use the value `off` or `nope`.",
|
101
|
-
[erb_node, send_node]
|
101
|
+
[erb_node, send_node],
|
102
102
|
)
|
103
103
|
end
|
104
104
|
end
|
@@ -29,7 +29,7 @@ module ERBLint
|
|
29
29
|
add_offense(
|
30
30
|
tag_node.to_a[1].loc,
|
31
31
|
"Missing a nonce attribute. Use request.content_security_policy_nonce",
|
32
|
-
[nonce_attribute]
|
32
|
+
[nonce_attribute],
|
33
33
|
)
|
34
34
|
end
|
35
35
|
end
|
@@ -67,7 +67,7 @@ module ERBLint
|
|
67
67
|
add_offense(
|
68
68
|
erb_node.loc,
|
69
69
|
"Missing a nonce attribute. Use nonce: true",
|
70
|
-
[erb_node, send_node]
|
70
|
+
[erb_node, send_node],
|
71
71
|
)
|
72
72
|
end
|
73
73
|
end
|
@@ -19,7 +19,7 @@ module ERBLint
|
|
19
19
|
|
20
20
|
add_offense(
|
21
21
|
trim_node.loc,
|
22
|
-
"Prefer #{@config.enforced_style}%> instead of #{trim_node.loc.source}%> for trimming on the right."
|
22
|
+
"Prefer #{@config.enforced_style}%> instead of #{trim_node.loc.source}%> for trimming on the right.",
|
23
23
|
)
|
24
24
|
end
|
25
25
|
end
|
@@ -134,7 +134,7 @@ module ERBLint
|
|
134
134
|
source = ::RuboCop::ProcessedSource.new(
|
135
135
|
content,
|
136
136
|
@rubocop_config.target_ruby_version,
|
137
|
-
filename
|
137
|
+
filename,
|
138
138
|
)
|
139
139
|
if ::RuboCop::Version::STRING.to_f >= 1.38
|
140
140
|
registry = RuboCop::Cop::Registry.global
|
@@ -146,15 +146,15 @@ module ERBLint
|
|
146
146
|
|
147
147
|
def cop_classes
|
148
148
|
if @only_cops.present?
|
149
|
-
selected_cops = ::RuboCop::Cop::
|
149
|
+
selected_cops = ::RuboCop::Cop::Registry.all.select { |cop| cop.match?(@only_cops) }
|
150
150
|
::RuboCop::Cop::Registry.new(selected_cops)
|
151
151
|
else
|
152
|
-
::RuboCop::Cop::Registry.new(::RuboCop::Cop::
|
152
|
+
::RuboCop::Cop::Registry.new(::RuboCop::Cop::Registry.all)
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
156
|
def build_team
|
157
|
-
::RuboCop::Cop::Team.
|
157
|
+
::RuboCop::Cop::Team.mobilize(
|
158
158
|
cop_classes,
|
159
159
|
@rubocop_config,
|
160
160
|
extra_details: true,
|
@@ -29,7 +29,7 @@ module ERBLint
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def cop_classes
|
32
|
-
selected_cops = ::RuboCop::Cop::
|
32
|
+
selected_cops = ::RuboCop::Cop::Registry.all.select { |cop| cop.match?(@only_cops) }
|
33
33
|
|
34
34
|
::RuboCop::Cop::Registry.new(selected_cops)
|
35
35
|
end
|
@@ -11,8 +11,25 @@ module ERBLint
|
|
11
11
|
end
|
12
12
|
self.config_schema = ConfigSchema
|
13
13
|
|
14
|
-
SELF_CLOSING_TAGS = [
|
15
|
-
|
14
|
+
SELF_CLOSING_TAGS = [
|
15
|
+
"area",
|
16
|
+
"base",
|
17
|
+
"br",
|
18
|
+
"col",
|
19
|
+
"command",
|
20
|
+
"embed",
|
21
|
+
"hr",
|
22
|
+
"input",
|
23
|
+
"keygen",
|
24
|
+
"link",
|
25
|
+
"menuitem",
|
26
|
+
"meta",
|
27
|
+
"param",
|
28
|
+
"source",
|
29
|
+
"track",
|
30
|
+
"wbr",
|
31
|
+
"img",
|
32
|
+
]
|
16
33
|
|
17
34
|
def run(processed_source)
|
18
35
|
processed_source.ast.descendants(:tag).each do |tag_node|
|
@@ -24,7 +41,7 @@ module ERBLint
|
|
24
41
|
add_offense(
|
25
42
|
start_solidus.loc,
|
26
43
|
"Tag `#{tag.name}` is a void element, it must not start with `</`.",
|
27
|
-
""
|
44
|
+
"",
|
28
45
|
)
|
29
46
|
end
|
30
47
|
|
@@ -32,7 +49,7 @@ module ERBLint
|
|
32
49
|
add_offense(
|
33
50
|
tag_node.loc.end.offset(-1),
|
34
51
|
"Tag `#{tag.name}` is self-closing, it must end with `/>`.",
|
35
|
-
"/"
|
52
|
+
"/",
|
36
53
|
)
|
37
54
|
end
|
38
55
|
|
@@ -42,7 +59,7 @@ module ERBLint
|
|
42
59
|
add_offense(
|
43
60
|
end_solidus.loc,
|
44
61
|
"Tag `#{tag.name}` is a void element, it must end with `>` and not `/>`.",
|
45
|
-
""
|
62
|
+
"",
|
46
63
|
)
|
47
64
|
end
|
48
65
|
end
|
@@ -23,17 +23,17 @@ module ERBLint
|
|
23
23
|
if start_spaces.size != 1 && !start_spaces.include?("\n")
|
24
24
|
add_offense(
|
25
25
|
code_node.loc.resize(start_spaces.size),
|
26
|
-
"Use 1 space after `<%#{indicator}#{ltrim&.loc&.source}` "\
|
26
|
+
"Use 1 space after `<%#{indicator}#{ltrim&.loc&.source}` " \
|
27
27
|
"instead of #{start_spaces.size} space#{"s" if start_spaces.size > 1}.",
|
28
|
-
" "
|
28
|
+
" ",
|
29
29
|
)
|
30
30
|
elsif start_spaces.count("\n") > 1
|
31
31
|
lines = start_spaces.split("\n", -1)
|
32
32
|
add_offense(
|
33
33
|
code_node.loc.resize(start_spaces.size),
|
34
|
-
"Use 1 newline after `<%#{indicator&.loc&.source}#{ltrim&.loc&.source}` "\
|
34
|
+
"Use 1 newline after `<%#{indicator&.loc&.source}#{ltrim&.loc&.source}` " \
|
35
35
|
"instead of #{start_spaces.count("\n")}.",
|
36
|
-
"#{lines.first}\n#{lines.last}"
|
36
|
+
"#{lines.first}\n#{lines.last}",
|
37
37
|
)
|
38
38
|
end
|
39
39
|
|
@@ -41,17 +41,17 @@ module ERBLint
|
|
41
41
|
if end_spaces.size != 1 && !end_spaces.include?("\n")
|
42
42
|
add_offense(
|
43
43
|
code_node.loc.end.adjust(begin_pos: -end_spaces.size),
|
44
|
-
"Use 1 space before `#{rtrim&.loc&.source}%>` "\
|
44
|
+
"Use 1 space before `#{rtrim&.loc&.source}%>` " \
|
45
45
|
"instead of #{end_spaces.size} space#{"s" if start_spaces.size > 1}.",
|
46
|
-
" "
|
46
|
+
" ",
|
47
47
|
)
|
48
48
|
elsif end_spaces.count("\n") > 1
|
49
49
|
lines = end_spaces.split("\n", -1)
|
50
50
|
add_offense(
|
51
51
|
code_node.loc.end.adjust(begin_pos: -end_spaces.size),
|
52
|
-
"Use 1 newline before `#{rtrim&.loc&.source}%>` "\
|
52
|
+
"Use 1 newline before `#{rtrim&.loc&.source}%>` " \
|
53
53
|
"instead of #{end_spaces.count("\n")}.",
|
54
|
-
"#{lines.first}\n#{lines.last}"
|
54
|
+
"#{lines.first}\n#{lines.last}",
|
55
55
|
)
|
56
56
|
end
|
57
57
|
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
|
|
@@ -69,24 +69,24 @@ module ERBLint
|
|
69
69
|
if non_space && !non_space.captures.empty?
|
70
70
|
add_offense(
|
71
71
|
processed_source.to_source_range(range),
|
72
|
-
"Non-whitespace character(s) detected: "\
|
72
|
+
"Non-whitespace character(s) detected: " \
|
73
73
|
"#{non_space.captures.map(&:inspect).join(", ")}.",
|
74
|
-
expected
|
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
|
-
expected
|
82
|
+
expected,
|
83
83
|
)
|
84
84
|
end
|
85
85
|
else
|
86
86
|
add_offense(
|
87
87
|
processed_source.to_source_range(range),
|
88
88
|
"#{chars.empty? ? "No" : "Extra"} space detected where there should be a single space.",
|
89
|
-
expected
|
89
|
+
expected,
|
90
90
|
)
|
91
91
|
end
|
92
92
|
end
|
@@ -103,7 +103,7 @@ module ERBLint
|
|
103
103
|
|
104
104
|
single_space_or_newline(
|
105
105
|
processed_source,
|
106
|
-
attribute.loc.end_pos...next_attribute.loc.begin_pos
|
106
|
+
attribute.loc.end_pos...next_attribute.loc.begin_pos,
|
107
107
|
)
|
108
108
|
end
|
109
109
|
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
|
|
data/lib/erb_lint/offense.rb
CHANGED
@@ -23,9 +23,9 @@ module ERBLint
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def inspect
|
26
|
-
"#<#{self.class.name} linter=#{linter.class.name} "\
|
27
|
-
"source_range=#{source_range.begin_pos}...#{source_range.end_pos} "\
|
28
|
-
"message=#{message}> "\
|
26
|
+
"#<#{self.class.name} linter=#{linter.class.name} " \
|
27
|
+
"source_range=#{source_range.begin_pos}...#{source_range.end_pos} " \
|
28
|
+
"message=#{message}> " \
|
29
29
|
"severity=#{severity}"
|
30
30
|
end
|
31
31
|
|
data/lib/erb_lint/reporter.rb
CHANGED
@@ -23,9 +23,10 @@ module ERBLint
|
|
23
23
|
.sort
|
24
24
|
end
|
25
25
|
|
26
|
-
def initialize(stats, autocorrect)
|
26
|
+
def initialize(stats, autocorrect, show_linter_names = false)
|
27
27
|
@stats = stats
|
28
28
|
@autocorrect = autocorrect
|
29
|
+
@show_linter_names = show_linter_names
|
29
30
|
end
|
30
31
|
|
31
32
|
def preview; end
|
@@ -34,7 +35,7 @@ module ERBLint
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
37
|
-
attr_reader :stats, :autocorrect
|
38
|
+
attr_reader :stats, :autocorrect, :show_linter_names
|
38
39
|
|
39
40
|
delegate :processed_files, to: :stats
|
40
41
|
end
|
@@ -33,8 +33,9 @@ module ERBLint
|
|
33
33
|
"#{filename}:",
|
34
34
|
"#{offense.line_number}:",
|
35
35
|
"#{offense.column}: ",
|
36
|
+
("[#{offense.simple_name}] " if show_linter_names),
|
36
37
|
offense.message.to_s,
|
37
|
-
].join
|
38
|
+
].compact.join
|
38
39
|
end
|
39
40
|
|
40
41
|
def footer; end
|
@@ -60,7 +61,7 @@ module ERBLint
|
|
60
61
|
|
61
62
|
if corrected_found_diff > 0
|
62
63
|
message = Rainbow(
|
63
|
-
"#{stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files"
|
64
|
+
"#{stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files",
|
64
65
|
).red
|
65
66
|
|
66
67
|
warn(message)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module ERBLint
|
6
|
+
module Reporters
|
7
|
+
class GitlabReporter < Reporter
|
8
|
+
def preview; end
|
9
|
+
|
10
|
+
def show
|
11
|
+
puts formatted_data
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def formatted_data
|
17
|
+
formatted_files.to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
def formatted_files
|
21
|
+
processed_files.flat_map do |filename, offenses|
|
22
|
+
formatted_offenses(filename, offenses)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def formatted_offenses(filename, offenses)
|
27
|
+
offenses.map do |offense|
|
28
|
+
format_offense(filename, offense)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def format_offense(filename, offense)
|
33
|
+
{
|
34
|
+
description: offense.message,
|
35
|
+
check_name: offense.simple_name,
|
36
|
+
fingerprint: generate_fingerprint(filename, offense),
|
37
|
+
severity: offense.severity,
|
38
|
+
location: {
|
39
|
+
path: filename,
|
40
|
+
lines: {
|
41
|
+
begin: offense.line_number,
|
42
|
+
end: offense.last_line,
|
43
|
+
},
|
44
|
+
},
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate_fingerprint(filename, offense)
|
49
|
+
Digest::MD5.hexdigest(
|
50
|
+
"#{offense.simple_name}@#{filename}:#{offense.line_number}:#{offense.last_line}",
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,111 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rexml/document"
|
4
|
-
require "rexml/formatters/pretty"
|
5
|
-
|
6
3
|
module ERBLint
|
7
4
|
module Reporters
|
8
5
|
class JunitReporter < Reporter
|
6
|
+
ESCAPE_MAP = {
|
7
|
+
'"' => """,
|
8
|
+
"'" => "'",
|
9
|
+
"<" => "<",
|
10
|
+
">" => ">",
|
11
|
+
"&" => "&",
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
PROPERTIES = [
|
15
|
+
["erb_lint_version", ERBLint::VERSION],
|
16
|
+
["ruby_engine", RUBY_ENGINE],
|
17
|
+
["ruby_version", RUBY_VERSION],
|
18
|
+
["ruby_patchlevel", RUBY_PATCHLEVEL.to_s],
|
19
|
+
["ruby_platform", RUBY_PLATFORM],
|
20
|
+
].freeze
|
21
|
+
|
9
22
|
def preview; end
|
10
23
|
|
11
24
|
def show
|
12
|
-
xml =
|
13
|
-
|
14
|
-
REXML::Formatters::Pretty.new.write(xml, formatted_xml_string)
|
15
|
-
puts formatted_xml_string.string
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
CONTEXT = {
|
21
|
-
prologue_quote: :quote,
|
22
|
-
attribute_quote: :quote,
|
23
|
-
}
|
24
|
-
|
25
|
-
def create_junit_xml
|
26
|
-
# create prologue
|
27
|
-
xml = REXML::Document.new(nil, CONTEXT)
|
28
|
-
xml << REXML::XMLDecl.new("1.0", "UTF-8")
|
29
|
-
|
30
|
-
xml.add_element(create_testsuite_element)
|
25
|
+
puts %(<?xml version="1.0" encoding="UTF-8"?>)
|
26
|
+
puts %(<testsuite name="erblint" tests="#{@stats.processed_files.size}" failures="#{@stats.found}">)
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
failures = stats.found
|
38
|
-
testsuite_element = REXML::Element.new("testsuite", nil, CONTEXT)
|
39
|
-
testsuite_element.add_attribute("name", "erblint")
|
40
|
-
testsuite_element.add_attribute("tests", tests.to_s)
|
41
|
-
testsuite_element.add_attribute("failures", failures.to_s)
|
42
|
-
|
43
|
-
testsuite_element.add_element(create_properties)
|
28
|
+
puts %( <properties>)
|
29
|
+
PROPERTIES.each do |key, value|
|
30
|
+
puts %( <property name="#{xml_escape(key)}" value="#{xml_escape(value)}"/>)
|
31
|
+
end
|
32
|
+
puts %( </properties>)
|
44
33
|
|
45
34
|
processed_files.each do |filename, offenses|
|
35
|
+
filename_escaped = xml_escape(filename)
|
46
36
|
if offenses.empty?
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
puts %( <testcase name="#{filename_escaped}" file="#{filename_escaped}"/>)
|
38
|
+
else
|
39
|
+
offenses.each do |offense|
|
40
|
+
type = offense.simple_name
|
41
|
+
message = "#{type}: #{offense.message}"
|
42
|
+
body = "#{message} at #{filename}:#{offense.line_number}:#{offense.column}"
|
43
|
+
|
44
|
+
puts %( <testcase name="#{filename_escaped}" file="#{filename_escaped}" lineno="#{offense.line_number}">)
|
45
|
+
puts %( <failure message="#{xml_escape(message)}" type="#{xml_escape(type)}">)
|
46
|
+
puts %( #{xml_escape(body)})
|
47
|
+
puts %( </failure>)
|
48
|
+
puts %( </testcase>)
|
49
|
+
end
|
56
50
|
end
|
57
51
|
end
|
58
52
|
|
59
|
-
|
53
|
+
puts %(</testsuite>)
|
60
54
|
end
|
61
55
|
|
62
|
-
|
63
|
-
properties_element = REXML::Element.new("properties", nil, CONTEXT)
|
64
|
-
|
65
|
-
[
|
66
|
-
["erb_lint_version", ERBLint::VERSION],
|
67
|
-
["ruby_engine", RUBY_ENGINE],
|
68
|
-
["ruby_version", RUBY_VERSION],
|
69
|
-
["ruby_patchlevel", RUBY_PATCHLEVEL.to_s],
|
70
|
-
["ruby_platform", RUBY_PLATFORM],
|
71
|
-
].each do |property_attribute|
|
72
|
-
properties_element.add_element(create_property(*property_attribute))
|
73
|
-
end
|
74
|
-
|
75
|
-
properties_element
|
76
|
-
end
|
77
|
-
|
78
|
-
def create_property(name, value)
|
79
|
-
property_element = REXML::Element.new("property")
|
80
|
-
property_element.add_attribute("name", name)
|
81
|
-
property_element.add_attribute("value", value)
|
82
|
-
|
83
|
-
property_element
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_testcase(filename, offense)
|
87
|
-
testcase_element = REXML::Element.new("testcase", nil, CONTEXT)
|
88
|
-
testcase_element.add_attribute("name", filename.to_s)
|
89
|
-
testcase_element.add_attribute("file", filename.to_s)
|
90
|
-
testcase_element.add_attribute("lineno", offense.line_number.to_s)
|
91
|
-
|
92
|
-
testcase_element.add_element(create_failure(filename, offense))
|
93
|
-
|
94
|
-
testcase_element
|
95
|
-
end
|
96
|
-
|
97
|
-
def create_failure(filename, offense)
|
98
|
-
message = offense.message
|
99
|
-
type = offense.simple_name
|
100
|
-
|
101
|
-
failure_element = REXML::Element.new("failure", nil, CONTEXT)
|
102
|
-
failure_element.add_attribute("message", "#{type}: #{message}")
|
103
|
-
failure_element.add_attribute("type", type.to_s)
|
104
|
-
|
105
|
-
cdata_element = REXML::CData.new("#{type}: #{message} at #{filename}:#{offense.line_number}:#{offense.column}")
|
106
|
-
failure_element.add_text(cdata_element)
|
56
|
+
private
|
107
57
|
|
108
|
-
|
58
|
+
def xml_escape(string)
|
59
|
+
string.gsub(Regexp.union(ESCAPE_MAP.keys), ESCAPE_MAP)
|
109
60
|
end
|
110
61
|
end
|
111
62
|
end
|
@@ -8,9 +8,14 @@ module ERBLint
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def format_offense(filename, offense)
|
11
|
+
details = "#{offense.message}#{Rainbow(" (not autocorrected)").red if autocorrect}"
|
12
|
+
if show_linter_names
|
13
|
+
details = "[#{offense.simple_name}] " + details
|
14
|
+
end
|
15
|
+
|
11
16
|
<<~EOF
|
12
17
|
|
13
|
-
#{
|
18
|
+
#{details}
|
14
19
|
In file: #{filename}:#{offense.line_number}
|
15
20
|
EOF
|
16
21
|
end
|
data/lib/erb_lint/runner.rb
CHANGED
@@ -57,7 +57,7 @@ module ERBLint
|
|
57
57
|
if no_unused_disable_enabled? && enable_inline_configs?
|
58
58
|
@no_unused_disable = ERBLint::Linters::NoUnusedDisable.new(
|
59
59
|
@file_loader,
|
60
|
-
@config.for_linter(ERBLint::Linters::NoUnusedDisable)
|
60
|
+
@config.for_linter(ERBLint::Linters::NoUnusedDisable),
|
61
61
|
)
|
62
62
|
@no_unused_disable.run(processed_source, @offenses)
|
63
63
|
@offenses.concat(@no_unused_disable.offenses)
|
@@ -37,7 +37,7 @@ module ERBLint
|
|
37
37
|
|
38
38
|
def resolve_inheritance_from_gems(hash, gems)
|
39
39
|
(gems || {}).each_pair do |gem_name, config_path|
|
40
|
-
raise(ArgumentError, "can't inherit configuration from the
|
40
|
+
raise(ArgumentError, "can't inherit configuration from the erb_lint gem") if gem_name == "erb_lint"
|
41
41
|
|
42
42
|
hash["inherit_from"] = Array(hash["inherit_from"])
|
43
43
|
Array(config_path).reverse_each do |path|
|
@@ -60,7 +60,7 @@ module ERBLint
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def inspect
|
63
|
-
"
|
63
|
+
"#<#{self.class.name} type=#{type.inspect} nodes=#{nodes.inspect}>"
|
64
64
|
end
|
65
65
|
|
66
66
|
def &(other)
|
@@ -102,7 +102,7 @@ module ERBLint
|
|
102
102
|
node.type,
|
103
103
|
extract_map_locations(node)
|
104
104
|
.map { |loc| find_entry(loc) }
|
105
|
-
.compact.map(&:node)
|
105
|
+
.compact.map(&:node),
|
106
106
|
)
|
107
107
|
end
|
108
108
|
|
@@ -111,7 +111,7 @@ module ERBLint
|
|
111
111
|
:begin,
|
112
112
|
(extract_map_locations(node) + rescue_locations(node))
|
113
113
|
.map { |loc| find_entry(loc) }
|
114
|
-
.compact.map(&:node)
|
114
|
+
.compact.map(&:node),
|
115
115
|
)
|
116
116
|
end
|
117
117
|
|
@@ -120,7 +120,7 @@ module ERBLint
|
|
120
120
|
node.type,
|
121
121
|
(extract_map_locations(node) + when_locations(node))
|
122
122
|
.map { |loc| find_entry(loc) }
|
123
|
-
.compact.map(&:node)
|
123
|
+
.compact.map(&:node),
|
124
124
|
)
|
125
125
|
end
|
126
126
|
|
@@ -42,15 +42,12 @@ module ERBLint
|
|
42
42
|
range = to_range(node_or_range)
|
43
43
|
|
44
44
|
@processed_source.to_source_range(
|
45
|
-
bound(@offset + range.begin_pos)..bound(@offset + (range.end_pos - 1))
|
45
|
+
bound(@offset + range.begin_pos)..bound(@offset + (range.end_pos - 1)),
|
46
46
|
)
|
47
47
|
end
|
48
48
|
|
49
49
|
def bound(pos)
|
50
|
-
|
51
|
-
[pos, @bound_range.min].max,
|
52
|
-
@bound_range.max,
|
53
|
-
].min
|
50
|
+
pos.clamp(@bound_range.min, @bound_range.max)
|
54
51
|
end
|
55
52
|
|
56
53
|
private
|
@@ -5,8 +5,14 @@ module ERBLint
|
|
5
5
|
module SeverityLevels
|
6
6
|
SEVERITY_NAMES = [:info, :refactor, :convention, :warning, :error, :fatal].freeze
|
7
7
|
|
8
|
-
SEVERITY_CODE_TABLE = {
|
9
|
-
|
8
|
+
SEVERITY_CODE_TABLE = {
|
9
|
+
I: :info,
|
10
|
+
R: :refactor,
|
11
|
+
C: :convention,
|
12
|
+
W: :warning,
|
13
|
+
E: :error,
|
14
|
+
F: :fatal,
|
15
|
+
}.freeze
|
10
16
|
|
11
17
|
def severity_level_for_name(name)
|
12
18
|
SEVERITY_NAMES.index(name || :error) + 1
|
data/lib/erb_lint/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erb_lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Chan
|
8
8
|
- Shopify Developers
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -73,14 +73,14 @@ dependencies:
|
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
76
|
+
version: '1'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
83
|
+
version: '1'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: smart_properties
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,10 +141,12 @@ description: ERB Linter tool.
|
|
141
141
|
email:
|
142
142
|
- ruby@shopify.com
|
143
143
|
executables:
|
144
|
+
- erb_lint
|
144
145
|
- erblint
|
145
146
|
extensions: []
|
146
147
|
extra_rdoc_files: []
|
147
148
|
files:
|
149
|
+
- exe/erb_lint
|
148
150
|
- exe/erblint
|
149
151
|
- lib/erb_lint.rb
|
150
152
|
- lib/erb_lint/all.rb
|
@@ -182,6 +184,7 @@ files:
|
|
182
184
|
- lib/erb_lint/processed_source.rb
|
183
185
|
- lib/erb_lint/reporter.rb
|
184
186
|
- lib/erb_lint/reporters/compact_reporter.rb
|
187
|
+
- lib/erb_lint/reporters/gitlab_reporter.rb
|
185
188
|
- lib/erb_lint/reporters/json_reporter.rb
|
186
189
|
- lib/erb_lint/reporters/junit_reporter.rb
|
187
190
|
- lib/erb_lint/reporters/multiline_reporter.rb
|
@@ -195,12 +198,12 @@ files:
|
|
195
198
|
- lib/erb_lint/utils/ruby_to_erb.rb
|
196
199
|
- lib/erb_lint/utils/severity_levels.rb
|
197
200
|
- lib/erb_lint/version.rb
|
198
|
-
homepage: https://github.com/Shopify/
|
201
|
+
homepage: https://github.com/Shopify/erb_lint
|
199
202
|
licenses:
|
200
203
|
- MIT
|
201
204
|
metadata:
|
202
205
|
allowed_push_host: https://rubygems.org
|
203
|
-
post_install_message:
|
206
|
+
post_install_message:
|
204
207
|
rdoc_options: []
|
205
208
|
require_paths:
|
206
209
|
- lib
|
@@ -215,8 +218,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
218
|
- !ruby/object:Gem::Version
|
216
219
|
version: '0'
|
217
220
|
requirements: []
|
218
|
-
rubygems_version: 3.
|
219
|
-
signing_key:
|
221
|
+
rubygems_version: 3.5.21
|
222
|
+
signing_key:
|
220
223
|
specification_version: 4
|
221
224
|
summary: ERB lint tool
|
222
225
|
test_files: []
|