Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #9934] Fix configuration loading to not raise an error for an obsolete ruby version that is overridden #10112

Merged
merged 1 commit into from Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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