Skip to content

Commit

Permalink
[Fix #10263] Fix aliasing problem for Enabled in Config
Browse files Browse the repository at this point in the history
There was an aliasing problem in the `Config` class causing the
`cop_options` local variable to reference the same object between
different calls to `for_cop` even when the calls were to different
`Config` objects with different `@hash` objects.

I have not been able to figure out the root cause. Only that the
phenomenon occurs, and that duplicating the cop options before
setting the `Enabled` property resolves it.
  • Loading branch information
jonas054 committed Jul 8, 2022
1 parent 4868b0e commit 0724f1a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog/fix_disabling_leaking_between_directories.md
@@ -0,0 +1 @@
* [#10263](https://github.com/rubocop/rubocop/pull/10263): Fix the value of `Enabled` leaking between configurations. ([@jonas054][])
2 changes: 1 addition & 1 deletion lib/rubocop/config.rb
Expand Up @@ -25,7 +25,7 @@ def initialize(hash = {}, loaded_path = nil)
@loaded_path = loaded_path
@for_cop = Hash.new do |h, cop|
qualified_cop_name = Cop::Registry.qualified_cop_name(cop, loaded_path)
cop_options = self[qualified_cop_name] || {}
cop_options = self[qualified_cop_name].dup || {}
cop_options['Enabled'] = enable_cop?(qualified_cop_name, cop_options)
h[cop] = cop_options
end
Expand Down
36 changes: 36 additions & 0 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -635,6 +635,42 @@
end
end

context 'when a department is enabled in the top directory and disabled in a subdirectory' do
let(:file_path) { '.rubocop.yml' }
let(:configuration_from_subdir) do
described_class.configuration_from_file('subdir/.rubocop.yml')
end

before do
stub_const('RuboCop::ConfigLoader::RUBOCOP_HOME', 'rubocop')
stub_const('RuboCop::ConfigLoader::DEFAULT_FILE',
File.join('rubocop', 'config', 'default.yml'))

create_file('rubocop/config/default.yml', <<~YAML)
Layout/SomeCop:
Enabled: pending
YAML
create_file(file_path, <<~YAML)
Layout:
Enabled: true
YAML
create_file('subdir/.rubocop.yml', <<~YAML)
Layout:
Enabled: false
YAML
end

it 'does not disable pending cops of that department in the top directory' do
# The cop is disabled in subdir because its department is disabled there.
subdir_configuration = configuration_from_subdir.for_cop('Layout/SomeCop')
expect(subdir_configuration['Enabled']).to be(false)

# The disabling of the cop in subdir should not leak into the top directory.
examples_configuration = configuration_from_file.for_cop('Layout/SomeCop')
expect(examples_configuration['Enabled']).to eq('pending')
end
end

context 'when a department is disabled', :restore_registry do
let(:file_path) { '.rubocop.yml' }

Expand Down

0 comments on commit 0724f1a

Please sign in to comment.