From 7fcd2908a9709731d9e4d2fb83ae974ab3ae39f1 Mon Sep 17 00:00:00 2001 From: Martin Ericson Date: Mon, 17 Jul 2023 13:51:17 +0200 Subject: [PATCH] [Fix #12052] Handle all glob special characters Co-Authored-By: Love Ottosson --- .../fix_nested_special_glob_characters.md | 1 + lib/rubocop/target_finder.rb | 8 ++++-- spec/rubocop/target_finder_spec.rb | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_nested_special_glob_characters.md diff --git a/changelog/fix_nested_special_glob_characters.md b/changelog/fix_nested_special_glob_characters.md new file mode 100644 index 00000000000..65a5b53e54d --- /dev/null +++ b/changelog/fix_nested_special_glob_characters.md @@ -0,0 +1 @@ +* [#12052](https://github.com/rubocop/rubocop/issues/12052): Fix "Subfolders can't include glob special characters". ([@meric426][], [@loveo][]) diff --git a/lib/rubocop/target_finder.rb b/lib/rubocop/target_finder.rb index 10327b20790..b1eadd423d9 100644 --- a/lib/rubocop/target_finder.rb +++ b/lib/rubocop/target_finder.rb @@ -94,8 +94,12 @@ def find_files(base_dir, flags) end def wanted_dir_patterns(base_dir, exclude_pattern, flags) - base_dir = base_dir.gsub('/{}/', '/\{}/') - dirs = Dir.glob(File.join(base_dir.gsub('/*/', '/\*/').gsub('/**/', '/\**/'), '*/'), flags) + # Escape glob characters in base_dir to avoid unwanted behavior. + base_dir = base_dir.gsub(/[\\\{\}\[\]\*\?]/) do |reserved_glob_character| + "\\#{reserved_glob_character}" + end + + dirs = Dir.glob(File.join(base_dir, '*/'), flags) .reject do |dir| next true if dir.end_with?('/./', '/../') next true if File.fnmatch?(exclude_pattern, dir, flags) diff --git a/spec/rubocop/target_finder_spec.rb b/spec/rubocop/target_finder_spec.rb index 50b8f85c2f6..20b6e2bdfe3 100755 --- a/spec/rubocop/target_finder_spec.rb +++ b/spec/rubocop/target_finder_spec.rb @@ -435,6 +435,32 @@ expect(found_basenames.include?('ruby4.rb')).to be(true) end + it 'works also if a folder is named "{foo}"' do + create_empty_file('{foo}/ruby4.rb') + + config = instance_double(RuboCop::Config) + exclude_property = { 'Exclude' => [File.expand_path('dir1/**/*')] } + allow(config).to receive(:for_all_cops).and_return(exclude_property) + allow(config_store).to receive(:for).and_return(config) + + expect(found_basenames.include?('ruby1.rb')).to be(false) + expect(found_basenames.include?('ruby3.rb')).to be(true) + expect(found_basenames.include?('ruby4.rb')).to be(true) + end + + it 'works also if a folder is named "[...something]"' do + create_empty_file('[...something]/ruby4.rb') + + config = instance_double(RuboCop::Config) + exclude_property = { 'Exclude' => [File.expand_path('dir1/**/*')] } + allow(config).to receive(:for_all_cops).and_return(exclude_property) + allow(config_store).to receive(:for).and_return(config) + + expect(found_basenames.include?('ruby1.rb')).to be(false) + expect(found_basenames.include?('ruby3.rb')).to be(true) + expect(found_basenames.include?('ruby4.rb')).to be(true) + end + it 'works if patterns are empty' do allow(Dir).to receive(:glob).and_call_original allow_any_instance_of(described_class).to receive(:wanted_dir_patterns).and_return([])