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

Allow inherit_from to accept a glob #11261

Merged
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/new_allow_inherit_from_to_accept_a_glob.md
@@ -0,0 +1 @@
* [#11261](https://github.com/rubocop/rubocop/pull/11261): Allow inherit_from to accept a glob. ([@alexevanczuk][])
10 changes: 10 additions & 0 deletions docs/modules/ROOT/pages/configuration.adoc
Expand Up @@ -114,6 +114,16 @@ inherit_from:
- ../conf/.rubocop.yml
----

`inherit_from` also accepts a glob, for example:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might also want to say a few words about potential use-cases here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some more text about using this to manage per-component .rubocop_todo.yml files. I'm not actually sure about other use cases since that use-case was the main motivator here 🤔 Let me know what ya think!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.


[source,yaml]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add an extra blank here.

----
inherit_from:
- packages/*/.rubocop_todo.yml
----

The example above is one potential use-case: allowing components within your repo to organize their own `.rubocop_todo.yml` files.

== Inheriting configuration from a remote URL

The optional `inherit_from` directive can contain a full url to a remote
Expand Down
6 changes: 5 additions & 1 deletion lib/rubocop/config_loader_resolver.rb
Expand Up @@ -206,7 +206,11 @@ def merge_hashes?(base_hash, derived_hash, key)
end

def base_configs(path, inherit_from, file)
configs = Array(inherit_from).compact.map do |f|
inherit_froms = Array(inherit_from).compact.flat_map do |f|
PathUtil.glob?(f) ? Dir.glob(f) : f
end

configs = inherit_froms.map do |f|
ConfigLoader.load_file(inherited_file(path, f, file))
end

Expand Down
7 changes: 6 additions & 1 deletion lib/rubocop/path_util.rb
Expand Up @@ -40,7 +40,7 @@ def match_path?(pattern, path)
matches =
if pattern == path
true
elsif pattern.match?(/[*{\[?]/)
elsif glob?(pattern)
File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
end

Expand All @@ -62,6 +62,11 @@ def absolute?(path)
%r{\A([A-Z]:)?/}i.match?(path)
end

# Returns true for a glob
def glob?(path)
path.match?(/[*{\[?]/)
end

def hidden_file_in_not_hidden_dir?(pattern, path)
hidden_file?(path) &&
File.fnmatch?(
Expand Down
47 changes: 47 additions & 0 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -384,6 +384,53 @@
end
end

context 'when a file inherits from multiple files using a glob' do
let(:file_path) { '.rubocop.yml' }

before do
create_file(file_path, <<~YAML)
inherit_from:
- packages/*/.rubocop_todo.yml

inherit_mode:
merge:
- Exclude

Style/For:
Exclude:
- spec/requests/group_invite_spec.rb
YAML

create_file('packages/package_one/.rubocop_todo.yml', <<~YAML)
Style/For:
Exclude:
- 'spec/models/group_spec.rb'
YAML

create_file('packages/package_two/.rubocop_todo.yml', <<~YAML)
Style/For:
Exclude:
- 'spec/models/expense_spec.rb'
YAML

create_file('packages/package_three/.rubocop_todo.yml', <<~YAML)
Style/For:
Exclude:
- 'spec/models/order_spec.rb'
YAML
end

it 'gets the Exclude merging the inherited one' do
expected = [
File.expand_path('packages/package_two/spec/models/expense_spec.rb'),
File.expand_path('packages/package_one/spec/models/group_spec.rb'),
File.expand_path('packages/package_three/spec/models/order_spec.rb'),
File.expand_path('spec/requests/group_invite_spec.rb')
]
expect(configuration_from_file['Style/For']['Exclude']).to match_array(expected)
end
end

context 'when a file inherits and overrides a hash with nil' do
let(:file_path) { '.rubocop.yml' }

Expand Down