erb_lint 0.0.31 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 421010e9ed7767b1702afd3360fc90e3461ba2955a06d9757aa7377943b26d7e
4
- data.tar.gz: a8d4558c8407297f5470a7f50aae478f295b370a2af76f86118b24637a417de2
3
+ metadata.gz: 63f417288a7c49d68dcd0a04bbf07d4c8fc31c424cec244ddebab39ed3e5fab4
4
+ data.tar.gz: 22649a4264e1c570fe4a39e4112ea402d5ae04da3aaf7c35d3ce685c6fff7e21
5
5
  SHA512:
6
- metadata.gz: c00c0b52e0da4421ad79a52981a47a7dc7c1d289ab7ecd2757a201dac54ed75ff09a4f1ec009e8c7c242635eb5f8231059e147bf4d7e62c46518f07ccff7c08a
7
- data.tar.gz: 4ec4bf36b000df7e2118f147e02507fa82a9a033c5bb656f35719616ed023ac89eec9e5b26ffa1a67ae642cde47d061e0e657ae9237afd0a520ed0b799364786
6
+ metadata.gz: c0c1a2bdef25b71c750708c661aea9504551f3bcc53e7ed2017056f15d2789be58e4f758fe3735885ff4da6d43c0501f99542ce764737a8c072c24f228239155
7
+ data.tar.gz: 0653d4ec366580de6a08aff33263e9415f96ecb4bc9e579db20979f8ffb0d238cc6db9e361877ca529eef2fdf45c98233ec1ddf39cb4c01d6560a2e30fa6b489
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rubocop'
4
+
3
5
  require 'erb_lint/corrector'
4
6
  require 'erb_lint/file_loader'
5
7
  require 'erb_lint/linter_config'
@@ -10,8 +12,15 @@ require 'erb_lint/processed_source'
10
12
  require 'erb_lint/runner_config'
11
13
  require 'erb_lint/runner'
12
14
  require 'erb_lint/version'
15
+ require 'erb_lint/stats'
16
+ require 'erb_lint/reporter'
13
17
 
14
18
  # Load linters
15
19
  Dir[File.expand_path('erb_lint/linters/**/*.rb', File.dirname(__FILE__))].each do |file|
16
20
  require file
17
21
  end
22
+
23
+ # Load reporters
24
+ Dir[File.expand_path('erb_lint/reporters/**/*.rb', File.dirname(__FILE__))].each do |file|
25
+ require file
26
+ end
@@ -14,16 +14,8 @@ module ERBLint
14
14
  DEFAULT_LINT_ALL_GLOB = "**/*.html{+*,}.erb"
15
15
 
16
16
  class ExitWithFailure < RuntimeError; end
17
- class ExitWithSuccess < RuntimeError; end
18
17
 
19
- class Stats
20
- attr_accessor :found, :corrected, :exceptions
21
- def initialize
22
- @found = 0
23
- @corrected = 0
24
- @exceptions = 0
25
- end
26
- end
18
+ class ExitWithSuccess < RuntimeError; end
27
19
 
28
20
  def initialize
29
21
  @options = {}
@@ -33,8 +25,9 @@ module ERBLint
33
25
  end
34
26
 
35
27
  def run(args = ARGV)
36
- load_options(args)
37
- @files = args.dup
28
+ dupped_args = args.dup
29
+ load_options(dupped_args)
30
+ @files = dupped_args
38
31
 
39
32
  load_config
40
33
 
@@ -50,9 +43,12 @@ module ERBLint
50
43
  failure!('no linter available with current configuration')
51
44
  end
52
45
 
53
- puts "Linting #{lint_files.size} files with "\
54
- "#{enabled_linter_classes.size} #{'autocorrectable ' if autocorrect?}linters..."
55
- puts
46
+ @options[:format] ||= :multiline
47
+ @stats.files = lint_files.size
48
+ @stats.linters = enabled_linter_classes.size
49
+
50
+ reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?)
51
+ reporter.preview
56
52
 
57
53
  runner = ERBLint::Runner.new(file_loader, @config)
58
54
 
@@ -71,20 +67,7 @@ module ERBLint
71
67
  end
72
68
  end
73
69
 
74
- if @stats.corrected > 0
75
- corrected_found_diff = @stats.found - @stats.corrected
76
- if corrected_found_diff > 0
77
- warn(Rainbow(
78
- "#{@stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files"
79
- ).red)
80
- else
81
- puts Rainbow("#{@stats.corrected} error(s) corrected in ERB files").green
82
- end
83
- elsif @stats.found > 0
84
- warn(Rainbow("#{@stats.found} error(s) were found in ERB files").red)
85
- else
86
- puts Rainbow("No errors were found in ERB files").green
87
- end
70
+ reporter.show
88
71
 
89
72
  @stats.found == 0 && @stats.exceptions == 0
90
73
  rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, ExitWithFailure => e
@@ -125,15 +108,12 @@ module ERBLint
125
108
  file_content = corrector.corrected_content
126
109
  runner.clear_offenses
127
110
  end
111
+ offenses_filename = relative_filename(filename)
112
+ offenses = runner.offenses || []
128
113
 
129
- @stats.found += runner.offenses.size
130
- runner.offenses.each do |offense|
131
- puts <<~EOF
132
- #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect?}
133
- In file: #{relative_filename(filename)}:#{offense.line_range.begin}
134
-
135
- EOF
136
- end
114
+ @stats.found += offenses.size
115
+ @stats.processed_files[offenses_filename] ||= []
116
+ @stats.processed_files[offenses_filename] |= offenses
137
117
  end
138
118
 
139
119
  def correct(processed_source, offenses)
@@ -149,14 +129,15 @@ module ERBLint
149
129
  def load_config
150
130
  if File.exist?(config_filename)
151
131
  config = RunnerConfig.new(file_loader.yaml(config_filename), file_loader)
152
- @config = RunnerConfig.default.merge(config)
132
+ @config = RunnerConfig.default_for(config)
153
133
  else
154
134
  warn(Rainbow("#{config_filename} not found: using default config").yellow)
155
135
  @config = RunnerConfig.default
156
136
  end
157
- @config.merge!(runner_config_override)
158
137
  rescue Psych::SyntaxError => e
159
138
  failure!("error parsing config: #{e.message}")
139
+ ensure
140
+ @config.merge!(runner_config_override)
160
141
  end
161
142
 
162
143
  def file_loader
@@ -170,11 +151,11 @@ module ERBLint
170
151
  def lint_files
171
152
  @lint_files ||=
172
153
  if @options[:lint_all]
173
- pattern = File.expand_path(DEFAULT_LINT_ALL_GLOB, Dir.pwd)
154
+ pattern = File.expand_path(glob, Dir.pwd)
174
155
  Dir[pattern].select { |filename| !excluded?(filename) }
175
156
  else
176
157
  @files
177
- .map { |f| Dir.exist?(f) ? Dir[File.join(f, DEFAULT_LINT_ALL_GLOB)] : f }
158
+ .map { |f| Dir.exist?(f) ? Dir[File.join(f, glob)] : f }
178
159
  .map { |f| f.include?('*') ? Dir[f] : f }
179
160
  .flatten
180
161
  .map { |f| File.expand_path(f, Dir.pwd) }
@@ -182,6 +163,10 @@ module ERBLint
182
163
  end
183
164
  end
184
165
 
166
+ def glob
167
+ @config.to_hash["glob"] || DEFAULT_LINT_ALL_GLOB
168
+ end
169
+
185
170
  def excluded?(filename)
186
171
  @config.global_exclude.any? do |path|
187
172
  File.fnmatch?(path, filename)
@@ -252,7 +237,16 @@ module ERBLint
252
237
  end
253
238
  end
254
239
 
255
- opts.on("--lint-all", "Lint all files matching #{DEFAULT_LINT_ALL_GLOB}") do |config|
240
+ opts.on("--format FORMAT", format_options_help) do |format|
241
+ unless Reporter.available_format?(format)
242
+ error_message = invalid_format_error_message(format)
243
+ failure!(error_message)
244
+ end
245
+
246
+ @options[:format] = format
247
+ end
248
+
249
+ opts.on("--lint-all", "Lint all files matching configured glob [default: #{DEFAULT_LINT_ALL_GLOB}]") do |config|
256
250
  @options[:lint_all] = config
257
251
  end
258
252
 
@@ -283,5 +277,15 @@ module ERBLint
283
277
  end
284
278
  end
285
279
  end
280
+
281
+ def format_options_help
282
+ "Report offenses in the given format: "\
283
+ "(#{Reporter.available_formats.join(', ')}) (default: multiline)"
284
+ end
285
+
286
+ def invalid_format_error_message(given_format)
287
+ formats = Reporter.available_formats.map { |format| " - #{format}\n" }
288
+ "#{given_format}: is not a valid format. Available formats:\n#{formats.join}"
289
+ end
286
290
  end
287
291
  end
@@ -17,11 +17,22 @@ module ERBLint
17
17
  end
18
18
 
19
19
  def corrector
20
- RuboCop::Cop::Corrector.new(@processed_source.source_buffer, corrections)
20
+ BASE.new(@processed_source.source_buffer, corrections)
21
21
  end
22
22
 
23
- def diagnostics
24
- corrector.diagnostics
23
+ if ::RuboCop::Version::STRING.to_f >= 0.87
24
+ require 'rubocop/cop/legacy/corrector'
25
+ BASE = ::RuboCop::Cop::Legacy::Corrector
26
+
27
+ def diagnostics
28
+ []
29
+ end
30
+ else
31
+ BASE = ::RuboCop::Cop::Corrector
32
+
33
+ def diagnostics
34
+ corrector.diagnostics
35
+ end
25
36
  end
26
37
  end
27
38
  end
@@ -9,8 +9,14 @@ module ERBLint
9
9
  @base_path = base_path
10
10
  end
11
11
 
12
- def yaml(filename)
13
- YAML.safe_load(read_content(filename), [Regexp, Symbol], [], false, filename) || {}
12
+ if RUBY_VERSION >= "2.6"
13
+ def yaml(filename)
14
+ YAML.safe_load(read_content(filename), permitted_classes: [Regexp, Symbol], filename: filename) || {}
15
+ end
16
+ else
17
+ def yaml(filename)
18
+ YAML.safe_load(read_content(filename), [Regexp, Symbol], [], false, filename) || {}
19
+ end
14
20
  end
15
21
 
16
22
  private
@@ -14,6 +14,7 @@ module ERBLint
14
14
  # `ERBLint::Linters::Foo.simple_name` #=> "Foo"
15
15
  # `ERBLint::Linters::Compass::Bar.simple_name` #=> "Compass::Bar"
16
16
  def inherited(linter)
17
+ super
17
18
  linter.simple_name = if linter.name.start_with?('ERBLint::Linters::')
18
19
  name_parts = linter.name.split('::')
19
20
  name_parts[2..-1].join('::')
@@ -4,19 +4,28 @@ module ERBLint
4
4
  # Stores all linters available to the application.
5
5
  module LinterRegistry
6
6
  CUSTOM_LINTERS_DIR = '.erb-linters'
7
- @linters = []
7
+ @loaded_linters = []
8
8
 
9
9
  class << self
10
- attr_reader :linters
10
+ def clear
11
+ @linters = nil
12
+ end
11
13
 
12
14
  def included(linter_class)
13
- @linters << linter_class
15
+ @loaded_linters << linter_class
14
16
  end
15
17
 
16
18
  def find_by_name(name)
17
19
  linters.detect { |linter| linter.simple_name == name }
18
20
  end
19
21
 
22
+ def linters
23
+ @linters ||= begin
24
+ load_custom_linters
25
+ @loaded_linters
26
+ end
27
+ end
28
+
20
29
  def load_custom_linters(directory = CUSTOM_LINTERS_DIR)
21
30
  ruby_files = Dir.glob(File.expand_path(File.join(directory, '**', '*.rb')))
22
31
  ruby_files.each { |file| require file }
@@ -63,7 +63,7 @@ module ERBLint
63
63
  string = offense.source_range.source
64
64
  return unless (klass = load_corrector)
65
65
  return unless string.strip.length > 1
66
- node = RuboCop::AST::StrNode.new(:str, [string])
66
+ node = ::RuboCop::AST::StrNode.new(:str, [string])
67
67
  corrector = klass.new(node, processed_source.filename, corrector_i18n_load_path, offense.source_range)
68
68
  corrector.autocorrect(tag_start: '<%= ', tag_end: ' %>')
69
69
  rescue MissingCorrector, MissingI18nLoadPath
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'better_html'
3
4
  require 'better_html/ast/node'
4
5
  require 'better_html/test_helper/ruby_node'
5
6
  require 'erb_lint/utils/block_map'
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'better_html'
4
- require 'rubocop'
5
4
  require 'tempfile'
6
5
  require 'erb_lint/utils/offset_corrector'
7
6
 
@@ -26,7 +25,7 @@ module ERBLint
26
25
  super
27
26
  @only_cops = @config.only
28
27
  custom_config = config_from_hash(@config.rubocop_config)
29
- @rubocop_config = RuboCop::ConfigLoader.merge_with_default(custom_config, '')
28
+ @rubocop_config = ::RuboCop::ConfigLoader.merge_with_default(custom_config, '')
30
29
  end
31
30
 
32
31
  def run(processed_source)
@@ -35,17 +34,29 @@ module ERBLint
35
34
  end
36
35
  end
37
36
 
38
- def autocorrect(processed_source, offense)
39
- return unless offense.context
40
-
41
- lambda do |corrector|
42
- passthrough = Utils::OffsetCorrector.new(
43
- processed_source,
44
- corrector,
45
- offense.context[:offset],
46
- offense.context[:bound_range],
47
- )
48
- offense.context[:rubocop_correction].call(passthrough)
37
+ if ::RuboCop::Version::STRING.to_f >= 0.87
38
+ def autocorrect(_processed_source, offense)
39
+ return unless offense.context
40
+ rubocop_correction = offense.context[:rubocop_correction]
41
+ return unless rubocop_correction
42
+
43
+ lambda do |corrector|
44
+ corrector.import!(rubocop_correction, offset: offense.context[:offset])
45
+ end
46
+ end
47
+ else
48
+ def autocorrect(processed_source, offense)
49
+ return unless offense.context
50
+
51
+ lambda do |corrector|
52
+ passthrough = Utils::OffsetCorrector.new(
53
+ processed_source,
54
+ corrector,
55
+ offense.context[:offset],
56
+ offense.context[:bound_range],
57
+ )
58
+ offense.context[:rubocop_correction].call(passthrough)
59
+ end
49
60
  end
50
61
  end
51
62
 
@@ -62,22 +73,23 @@ module ERBLint
62
73
  original_source = code_node.loc.source
63
74
  trimmed_source = original_source.sub(BLOCK_EXPR, '').sub(SUFFIX_EXPR, '')
64
75
  alignment_column = code_node.loc.column
76
+ offset = code_node.loc.begin_pos - alignment_column
65
77
  aligned_source = "#{' ' * alignment_column}#{trimmed_source}"
66
78
 
67
79
  source = rubocop_processed_source(aligned_source, processed_source.filename)
68
80
  return unless source.valid_syntax?
69
81
 
70
- team = build_team
71
- team.inspect_file(source)
72
- team.cops.each do |cop|
73
- correction_offset = 0
74
- cop.offenses.reject(&:disabled?).each do |rubocop_offense|
75
- if rubocop_offense.corrected?
76
- correction = cop.corrections[correction_offset]
77
- correction_offset += 1
78
- end
82
+ activate_team(processed_source, source, offset, code_node, build_team)
83
+ end
84
+
85
+ if ::RuboCop::Version::STRING.to_f >= 0.87
86
+ def activate_team(processed_source, source, offset, code_node, team)
87
+ report = team.investigate(source)
88
+ report.offenses.each do |rubocop_offense|
89
+ next if rubocop_offense.disabled?
90
+
91
+ correction = rubocop_offense.corrector if rubocop_offense.corrected?
79
92
 
80
- offset = code_node.loc.begin_pos - alignment_column
81
93
  offense_range = processed_source
82
94
  .to_source_range(rubocop_offense.location)
83
95
  .offset(offset)
@@ -85,6 +97,25 @@ module ERBLint
85
97
  add_offense(rubocop_offense, offense_range, correction, offset, code_node.loc.range)
86
98
  end
87
99
  end
100
+ else
101
+ def activate_team(processed_source, source, offset, code_node, team)
102
+ team.inspect_file(source)
103
+ team.cops.each do |cop|
104
+ correction_offset = 0
105
+ cop.offenses.reject(&:disabled?).each do |rubocop_offense|
106
+ if rubocop_offense.corrected?
107
+ correction = cop.corrections[correction_offset]
108
+ correction_offset += 1
109
+ end
110
+
111
+ offense_range = processed_source
112
+ .to_source_range(rubocop_offense.location)
113
+ .offset(offset)
114
+
115
+ add_offense(rubocop_offense, offense_range, correction, offset, code_node.loc.range)
116
+ end
117
+ end
118
+ end
88
119
  end
89
120
 
90
121
  def tempfile_from(filename, content)
@@ -97,7 +128,7 @@ module ERBLint
97
128
  end
98
129
 
99
130
  def rubocop_processed_source(content, filename)
100
- RuboCop::ProcessedSource.new(
131
+ ::RuboCop::ProcessedSource.new(
101
132
  content,
102
133
  @rubocop_config.target_ruby_version,
103
134
  filename
@@ -106,15 +137,15 @@ module ERBLint
106
137
 
107
138
  def cop_classes
108
139
  if @only_cops.present?
109
- selected_cops = RuboCop::Cop::Cop.all.select { |cop| cop.match?(@only_cops) }
110
- RuboCop::Cop::Registry.new(selected_cops)
140
+ selected_cops = ::RuboCop::Cop::Cop.all.select { |cop| cop.match?(@only_cops) }
141
+ ::RuboCop::Cop::Registry.new(selected_cops)
111
142
  else
112
- RuboCop::Cop::Registry.new(RuboCop::Cop::Cop.all)
143
+ ::RuboCop::Cop::Registry.new(::RuboCop::Cop::Cop.all)
113
144
  end
114
145
  end
115
146
 
116
147
  def build_team
117
- RuboCop::Cop::Team.new(
148
+ ::RuboCop::Cop::Team.new(
118
149
  cop_classes,
119
150
  @rubocop_config,
120
151
  extra_details: true,
@@ -129,7 +160,7 @@ module ERBLint
129
160
  resolve_inheritance(hash, inherit_from)
130
161
 
131
162
  tempfile_from('.erblint-rubocop', hash.to_yaml) do |tempfile|
132
- RuboCop::ConfigLoader.load_file(tempfile.path)
163
+ ::RuboCop::ConfigLoader.load_file(tempfile.path)
133
164
  end
134
165
  end
135
166
 
@@ -137,7 +168,7 @@ module ERBLint
137
168
  base_configs(inherit_from)
138
169
  .reverse_each do |base_config|
139
170
  base_config.each do |k, v|
140
- hash[k] = hash.key?(k) ? RuboCop::ConfigLoader.merge(v, hash[k]) : v if v.is_a?(Hash)
171
+ hash[k] = hash.key?(k) ? ::RuboCop::ConfigLoader.merge(v, hash[k]) : v if v.is_a?(Hash)
141
172
  end
142
173
  end
143
174
  end
@@ -146,7 +177,7 @@ module ERBLint
146
177
  regex = URI::DEFAULT_PARSER.make_regexp(%w(http https))
147
178
  configs = Array(inherit_from).compact.map do |base_name|
148
179
  if base_name =~ /\A#{regex}\z/
149
- RuboCop::ConfigLoader.load_file(RuboCop::RemoteConfig.new(base_name, Dir.pwd))
180
+ ::RuboCop::ConfigLoader.load_file(::RuboCop::RemoteConfig.new(base_name, Dir.pwd))
150
181
  else
151
182
  config_from_hash(@file_loader.yaml(base_name))
152
183
  end
@@ -28,9 +28,9 @@ module ERBLint
28
28
  end
29
29
 
30
30
  def cop_classes
31
- selected_cops = RuboCop::Cop::Cop.all.select { |cop| cop.match?(@only_cops) }
31
+ selected_cops = ::RuboCop::Cop::Cop.all.select { |cop| cop.match?(@only_cops) }
32
32
 
33
- RuboCop::Cop::Registry.new(selected_cops)
33
+ ::RuboCop::Cop::Registry.new(selected_cops)
34
34
  end
35
35
  end
36
36
  end
@@ -31,5 +31,13 @@ module ERBLint
31
31
  def line_range
32
32
  Range.new(source_range.line, source_range.last_line)
33
33
  end
34
+
35
+ def line_number
36
+ line_range.begin
37
+ end
38
+
39
+ def column
40
+ source_range.column
41
+ end
34
42
  end
35
43
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require 'active_support/core_ext/class'
3
+
4
+ module ERBLint
5
+ class Reporter
6
+ def self.create_reporter(format, *args)
7
+ reporter_klass = "#{ERBLint::Reporters}::#{format.to_s.camelize}Reporter".constantize
8
+ reporter_klass.new(*args)
9
+ end
10
+
11
+ def self.available_format?(format)
12
+ available_formats.include?(format.to_s)
13
+ end
14
+
15
+ def self.available_formats
16
+ descendants
17
+ .map(&:to_s)
18
+ .map(&:demodulize)
19
+ .map(&:underscore)
20
+ .map { |klass_name| klass_name.sub("_reporter", "") }
21
+ .sort
22
+ end
23
+
24
+ def initialize(stats, autocorrect)
25
+ @stats = stats
26
+ @autocorrect = autocorrect
27
+ end
28
+
29
+ def preview; end
30
+
31
+ def show; end
32
+
33
+ private
34
+
35
+ attr_reader :stats, :autocorrect
36
+ delegate :processed_files, to: :stats
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ERBLint
4
+ module Reporters
5
+ class CompactReporter < Reporter
6
+ def preview
7
+ puts "Linting #{stats.files} files with "\
8
+ "#{stats.linters} #{'autocorrectable ' if autocorrect}linters..."
9
+ end
10
+
11
+ def show
12
+ processed_files.each do |filename, offenses|
13
+ offenses.each do |offense|
14
+ puts format_offense(filename, offense)
15
+ end
16
+ end
17
+
18
+ footer
19
+ summary
20
+ end
21
+
22
+ private
23
+
24
+ def format_offense(filename, offense)
25
+ [
26
+ "#{filename}:",
27
+ "#{offense.line_number}:",
28
+ "#{offense.column}: ",
29
+ offense.message.to_s,
30
+ ].join
31
+ end
32
+
33
+ def footer; end
34
+
35
+ def summary
36
+ if stats.corrected > 0
37
+ report_corrected_offenses
38
+ elsif stats.found > 0
39
+ warn(Rainbow("#{stats.found} error(s) were found in ERB files").red)
40
+ else
41
+ puts Rainbow("No errors were found in ERB files").green
42
+ end
43
+ end
44
+
45
+ def report_corrected_offenses
46
+ corrected_found_diff = stats.found - stats.corrected
47
+
48
+ if corrected_found_diff > 0
49
+ message = Rainbow(
50
+ "#{stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files"
51
+ ).red
52
+
53
+ warn(message)
54
+ else
55
+ puts Rainbow("#{stats.corrected} error(s) corrected in ERB files").green
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require_relative "compact_reporter"
3
+
4
+ module ERBLint
5
+ module Reporters
6
+ class MultilineReporter < CompactReporter
7
+ private
8
+
9
+ def format_offense(filename, offense)
10
+ <<~EOF
11
+
12
+ #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect}
13
+ In file: #{filename}:#{offense.line_number}
14
+ EOF
15
+ end
16
+
17
+ def footer
18
+ puts
19
+ end
20
+ end
21
+ end
22
+ end
@@ -10,7 +10,6 @@ module ERBLint
10
10
  @config = config || RunnerConfig.default
11
11
  raise ArgumentError, 'expect `config` to be a RunnerConfig instance' unless @config.is_a?(RunnerConfig)
12
12
 
13
- LinterRegistry.load_custom_linters
14
13
  linter_classes = LinterRegistry.linters.select { |klass| @config.for_linter(klass).enabled? }
15
14
  @linters = linter_classes.map do |linter_class|
16
15
  linter_class.new(@file_loader, @config.for_linter(linter_class))
@@ -45,24 +45,30 @@ module ERBLint
45
45
  end
46
46
 
47
47
  class << self
48
- def default
48
+ def default(default_enabled: nil)
49
+ default_enabled = default_enabled.nil? ? true : default_enabled
49
50
  new(
50
51
  linters: {
51
- AllowedScriptType: { enabled: true },
52
- ClosingErbTagIndent: { enabled: true },
53
- ExtraNewline: { enabled: true },
54
- FinalNewline: { enabled: true },
55
- NoJavascriptTagHelper: { enabled: true },
56
- ParserErrors: { enabled: true },
57
- RightTrim: { enabled: true },
58
- SelfClosingTag: { enabled: true },
59
- SpaceAroundErbTag: { enabled: true },
60
- SpaceIndentation: { enabled: true },
61
- SpaceInHtmlTag: { enabled: true },
62
- TrailingWhitespace: { enabled: true },
52
+ AllowedScriptType: { enabled: default_enabled },
53
+ ClosingErbTagIndent: { enabled: default_enabled },
54
+ ExtraNewline: { enabled: default_enabled },
55
+ FinalNewline: { enabled: default_enabled },
56
+ NoJavascriptTagHelper: { enabled: default_enabled },
57
+ ParserErrors: { enabled: default_enabled },
58
+ RightTrim: { enabled: default_enabled },
59
+ SelfClosingTag: { enabled: default_enabled },
60
+ SpaceAroundErbTag: { enabled: default_enabled },
61
+ SpaceIndentation: { enabled: default_enabled },
62
+ SpaceInHtmlTag: { enabled: default_enabled },
63
+ TrailingWhitespace: { enabled: default_enabled },
63
64
  },
64
65
  )
65
66
  end
67
+
68
+ def default_for(config)
69
+ default_linters_enabled = config.to_hash.dig("EnableDefaultLinters")
70
+ default(default_enabled: default_linters_enabled).merge(config)
71
+ end
66
72
  end
67
73
 
68
74
  private
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ module ERBLint
3
+ class Stats
4
+ attr_accessor :found,
5
+ :corrected,
6
+ :exceptions,
7
+ :linters,
8
+ :files,
9
+ :processed_files
10
+
11
+ def initialize(
12
+ found: 0,
13
+ corrected: 0,
14
+ exceptions: 0,
15
+ linters: 0,
16
+ files: 0,
17
+ processed_files: {}
18
+ )
19
+ @found = found
20
+ @corrected = corrected
21
+ @exceptions = exceptions
22
+ @linters = linters
23
+ @files = files
24
+ @processed_files = processed_files
25
+ end
26
+ end
27
+ end
@@ -38,7 +38,9 @@ module ERBLint
38
38
  @corrector.remove_trailing(range_with_offset(range), size)
39
39
  end
40
40
 
41
- def range_with_offset(range)
41
+ def range_with_offset(node_or_range)
42
+ range = to_range(node_or_range)
43
+
42
44
  @processed_source.to_source_range(
43
45
  bound(@offset + range.begin_pos)..bound(@offset + (range.end_pos - 1))
44
46
  )
@@ -50,6 +52,21 @@ module ERBLint
50
52
  @bound_range.max,
51
53
  ].min
52
54
  end
55
+
56
+ private
57
+
58
+ def to_range(node_or_range)
59
+ case node_or_range
60
+ when ::RuboCop::AST::Node, ::Parser::Source::Comment
61
+ node_or_range.loc.expression
62
+ when ::Parser::Source::Range
63
+ node_or_range
64
+ else
65
+ raise TypeError,
66
+ 'Expected a Parser::Source::Range, Comment or ' \
67
+ "Rubocop::AST::Node, got #{node_or_range.class}"
68
+ end
69
+ end
53
70
  end
54
71
  end
55
72
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ERBLint
4
- VERSION = '0.0.31'
4
+ VERSION = '0.0.36'
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.0.31
4
+ version: 0.0.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Chan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-22 00:00:00.000000000 Z
11
+ date: 2021-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: better_html
@@ -42,16 +42,30 @@ dependencies:
42
42
  name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.79.0
47
+ version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: parser
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.7.1.4
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: 0.79.0
68
+ version: 2.7.1.4
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: activesupport
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-shopify
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  description: ERB Linter tool.
126
154
  email:
127
155
  - justin.the.c@gmail.com
@@ -157,9 +185,13 @@ files:
157
185
  - lib/erb_lint/linters/trailing_whitespace.rb
158
186
  - lib/erb_lint/offense.rb
159
187
  - lib/erb_lint/processed_source.rb
188
+ - lib/erb_lint/reporter.rb
189
+ - lib/erb_lint/reporters/compact_reporter.rb
190
+ - lib/erb_lint/reporters/multiline_reporter.rb
160
191
  - lib/erb_lint/runner.rb
161
192
  - lib/erb_lint/runner_config.rb
162
193
  - lib/erb_lint/runner_config_resolver.rb
194
+ - lib/erb_lint/stats.rb
163
195
  - lib/erb_lint/utils/block_map.rb
164
196
  - lib/erb_lint/utils/offset_corrector.rb
165
197
  - lib/erb_lint/utils/ruby_to_erb.rb
@@ -167,7 +199,8 @@ files:
167
199
  homepage: https://github.com/Shopify/erb-lint
168
200
  licenses:
169
201
  - MIT
170
- metadata: {}
202
+ metadata:
203
+ allowed_push_host: https://rubygems.org
171
204
  post_install_message:
172
205
  rdoc_options: []
173
206
  require_paths:
@@ -176,7 +209,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
176
209
  requirements:
177
210
  - - ">="
178
211
  - !ruby/object:Gem::Version
179
- version: 2.4.0
212
+ version: 2.5.0
180
213
  required_rubygems_version: !ruby/object:Gem::Requirement
181
214
  requirements:
182
215
  - - ">="