Skip to content

Commit

Permalink
[Fix rubocop#5576] Treat relativity of Include parameters correctly
Browse files Browse the repository at this point in the history
For configuration files whose name begins with `.rubocop`, the paths in
`Include` parameters are relative to the directory of the configuration file.

When another configuration file inherits from such a file, we cannot just copy
the `Include` paths. We must modify them so they select the files that were
originally intended.
  • Loading branch information
jonas054 committed Apr 18, 2021
1 parent 7d12a8d commit 0ce108e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@
* [#7977](https://github.com/rubocop/rubocop/issues/7977): Add `Layout/RedundantLineBreak` cop. ([@jonas054][])
* [#9691](https://github.com/rubocop/rubocop/issues/9691): Add configuration parameter `InspectBlocks` to `Layout/RedundantLineBreak`. ([@jonas054][])

### Bug fixes

* [#5576](https://github.com/rubocop/rubocop/issues/5576): Fix problem with inherited `Include` parameters. ([@jonas054][])

## 1.12.1 (2021-04-04)

### Bug fixes
Expand Down
15 changes: 15 additions & 0 deletions lib/rubocop/config_loader_resolver.rb
Expand Up @@ -37,10 +37,25 @@ def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/Metho
inherit_mode: determine_inherit_mode(hash, k))
end
hash[k] = v
fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
end
end
end

# When one .rubocop.yml file inherits from another .rubocop.yml file, the Include paths in the
# base configuration are relative to the directory where the base configuration file is. For the
# derived configuration, we need to make those paths relative to where the derived configuration
# file is.
def fix_include_paths(base_config_path, hash, path, key, value)
return unless File.basename(base_config_path).start_with?('.rubocop')

base_dir = File.dirname(base_config_path)
derived_dir = File.dirname(path)
hash[key]['Include'] = value['Include'].map do |include_path|
PathUtil.relative_path(File.join(base_dir, include_path), derived_dir)
end
end

def resolve_inheritance_from_gems(hash)
gems = hash.delete('inherit_gem')
(gems || {}).each_pair do |gem_name, config_path|
Expand Down
14 changes: 14 additions & 0 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -269,6 +269,9 @@
Exclude:
- vendor/**
- !ruby/regexp /[A-Z]/
Style/StringLiterals:
Include:
- dir/**/*.rb
YAML

create_file(file_path, ['inherit_from: ../.rubocop.yml'])
Expand All @@ -279,6 +282,10 @@
expect(excludes).to eq([File.expand_path('vendor/**'), /[A-Z]/])
end

it 'gets an Include that is relative to the subdirectory' do
expect(configuration_from_file['Style/StringLiterals']['Include']).to eq(['**/*.rb'])
end

it 'ignores parent AllCops/Exclude if ignore_parent_exclusion is true' do
sub_file_path = 'vendor/.rubocop.yml'
create_file(sub_file_path, <<~YAML)
Expand Down Expand Up @@ -320,6 +327,9 @@
AllCops:
Exclude:
- vendor/**
Style/StringLiterals:
Include:
- '**/*.rb'
YAML

create_file(file_path, ['inherit_from: ../src/.rubocop.yml'])
Expand All @@ -329,6 +339,10 @@
excludes = configuration_from_file['AllCops']['Exclude']
expect(excludes).to eq([File.expand_path('src/vendor/**')])
end

it 'gets an Include that is relative to the subdirectory' do
expect(configuration_from_file['Style/StringLiterals']['Include']).to eq(['../src/**/*.rb'])
end
end

context 'when a file inherits and overrides an Exclude' do
Expand Down

0 comments on commit 0ce108e

Please sign in to comment.