haml_lint 0.62.0 → 0.63.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3754327462146047a8677d8e91b7d47e3d538f2459f2d3ebd583ad2dafc92c3b
4
- data.tar.gz: 33ccb58e67c32798c90da242cc8708e763f93a1509c6083d54b351453f587a5f
3
+ metadata.gz: ff5d0f872861912fb3f9ebb3dd05429f38302aff57e00aa91334a55fbde02029
4
+ data.tar.gz: c5c23f8563ffe272f090076522243069ad12a7db1d8af9c5eb498eea4e2f355e
5
5
  SHA512:
6
- metadata.gz: 8a9ece6eda4dac35772948661486fc6c4fada9d3071b8b4ff52d37bab8930d032d0138a95f59a1a54c760951001010102317965e11aea2fd6dec4a35c7528aac
7
- data.tar.gz: 67d13e3d045dd804f7f93c662dd8dfb833ac8104a2c52bd1699ba9201861630e686228de725ede55d469a9b3c15a02fcf0b910b843c3d425314e59721ae01ba0
6
+ metadata.gz: 7c36eee182a75b3917f263bd21dfdc4453b9a447682693739930ca8f703caf2aeb46fddae9fb8b47688c81bc21a29ad711182d837c2e6fe1e82cd54b8c1f4a17
7
+ data.tar.gz: 7d0f28064b25e97a12abad18ba0761a8230138ba784391a612ed63e79d64bf5eae9ca1d65b08600803a13870d47b3d75081d24e4487d10b3b9be8bc8b3770613
@@ -16,6 +16,31 @@ module HamlLint
16
16
  #
17
17
  # The work is spread across the classes in the HamlLint::RubyExtraction module.
18
18
  class Linter::RuboCop < Linter
19
+ # Processes a ruby file and reports RuboCop offenses
20
+ class Runner < ::RuboCop::Runner
21
+ attr_reader :offenses
22
+
23
+ def run(path, code, config:)
24
+ @offenses = []
25
+ @options[:stdin] = code
26
+ @config_store.instance_variable_set(:@options_config, config)
27
+ super([path])
28
+ end
29
+
30
+ def corrected_code
31
+ @options[:stdin]
32
+ end
33
+
34
+ # Executed when a file has been scanned by RuboCop, adding the reported
35
+ # offenses to our collection.
36
+ #
37
+ # @param _file [String]
38
+ # @param offenses [Array<RuboCop::Cop::Offense>]
39
+ def file_finished(_file, offenses)
40
+ @offenses = offenses
41
+ end
42
+ end
43
+
19
44
  include LinterRegistry
20
45
 
21
46
  supports_autocorrect(true)
@@ -98,9 +123,9 @@ module HamlLint
98
123
 
99
124
  def rubocop_config_for(path)
100
125
  user_config_path = ENV['HAML_LINT_RUBOCOP_CONF'] || config['config_file']
101
- user_config_path ||= self.class.rubocop_config_store.user_rubocop_config_path_for(path)
126
+ user_config_path ||= rubocop_config_store.user_rubocop_config_path_for(path)
102
127
  user_config_path = File.absolute_path(user_config_path)
103
- self.class.rubocop_config_store.config_object_pointing_to(user_config_path)
128
+ rubocop_config_store.config_object_pointing_to(user_config_path)
104
129
  end
105
130
 
106
131
  # Extracted here so that tests can stub this to always return true
@@ -168,15 +193,13 @@ module HamlLint
168
193
  false
169
194
  end
170
195
 
171
- # A single CLI instance is shared between files to avoid RuboCop
196
+ # A single RuboCop runner is shared between files to avoid RuboCop
172
197
  # having to repeatedly reload .rubocop.yml.
173
- def self.rubocop_cli # rubocop:disable Lint/IneffectiveAccessModifier
174
- # The ivar is stored on the class singleton rather than the Linter instance
175
- # because it can't be Marshal.dump'd (as used by Parallel.map)
176
- @rubocop_cli ||= ::RuboCop::CLI.new
198
+ def rubocop_runner
199
+ @rubocop_runner ||= Runner.new(rubocop_options, ::RuboCop::ConfigStore.new)
177
200
  end
178
201
 
179
- def self.rubocop_config_store # rubocop:disable Lint/IneffectiveAccessModifier
202
+ def rubocop_config_store
180
203
  @rubocop_config_store ||= RubocopConfigStore.new
181
204
  end
182
205
 
@@ -190,7 +213,7 @@ module HamlLint
190
213
  def process_ruby_source(ruby_code, source_map)
191
214
  filename = document.file || 'ruby_script.rb'
192
215
 
193
- offenses, corrected_ruby = run_rubocop(self.class.rubocop_cli, ruby_code, filename)
216
+ offenses, corrected_ruby = run_rubocop(rubocop_runner, ruby_code, filename)
194
217
 
195
218
  extract_lints_from_offenses(offenses, source_map)
196
219
  corrected_ruby
@@ -199,55 +222,35 @@ module HamlLint
199
222
  # Runs RuboCop, returning the offenses and corrected code. Raises when RuboCop
200
223
  # fails to run correctly.
201
224
  #
202
- # @param rubocop_cli [RuboCop::CLI] There to simplify tests by using a stub
225
+ # @param rubocop_runner [HamlLint::Linter::RuboCop::Runner] There to simplify tests by using a stub
203
226
  # @param ruby_code [String] The ruby code to run through RuboCop
204
227
  # @param path [String] the path to tell RuboCop we are running
205
228
  # @return [Array<RuboCop::Cop::Offense>, String]
206
- def run_rubocop(rubocop_cli, ruby_code, path) # rubocop:disable Metrics
207
- rubocop_status = nil
208
- stdout_str, stderr_str = HamlLint::Utils.with_captured_streams(ruby_code) do
209
- rubocop_cli.config_store.instance_variable_set(:@options_config, rubocop_config_for(path))
210
- rubocop_status = rubocop_cli.run(rubocop_flags + ['--stdin', path])
211
- end
229
+ def run_rubocop(rubocop_runner, ruby_code, path) # rubocop:disable Metrics
230
+ rubocop_runner.run(path, ruby_code, config: rubocop_config_for(path))
212
231
 
213
232
  if ENV['HAML_LINT_INTERNAL_DEBUG'] == 'true'
214
- if OffenseCollector.offenses.empty?
233
+ if rubocop_runner.offenses.empty?
215
234
  puts "------ No lints found by RuboCop in #{@document.file}"
216
235
  else
217
236
  puts "------ Raw lints found by RuboCop in #{@document.file}"
218
- OffenseCollector.offenses.each do |offense|
237
+ rubocop_runner.offenses.each do |offense|
219
238
  puts offense
220
239
  end
221
240
  puts '------'
222
241
  end
223
242
  end
224
243
 
225
- unless [::RuboCop::CLI::STATUS_SUCCESS, ::RuboCop::CLI::STATUS_OFFENSES].include?(rubocop_status)
226
- if stderr_str.start_with?('Infinite loop')
227
- msg = "RuboCop exited unsuccessfully with status #{rubocop_status}." \
228
- ' This appears to be due to an autocorrection infinite loop.'
229
- if ENV['HAML_LINT_DEBUG'] == 'true'
230
- msg += " DEBUG: RuboCop's output:\n"
231
- msg += stderr_str.strip
232
- else
233
- msg += " First line of RuboCop's output (Use --debug mode to see more):\n"
234
- msg += stderr_str.each_line.first.strip
235
- end
236
-
237
- raise HamlLint::Exceptions::InfiniteLoopError, msg
238
- end
239
-
240
- raise HamlLint::Exceptions::ConfigurationError,
241
- "RuboCop exited unsuccessfully with status #{rubocop_status}." \
242
- ' Here is its output to check the stack trace or see if there was' \
243
- " a misconfiguration:\n#{stderr_str}"
244
- end
245
-
246
244
  if @autocorrect
247
- corrected_ruby = stdout_str.partition("#{'=' * 20}\n").last
245
+ corrected_ruby = rubocop_runner.corrected_code
248
246
  end
249
247
 
250
- [OffenseCollector.offenses, corrected_ruby]
248
+ [rubocop_runner.offenses, corrected_ruby]
249
+ rescue ::RuboCop::Error => e
250
+ raise HamlLint::Exceptions::ConfigurationError,
251
+ "RuboCop raised #{e}." \
252
+ ' Here is its output to check the stack trace or see if there was' \
253
+ " a misconfiguration:\n#{e.message}\n#{e.backtrace}"
251
254
  end
252
255
 
253
256
  # Aggregates RuboCop offenses and converts them to {HamlLint::Lint}s
@@ -294,14 +297,27 @@ module HamlLint
294
297
  corrected: corrected)
295
298
  end
296
299
 
297
- # Returns flags that will be passed to RuboCop CLI.
300
+ # rubocop:disable Style/MutableConstant
301
+ DEFAULT_FLAGS = %w[--format RuboCop::Formatter::BaseFormatter]
302
+ begin
303
+ ::RuboCop::Options.new.parse(['--raise-cop-error'])
304
+ DEFAULT_FLAGS << '--raise-cop-error'
305
+ rescue OptionParser::InvalidOption
306
+ # older versions of RuboCop don't support this flag
307
+ end
308
+ DEFAULT_FLAGS.freeze
309
+ # rubocop:enable Style/MutableConstant
310
+
311
+ # Returns options that will be passed to the RuboCop runner.
298
312
  #
299
- # @return [Array<String>]
300
- def rubocop_flags
301
- flags = %w[--format HamlLint::OffenseCollector]
313
+ # @return [Hash]
314
+ def rubocop_options
315
+ # using BaseFormatter suppresses any default output
316
+ flags = DEFAULT_FLAGS
302
317
  flags += ignored_cops_flags
303
318
  flags += rubocop_autocorrect_flags
304
- flags
319
+ options, _args = ::RuboCop::Options.new.parse(flags)
320
+ options
305
321
  end
306
322
 
307
323
  def rubocop_autocorrect_flags
@@ -342,29 +358,19 @@ module HamlLint
342
358
  return [] if ignored_cops.empty?
343
359
  ['--except', ignored_cops.uniq.join(',')]
344
360
  end
345
- end
346
-
347
- # Collects offenses detected by RuboCop.
348
- class OffenseCollector < ::RuboCop::Formatter::BaseFormatter
349
- class << self
350
- # List of offenses reported by RuboCop.
351
- attr_accessor :offenses
352
- end
353
361
 
354
- # Executed when RuboCop begins linting.
355
- #
356
- # @param _target_files [Array<String>]
357
- def started(_target_files)
358
- self.class.offenses = []
362
+ # Exclude ivars that don't marshal properly
363
+ def marshal_dump
364
+ excluded_ivars = %i[@rubocop_runner @rubocop_config_store @user_config_path_to_config_object]
365
+ (instance_variables - excluded_ivars).to_h do |ivar|
366
+ [ivar, instance_variable_get(ivar)]
367
+ end
359
368
  end
360
369
 
361
- # Executed when a file has been scanned by RuboCop, adding the reported
362
- # offenses to our collection.
363
- #
364
- # @param _file [String]
365
- # @param offenses [Array<RuboCop::Cop::Offense>]
366
- def file_finished(_file, offenses)
367
- self.class.offenses += offenses
370
+ def marshal_load(ivars)
371
+ ivars.each do |k, v|
372
+ instance_variable_set(k, v)
373
+ end
368
374
  end
369
375
  end
370
376
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  module HamlLint
5
- VERSION = '0.62.0'
5
+ VERSION = '0.63.0'
6
6
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.62.0
4
+ version: 0.63.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane da Silva
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-08 00:00:00.000000000 Z
10
+ date: 2025-06-24 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: haml