Skip to content

Commit

Permalink
[Fix rubocop#9934] Fix configuration loading to not raise an error fo…
Browse files Browse the repository at this point in the history
…r an obsolete ruby version that is subsequently overridden.
  • Loading branch information
dvandersluis committed Sep 22, 2021
1 parent 7fe8ae0 commit 979f20b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog/fix_fix_configuration_loading_to_not_raise.md
@@ -0,0 +1 @@
* [#9934](https://github.com/rubocop/rubocop/issues/9934): Fix configuration loading to not raise an error for an obsolete ruby version that is subsequently overridden. ([@dvandersluis][])
5 changes: 5 additions & 0 deletions lib/rubocop/config.rb
Expand Up @@ -51,6 +51,11 @@ def check
self
end

def validate_after_resolution
@validator.validate_after_resolution
self
end

def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key,
:fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values
def_delegators :@validator, :validate, :target_ruby_version
Expand Down
2 changes: 2 additions & 0 deletions lib/rubocop/config_loader.rb
Expand Up @@ -101,6 +101,8 @@ def configuration_from_file(config_file, check: true)
return default_configuration if config_file == DEFAULT_FILE

config = load_file(config_file, check: check)
config.validate_after_resolution if check

if ignore_parent_exclusion?
print 'Ignoring AllCops/Exclude from parent folders' if debug?
else
Expand Down
10 changes: 9 additions & 1 deletion lib/rubocop/config_validator.rb
Expand Up @@ -44,14 +44,22 @@ def validate
check_obsoletions

alert_about_unrecognized_cops(invalid_cop_names)
check_target_ruby
validate_new_cops_parameter
validate_parameter_names(valid_cop_names)
validate_enforced_styles(valid_cop_names)
validate_syntax_cop
reject_mutually_exclusive_defaults
end

# Validations that should only be run after all config resolving has
# taken place:
# * The target ruby version is only checked once the entire inheritance
# chain has been loaded so that only the final value is validated, and
# any obsolete but overridden values are ignored.
def validate_after_resolution
check_target_ruby
end

def target_ruby_version
target_ruby.version
end
Expand Down
79 changes: 79 additions & 0 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -1155,6 +1155,85 @@ class Loop < Cop
end
end

context 'when a file inherits a configuration that specifies TargetRubyVersion' do
let(:file_path) { '.rubocop.yml' }
let(:target_ruby_version) { configuration_from_file['AllCops']['TargetRubyVersion'] }
let(:default_ruby_version) { RuboCop::TargetRuby::DEFAULT_VERSION }

before do
create_file('.rubocop-parent.yml', <<~YAML)
AllCops:
TargetRubyVersion: #{inherited_version}
YAML
end

context 'when the specified version is current' do
before do
create_file(file_path, <<~YAML)
inherit_from: .rubocop-parent.yml
YAML
end

let(:inherited_version) { default_ruby_version }

it 'sets TargetRubyVersion' do
expect(target_ruby_version).to eq(inherited_version)
end
end

context 'when the specified version is obsolete' do
let(:inherited_version) { '2.4' }

context 'and it is not overridden' do
before do
create_file(file_path, <<~YAML)
inherit_from: .rubocop-parent.yml
YAML
end

it 'raises a validation error' do
expect { configuration_from_file }.to raise_error(RuboCop::ValidationError) do |error|
expect(error.message).to start_with('RuboCop found unsupported Ruby version 2.4')
end
end
end

context 'and it is overridden' do
before do
create_file(file_path, <<~YAML)
inherit_from: .rubocop-parent.yml
AllCops:
TargetRubyVersion: #{default_ruby_version}
YAML
end

it 'uses the given version' do
expect(target_ruby_version).to eq(default_ruby_version)
end
end

context 'with deeper nesting' do
before do
create_file('.rubocop-child.yml', <<~YAML)
inherit_from: .rubocop-parent.yml
YAML

create_file('.rubocop.yml', <<~YAML)
inherit_from: .rubocop-child.yml
AllCops:
TargetRubyVersion: #{default_ruby_version}
YAML
end

it 'uses the given version' do
expect(target_ruby_version).to eq(default_ruby_version)
end
end
end
end

context 'EnabledByDefault / DisabledByDefault' do
def cop_enabled?(cop_class)
configuration_from_file.for_cop(cop_class).fetch('Enabled')
Expand Down

0 comments on commit 979f20b

Please sign in to comment.