Skip to content

Commit 39298e6

Browse files
authored
Add wildcard pattern support for paths in rubycritic.yml (#476)
1 parent 7a15d7f commit 39298e6

File tree

6 files changed

+120
-0
lines changed

6 files changed

+120
-0
lines changed

.reek.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ detectors:
9393
DuplicateMethodCall:
9494
exclude:
9595
- RubyCritic::Analyser::Churn#run
96+
- RubyCritic::Configuration#set
9697
- Parser::AST::Node#module_name
9798
TooManyStatements:
9899
exclude:
100+
- RubyCritic::Configuration#find_directories
99101
- RubyCritic::RakeTask#initialize
100102
- RubyCritic::Analyser::Complexity#run
101103
- RubyCritic::Analyser::Coverage#synchronize_resultset
@@ -119,15 +121,18 @@ detectors:
119121
- RubyCritic::ViewHelpers#smell_location_path
120122
- RubyCritic::Generator::HtmlReport#create_directories_and_files
121123
- RubyCritic::SourceLocator#deduplicate_symlinks
124+
- RubyCritic::Configuration#setup_paths_for_targets
122125
NestedIterators:
123126
exclude:
124127
- Parser::AST::Node#recursive_children
125128
- RubyCritic::Analyser::FlaySmells#run
126129
- RubyCritic::Cli::Options::Argv#parse
127130
- RubyCritic::Generator::HtmlReport#create_directories_and_files
128131
- RubyCritic::AnalysedModulesCollection#initialize
132+
- RubyCritic::Configuration#find_directories
129133
UtilityFunction:
130134
exclude:
135+
- RubyCritic::Configuration#find_directories
131136
- RubyCritic::Analyser::Coverage#resultset_path
132137
- RubyCritic::Analyser::Coverage#resultset_writelock
133138
- RubyCritic::Analyser::FlaySmells#cost

.rubocop.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,11 @@ Lint/StructNewOverride:
9292
Metrics/AbcSize:
9393
Exclude:
9494
- 'lib/rubycritic/configuration.rb'
95+
96+
Metrics/MethodLength:
97+
Exclude:
98+
- 'lib/rubycritic/configuration.rb'
99+
100+
Style/RedundantAssignment:
101+
Exclude:
102+
- 'lib/rubycritic/configuration.rb'

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
* [CHANGE] Fix some typos (by [@jbampton][])
2727
* [FEATURE] Add coverage_path configuration option (by [@exoego][])
2828

29+
* [CHANGE] Add support for wildcard entries to the paths option in rubycritic.yml (by [@rishiain][])
30+
2931
# v4.9.0 / 2023-10-18 [(commits)](https://github.com/whitesmith/rubycritic/compare/v4.8.1...v4.9.0)
3032

3133
* [CHANGE] Bump aruba, cucumber, fakefs, flog, mdl, minitest, and rubocop dependencies (by [@faisal][])

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ minimum_score: 95 # default is 0
154154
paths: # Files to analyse. Churn calculation is scoped to these files when using Git SCM.
155155
- 'app/controllers/'
156156
- 'app/models/'
157+
- 'lib/**' # Wildcard patterns are supported (excludes tmp directories automatically)
157158
```
158159
159160
### Analyzer Configuration

lib/rubycritic/configuration.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@ def set(options)
2121
self.no_browser = options[:no_browser]
2222
self.coverage_path = options[:coverage_path]
2323
self.threshold_score = options[:threshold_score].to_i
24+
setup_paths_for_targets(options) if options[:paths]
2425
setup_analysis_targets(options)
2526
setup_version_control(options)
2627
setup_formats(options)
2728
end
2829

30+
def setup_paths_for_targets(options)
31+
options[:paths] = find_directories(options[:paths])
32+
end
33+
2934
def setup_analysis_targets(options)
3035
self.paths = options[:paths] || ['.']
3136
self.ruby_extensions = options[:ruby_extensions] || %w[.rb .rake .thor]
@@ -51,6 +56,20 @@ def source_control_present?
5156
source_control_system &&
5257
!source_control_system.is_a?(SourceControlSystem::Double)
5358
end
59+
60+
private
61+
62+
def find_directories(paths)
63+
expanded_paths = paths.flat_map do |path|
64+
if path.include?('**')
65+
search_pattern = File.join(path)
66+
Dir.glob(search_pattern).select { |tmp_path| File.directory?(tmp_path) && !tmp_path.start_with?('tmp') }
67+
else
68+
path
69+
end
70+
end
71+
expanded_paths
72+
end
5473
end
5574

5675
module Config

test/lib/rubycritic/configuration_test.rb

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,89 @@
4040
_(RubyCritic::Config.formats).must_equal [:html]
4141
end
4242
end
43+
44+
describe '#setup_paths_for_targets' do
45+
let(:config) { RubyCritic::Configuration.new }
46+
47+
it 'processes paths without wildcards correctly' do
48+
options = { paths: ['lib', 'app/models'] }
49+
config.setup_paths_for_targets(options)
50+
51+
_(options[:paths]).must_equal ['lib', 'app/models']
52+
end
53+
54+
it 'expands wildcard patterns to matching directories' do
55+
# Create temporary directory structure for testing
56+
Dir.mktmpdir do |tmpdir|
57+
Dir.chdir(tmpdir) do
58+
FileUtils.mkdir_p('src/controllers')
59+
FileUtils.mkdir_p('src/admin/app')
60+
FileUtils.mkdir_p('src/admin/lib')
61+
FileUtils.mkdir_p('src/customer/app')
62+
FileUtils.mkdir_p('src/models')
63+
FileUtils.mkdir_p('src/views')
64+
FileUtils.mkdir_p('lib/tasks')
65+
66+
options = { paths: ['src/**/app'] }
67+
config.setup_paths_for_targets(options)
68+
expected = ['src/admin/app', 'src/customer/app']
69+
70+
_(options[:paths].sort).must_equal expected.sort
71+
end
72+
end
73+
end
74+
75+
it 'excludes tmp directories from wildcard expansion' do
76+
# Create temporary directory structure for testing
77+
Dir.mktmpdir do |tmpdir|
78+
Dir.chdir(tmpdir) do
79+
FileUtils.mkdir_p('src/models')
80+
FileUtils.mkdir_p('app/models')
81+
FileUtils.mkdir_p('tmp/cache')
82+
FileUtils.mkdir_p('tmp/logs')
83+
84+
options = { paths: ['**'] }
85+
config.setup_paths_for_targets(options)
86+
87+
_(options[:paths]).wont_include 'tmp/cache'
88+
_(options[:paths]).wont_include 'tmp/logs'
89+
_(options[:paths]).wont_include 'tmp'
90+
_(options[:paths]).must_include 'src'
91+
_(options[:paths]).must_include 'app'
92+
end
93+
end
94+
end
95+
96+
it 'handles mixed wildcard and non-wildcard paths' do
97+
# Create temporary directory structure for testing
98+
Dir.mktmpdir do |tmpdir|
99+
Dir.chdir(tmpdir) do
100+
FileUtils.mkdir_p('app/models')
101+
FileUtils.mkdir_p('app/controllers')
102+
FileUtils.mkdir_p('lib/tasks')
103+
FileUtils.mkdir_p('spec/support')
104+
105+
options = { paths: ['app/**', 'lib', 'spec/support'] }
106+
config.setup_paths_for_targets(options)
107+
108+
_(options[:paths]).must_include 'app/models'
109+
_(options[:paths]).must_include 'app/controllers'
110+
_(options[:paths]).must_include 'lib'
111+
_(options[:paths]).must_include 'spec/support'
112+
end
113+
end
114+
end
115+
116+
it 'processes empty wildcard results correctly' do
117+
# Create temporary directory structure for testing
118+
Dir.mktmpdir do |tmpdir|
119+
Dir.chdir(tmpdir) do
120+
options = { paths: ['nonexistent/**'] }
121+
config.setup_paths_for_targets(options)
122+
123+
_(options[:paths]).must_equal []
124+
end
125+
end
126+
end
127+
end
43128
end

0 commit comments

Comments
 (0)