reek 6.0.0 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/ruby.yml +52 -0
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +27 -20
- data/CHANGELOG.md +16 -0
- data/Gemfile +5 -6
- data/README.md +10 -4
- data/docs/Boolean-Parameter.md +2 -2
- data/docs/templates/default/docstring/setup.rb +1 -3
- data/features/command_line_interface/options.feature +2 -2
- data/features/configuration_files/schema_validation.feature +1 -1
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +4 -4
- data/features/reports/yaml.feature +3 -3
- data/features/step_definitions/reek_steps.rb +1 -1
- data/features/step_definitions/sample_file_steps.rb +2 -2
- data/features/support/env.rb +0 -1
- data/lib/reek/ast/node.rb +1 -1
- data/lib/reek/cli/options.rb +1 -1
- data/lib/reek/configuration/app_configuration.rb +4 -3
- data/lib/reek/configuration/configuration_converter.rb +2 -2
- data/lib/reek/configuration/directory_directives.rb +9 -3
- data/lib/reek/configuration/excluded_paths.rb +2 -1
- data/lib/reek/context/code_context.rb +1 -1
- data/lib/reek/context/module_context.rb +3 -1
- data/lib/reek/context/refinement_context.rb +16 -0
- data/lib/reek/context_builder.rb +16 -2
- data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
- data/lib/reek/smell_detectors/base_detector.rb +1 -0
- data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smell_warning.rb +1 -2
- data/lib/reek/source/source_locator.rb +13 -10
- data/lib/reek/spec/smell_matcher.rb +2 -1
- data/lib/reek/version.rb +1 -1
- data/lib/reek.rb +1 -0
- data/reek.gemspec +10 -2
- data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
- data/spec/quality/documentation_spec.rb +2 -1
- data/spec/reek/code_comment_spec.rb +20 -23
- data/spec/reek/configuration/directory_directives_spec.rb +6 -0
- data/spec/reek/configuration/excluded_paths_spec.rb +12 -3
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/location_formatter_spec.rb +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +3 -3
- data/spec/reek/smell_detectors/utility_function_spec.rb +16 -0
- data/spec/reek/smell_warning_spec.rb +12 -12
- data/spec/reek/spec/should_reek_of_spec.rb +0 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
- data/spec/reek/spec/smell_matcher_spec.rb +1 -1
- data/spec/spec_helper.rb +18 -5
- data/tasks/configuration.rake +1 -2
- metadata +21 -27
- data/.travis.yml +0 -36
- data/spec/factories/factories.rb +0 -37
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 967e95555fe823e1924a78ff2a8c94c40bdb4d16d031bacd51b885d1475bce30
|
|
4
|
+
data.tar.gz: c9760389b64b3bb9f96f1896192a540a4de8b7f395808299b9a67e47238e8c42
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea4c588166903c10bed44c2a459e43e4db479943f8f489ca1eaefbb6db375605e06ff678f5411def292e19ef8c2754245bca78eb24373532474091b0ab8eadbe
|
|
7
|
+
data.tar.gz: 9e0804841d54d4278149422d66c7e379597e3f99275ba8b9ab4aef6e7041bde6c928db5f3c62a3b5c3d1d6fc4da0216ba5d13aa5562f9e0b565ec31bb115d0fe
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and
|
|
2
|
+
# run tests with Rake
|
|
3
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
4
|
+
|
|
5
|
+
name: Ruby
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [ master ]
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [ master ]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
ruby: [2.4, 2.5, 2.6, 2.7, jruby-9.2]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v2
|
|
24
|
+
- name: Set up Ruby
|
|
25
|
+
uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
ruby-version: ${{ matrix.ruby }}
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
- name: Run specs
|
|
30
|
+
run: bundle exec rake test:spec
|
|
31
|
+
- name: Run performance tests
|
|
32
|
+
run: bundle exec rake test:performance
|
|
33
|
+
- name: Update default configuration
|
|
34
|
+
run: bundle exec rake configuration:update_default_configuration
|
|
35
|
+
- name: Run cucumber features
|
|
36
|
+
run: bundle exec rake test:features
|
|
37
|
+
- name: Run code quality specs
|
|
38
|
+
run: bundle exec rake test:quality
|
|
39
|
+
|
|
40
|
+
rubocop:
|
|
41
|
+
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v2
|
|
46
|
+
- name: Set up Ruby
|
|
47
|
+
uses: ruby/setup-ruby@v1
|
|
48
|
+
with:
|
|
49
|
+
ruby-version: 2.7
|
|
50
|
+
bundler-cache: true
|
|
51
|
+
- name: Run RuboCop
|
|
52
|
+
run: bundle exec rubocop -P
|
data/.rubocop.yml
CHANGED
|
@@ -9,6 +9,7 @@ AllCops:
|
|
|
9
9
|
- 'samples/**/*'
|
|
10
10
|
- 'tmp/**/*'
|
|
11
11
|
- 'vendor/**/*'
|
|
12
|
+
NewCops: enable
|
|
12
13
|
TargetRubyVersion: 2.4
|
|
13
14
|
|
|
14
15
|
# Tables are nice
|
|
@@ -57,6 +58,7 @@ Lint/BooleanSymbol:
|
|
|
57
58
|
# Spec blocks can be any size
|
|
58
59
|
Metrics/BlockLength:
|
|
59
60
|
Exclude:
|
|
61
|
+
- '**/*.gemspec'
|
|
60
62
|
- 'spec/**/*'
|
|
61
63
|
|
|
62
64
|
# Keyword arguments make long parameter lists readable
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2021-01-03 18:17:11 UTC using RuboCop version 1.7.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
9
|
+
# Offense count: 2
|
|
10
|
+
Lint/MissingSuper:
|
|
11
|
+
Exclude:
|
|
12
|
+
- 'lib/reek/rake/task.rb'
|
|
13
|
+
- 'lib/reek/smell_detectors/base_detector.rb'
|
|
14
|
+
|
|
15
|
+
# Offense count: 2
|
|
16
|
+
# Configuration parameters: IgnoredPatterns.
|
|
17
|
+
# IgnoredPatterns: (?-mix:(exactly|at_least|at_most)\(\d+\)\.times)
|
|
18
|
+
Lint/UnreachableLoop:
|
|
19
|
+
Exclude:
|
|
20
|
+
- 'spec/reek/ast/node_spec.rb'
|
|
21
|
+
|
|
22
|
+
# Offense count: 2
|
|
23
|
+
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
|
10
24
|
Metrics/AbcSize:
|
|
11
25
|
Max: 21
|
|
12
26
|
|
|
13
27
|
# Offense count: 1
|
|
14
|
-
# Configuration parameters: CountComments.
|
|
28
|
+
# Configuration parameters: CountComments, CountAsOne.
|
|
15
29
|
Metrics/ClassLength:
|
|
16
|
-
Max:
|
|
30
|
+
Max: 170
|
|
17
31
|
|
|
18
|
-
# Offense count:
|
|
19
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
|
32
|
+
# Offense count: 13
|
|
33
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
|
20
34
|
Metrics/MethodLength:
|
|
21
35
|
Max: 16
|
|
22
36
|
|
|
@@ -25,17 +39,6 @@ RSpec/AnyInstance:
|
|
|
25
39
|
Exclude:
|
|
26
40
|
- 'spec/reek/cli/application_spec.rb'
|
|
27
41
|
|
|
28
|
-
# Offense count: 1
|
|
29
|
-
# Configuration parameters: CustomIncludeMethods.
|
|
30
|
-
RSpec/EmptyExampleGroup:
|
|
31
|
-
Exclude:
|
|
32
|
-
- 'spec/factories/factories.rb'
|
|
33
|
-
|
|
34
|
-
# Offense count: 1
|
|
35
|
-
RSpec/MissingExampleGroupArgument:
|
|
36
|
-
Exclude:
|
|
37
|
-
- 'spec/factories/factories.rb'
|
|
38
|
-
|
|
39
42
|
# Offense count: 4
|
|
40
43
|
RSpec/MultipleDescribes:
|
|
41
44
|
Exclude:
|
|
@@ -44,12 +47,16 @@ RSpec/MultipleDescribes:
|
|
|
44
47
|
- 'spec/reek/report/location_formatter_spec.rb'
|
|
45
48
|
- 'spec/reek/report/progress_formatter_spec.rb'
|
|
46
49
|
|
|
47
|
-
# Offense count:
|
|
48
|
-
# Configuration parameters: AggregateFailuresByDefault.
|
|
50
|
+
# Offense count: 30
|
|
49
51
|
RSpec/MultipleExpectations:
|
|
50
52
|
Max: 5
|
|
51
53
|
|
|
52
|
-
# Offense count:
|
|
54
|
+
# Offense count: 16
|
|
55
|
+
# Configuration parameters: AllowSubject.
|
|
56
|
+
RSpec/MultipleMemoizedHelpers:
|
|
57
|
+
Max: 9
|
|
58
|
+
|
|
59
|
+
# Offense count: 27
|
|
53
60
|
RSpec/NestedGroups:
|
|
54
61
|
Max: 5
|
|
55
62
|
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## 6.0.3 (2021-01-11)
|
|
4
|
+
|
|
5
|
+
* (mvz) Require parser 3.0
|
|
6
|
+
* (mvz) In a refinement, assign smells to the refined module or class
|
|
7
|
+
|
|
8
|
+
## 6.0.3 (2020-10-17)
|
|
9
|
+
|
|
10
|
+
* (mvz) Loosen dependency on psych. This should resolve installation problems on
|
|
11
|
+
mingw32
|
|
12
|
+
* (Cesario Uy) Fix typo in docs for "Boolean Parameter" smell
|
|
13
|
+
* (mvz) Set link metadata in gemspec
|
|
14
|
+
|
|
15
|
+
## 6.0.1 (2020-05-26)
|
|
16
|
+
|
|
17
|
+
* (Maxim Pertsov) Handle absolute paths for directories correctly
|
|
18
|
+
|
|
3
19
|
## 6.0.0 (2020-03-30)
|
|
4
20
|
|
|
5
21
|
* (mvz) Make codeclimate-engine-rb a development dependency
|
data/Gemfile
CHANGED
|
@@ -7,17 +7,16 @@ ruby RUBY_VERSION
|
|
|
7
7
|
group :development do
|
|
8
8
|
gem 'aruba', '~> 1.0'
|
|
9
9
|
gem 'codeclimate-engine-rb', '~> 0.4.0'
|
|
10
|
-
gem 'cucumber', '
|
|
11
|
-
gem 'factory_bot', '~> 5.0', '!= 5.1.0'
|
|
10
|
+
gem 'cucumber', ['>= 4.0', '< 6.0']
|
|
12
11
|
gem 'kramdown', '~> 2.1'
|
|
13
12
|
gem 'kramdown-parser-gfm', '~> 1.0'
|
|
14
13
|
gem 'rake', '~> 13.0'
|
|
15
14
|
gem 'rspec', '~> 3.0'
|
|
16
15
|
gem 'rspec-benchmark', '~> 0.6.0'
|
|
17
|
-
gem 'rubocop', '~>
|
|
18
|
-
gem 'rubocop-performance', '~> 1.
|
|
19
|
-
gem 'rubocop-rspec', '~> 1.
|
|
20
|
-
gem 'simplecov', '
|
|
16
|
+
gem 'rubocop', '~> 1.7.0'
|
|
17
|
+
gem 'rubocop-performance', '~> 1.9.1'
|
|
18
|
+
gem 'rubocop-rspec', '~> 2.1.0'
|
|
19
|
+
gem 'simplecov', ['>= 0.18.0', '< 0.21.0']
|
|
21
20
|
gem 'yard', '~> 0.9.5'
|
|
22
21
|
|
|
23
22
|
platforms :mri do
|
data/README.md
CHANGED
|
@@ -286,7 +286,7 @@ detectors:
|
|
|
286
286
|
# You can disable smells completely
|
|
287
287
|
IrresponsibleModule:
|
|
288
288
|
enabled: false
|
|
289
|
-
|
|
289
|
+
|
|
290
290
|
# You can use filters to silence Reek warnings.
|
|
291
291
|
# Either because you simply disagree with Reek (we are not the police) or
|
|
292
292
|
# because you want to fix this at a later point in time.
|
|
@@ -294,7 +294,7 @@ detectors:
|
|
|
294
294
|
exclude:
|
|
295
295
|
- "MyWorker#self.class_method" # should be refactored
|
|
296
296
|
- "AnotherWorker#instance_method" # should be refactored as well
|
|
297
|
-
|
|
297
|
+
|
|
298
298
|
# A lot of smells allow fine tuning their configuration. You can look up all available options
|
|
299
299
|
# in the corresponding smell documentation in /docs. In most cases you probably can just go
|
|
300
300
|
# with the defaults as documented in defaults.reek.yml.
|
|
@@ -349,9 +349,14 @@ This configuration for instance:
|
|
|
349
349
|
detectors:
|
|
350
350
|
IrresponsibleModule:
|
|
351
351
|
enabled: false
|
|
352
|
-
|
|
352
|
+
|
|
353
353
|
TooManyStatements:
|
|
354
354
|
max_statements: 5
|
|
355
|
+
|
|
356
|
+
directories:
|
|
357
|
+
"app/controllers":
|
|
358
|
+
TooManyStatements:
|
|
359
|
+
max_statements: 10
|
|
355
360
|
```
|
|
356
361
|
|
|
357
362
|
translates to:
|
|
@@ -368,7 +373,7 @@ are documented in the corresponding smell type /docs page (if you want to get a
|
|
|
368
373
|
configurations you can also check out [the `defaults.reek.yml` file in this repository](docs/defaults.reek.yml).
|
|
369
374
|
|
|
370
375
|
Note that you do not need a configuration file at all.
|
|
371
|
-
If you're fine with all the [defaults
|
|
376
|
+
If you're fine with all the [defaults](docs/defaults.reek.yml) we set you can skip this completely.
|
|
372
377
|
|
|
373
378
|
Don't worry about introducing a mistake in your configuration file that might go unnoticed - Reek uses a
|
|
374
379
|
schema to validate your configuration against on start up and will faily loudly in case you
|
|
@@ -607,6 +612,7 @@ Be careful though, Reek does not merge your configuration entries, so if you alr
|
|
|
607
612
|
Reek
|
|
608
613
|
* [ruby-critic](https://github.com/whitesmith/rubycritic) - gem that wraps around static analysis gems such as Reek, [flay](https://github.com/seattlerb/flay) and [flog](https://github.com/seattlerb/flog)
|
|
609
614
|
* [pronto-reek](https://github.com/mmozuras/pronto-reek) - Reek integration for [pronto](https://github.com/mmozuras/pronto)
|
|
615
|
+
* [action-reek](https://github.com/reviewdog/action-reek) - GitHub Action to run reek with [reviewdog](https://github.com/reviewdog/reviewdog) 🐶
|
|
610
616
|
|
|
611
617
|
### Misc
|
|
612
618
|
|
data/docs/Boolean-Parameter.md
CHANGED
|
@@ -38,11 +38,11 @@ Note that both smells are reported, _Boolean Parameter_ and _Control Parameter_.
|
|
|
38
38
|
|
|
39
39
|
## Getting rid of the smell
|
|
40
40
|
|
|
41
|
-
This is highly
|
|
41
|
+
This is highly dependent on your exact architecture, but looking at the example above what you could do is:
|
|
42
42
|
|
|
43
43
|
* Move everything in the `if` branch into a separate method
|
|
44
44
|
* Move everything in the `else` branch into a separate method
|
|
45
|
-
* Get rid of the `hit_the_switch` method
|
|
45
|
+
* Get rid of the `hit_the_switch` method altogether
|
|
46
46
|
* Make the decision what method to call in the initial caller of `hit_the_switch`
|
|
47
47
|
|
|
48
48
|
## Current support in Reek
|
|
@@ -43,7 +43,7 @@ Feature: Reek can be controlled using command-line options
|
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
|
44
44
|
--smell SMELL Only look for a specific smell.
|
|
45
45
|
Call it like this: reek --smell MissingSafeMethod source.rb
|
|
46
|
-
Check out https://github.com/troessner/reek/blob/v6.0.
|
|
46
|
+
Check out https://github.com/troessner/reek/blob/v6.0.3/docs/Code-Smells.md for a list of smells
|
|
47
47
|
--stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
|
|
48
48
|
|
|
49
49
|
Generate a todo list:
|
|
@@ -119,5 +119,5 @@ Feature: Reek can be controlled using command-line options
|
|
|
119
119
|
UnusedPrivateMethod
|
|
120
120
|
UtilityFunction
|
|
121
121
|
|
|
122
|
-
Check out https://github.com/troessner/reek/blob/v6.0.
|
|
122
|
+
Check out https://github.com/troessner/reek/blob/v6.0.3/docs/Code-Smells.md for a details on each detector
|
|
123
123
|
"""
|
|
@@ -6,7 +6,7 @@ Feature: Validate schema
|
|
|
6
6
|
Scenario: Our generated default configuration
|
|
7
7
|
Given our default configuration file
|
|
8
8
|
And the clean file "clean.rb"
|
|
9
|
-
When I run reek -c defaults.reek clean.rb
|
|
9
|
+
When I run reek -c defaults.reek.yml clean.rb
|
|
10
10
|
Then it succeeds
|
|
11
11
|
And it reports nothing
|
|
12
12
|
|
|
@@ -24,7 +24,7 @@ Feature: Report smells using simple JSON layout
|
|
|
24
24
|
"context": "Smelly#x",
|
|
25
25
|
"lines": [ 4 ],
|
|
26
26
|
"message": "has the name 'x'",
|
|
27
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
|
27
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Method-Name.md",
|
|
28
28
|
"name": "x"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple JSON layout
|
|
|
33
33
|
"context": "Smelly#x",
|
|
34
34
|
"lines": [ 5 ],
|
|
35
35
|
"message": "has the variable name 'y'",
|
|
36
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
|
36
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Variable-Name.md",
|
|
37
37
|
"name": "y"
|
|
38
38
|
}
|
|
39
39
|
]
|
|
@@ -53,7 +53,7 @@ Feature: Report smells using simple JSON layout
|
|
|
53
53
|
1
|
|
54
54
|
],
|
|
55
55
|
"message": "has no descriptive comment",
|
|
56
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
|
56
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.3/docs/Irresponsible-Module.md"
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
59
|
"""
|
|
@@ -182,8 +182,8 @@ Feature: Correctly formatted reports
|
|
|
182
182
|
And it reports:
|
|
183
183
|
"""
|
|
184
184
|
smelly.rb -- 2 warnings:
|
|
185
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.
|
|
186
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.
|
|
185
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Method-Name.md]
|
|
186
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Variable-Name.md]
|
|
187
187
|
"""
|
|
188
188
|
|
|
189
189
|
Examples:
|
|
@@ -209,8 +209,8 @@ Feature: Correctly formatted reports
|
|
|
209
209
|
And it reports:
|
|
210
210
|
"""
|
|
211
211
|
smelly.rb -- 2 warnings:
|
|
212
|
-
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.
|
|
213
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.
|
|
212
|
+
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Method-Name.md]
|
|
213
|
+
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Variable-Name.md]
|
|
214
214
|
"""
|
|
215
215
|
|
|
216
216
|
Examples:
|
|
@@ -25,7 +25,7 @@ Feature: Report smells using simple YAML layout
|
|
|
25
25
|
smell_type: UncommunicativeMethodName
|
|
26
26
|
source: smelly.rb
|
|
27
27
|
name: x
|
|
28
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
|
28
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Method-Name.md
|
|
29
29
|
- context: Smelly#x
|
|
30
30
|
lines:
|
|
31
31
|
- 5
|
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple YAML layout
|
|
|
33
33
|
smell_type: UncommunicativeVariableName
|
|
34
34
|
source: smelly.rb
|
|
35
35
|
name: y
|
|
36
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
|
36
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.3/docs/Uncommunicative-Variable-Name.md
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
39
|
Scenario: Indicate smells and print them as yaml when using STDIN
|
|
@@ -48,5 +48,5 @@ Feature: Report smells using simple YAML layout
|
|
|
48
48
|
lines:
|
|
49
49
|
- 1
|
|
50
50
|
message: has no descriptive comment
|
|
51
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
|
51
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.3/docs/Irresponsible-Module.md
|
|
52
52
|
"""
|
|
@@ -44,8 +44,8 @@ Given(/^a configuration file '(.+)'$/) do |filename|
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
Given(/^our default configuration file$/) do
|
|
47
|
-
default_configuration = File.read
|
|
48
|
-
write_file('defaults.reek', default_configuration)
|
|
47
|
+
default_configuration = File.read Reek::DEFAULT_SMELL_CONFIGURATION
|
|
48
|
+
write_file('defaults.reek.yml', default_configuration)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
When(/^I run "reek (.*?)" in a subdirectory$/) do |args|
|
data/features/support/env.rb
CHANGED
data/lib/reek/ast/node.rb
CHANGED
|
@@ -60,7 +60,7 @@ module Reek
|
|
|
60
60
|
#
|
|
61
61
|
# Returns an array with all matching nodes.
|
|
62
62
|
def each_node(target_types, ignoring = [], &blk)
|
|
63
|
-
return enum_for(:each_node, target_types, ignoring) unless
|
|
63
|
+
return enum_for(:each_node, target_types, ignoring) unless blk
|
|
64
64
|
|
|
65
65
|
look_for(Array(target_types), ignoring, &blk)
|
|
66
66
|
end
|
data/lib/reek/cli/options.rb
CHANGED
|
@@ -72,11 +72,12 @@ module Reek
|
|
|
72
72
|
|
|
73
73
|
def load_values(values)
|
|
74
74
|
values.each do |key, value|
|
|
75
|
-
|
|
75
|
+
case key
|
|
76
|
+
when EXCLUDE_PATHS_KEY
|
|
76
77
|
excluded_paths.add value
|
|
77
|
-
|
|
78
|
+
when DIRECTORIES_KEY
|
|
78
79
|
directory_directives.add value
|
|
79
|
-
|
|
80
|
+
when DETECTORS_KEY
|
|
80
81
|
default_directive.add value
|
|
81
82
|
end
|
|
82
83
|
end
|
|
@@ -74,7 +74,7 @@ module Reek
|
|
|
74
74
|
return unless configuration[DETECTORS_KEY]
|
|
75
75
|
|
|
76
76
|
configuration[DETECTORS_KEY].tap do |detectors|
|
|
77
|
-
detectors.
|
|
77
|
+
detectors.each_key do |detector|
|
|
78
78
|
convertible_attributes(detectors[detector]).each do |attribute|
|
|
79
79
|
detectors[detector][attribute] = detectors[detector][attribute].map do |item|
|
|
80
80
|
to_regex item
|
|
@@ -94,7 +94,7 @@ module Reek
|
|
|
94
94
|
return unless configuration[DIRECTORIES_KEY]
|
|
95
95
|
|
|
96
96
|
configuration[DIRECTORIES_KEY].tap do |directories|
|
|
97
|
-
directories.
|
|
97
|
+
directories.each_key do |directory|
|
|
98
98
|
directories[directory].each do |detector, configuration|
|
|
99
99
|
convertible_attributes(configuration).each do |attribute|
|
|
100
100
|
directories[directory][detector][attribute] = directories[directory][detector][attribute].map do |item|
|
|
@@ -53,10 +53,16 @@ module Reek
|
|
|
53
53
|
# @quality :reek:FeatureEnvy
|
|
54
54
|
def best_match_for(source_base_dir)
|
|
55
55
|
keys.
|
|
56
|
-
select
|
|
56
|
+
select do |pathname|
|
|
57
|
+
match?(source_base_dir, pathname) || match?(source_base_dir, pathname.expand_path)
|
|
58
|
+
end.
|
|
57
59
|
max_by { |pathname| pathname.to_s.length }
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
def match?(source_base_dir, pathname)
|
|
63
|
+
source_base_dir.to_s.match(glob_to_regexp(pathname.to_s))
|
|
64
|
+
end
|
|
65
|
+
|
|
60
66
|
# Transform a glob pattern to a regexp.
|
|
61
67
|
#
|
|
62
68
|
# It changes:
|
|
@@ -78,7 +84,7 @@ module Reek
|
|
|
78
84
|
gsub('<<to_eol_wildcards>>', '.*').
|
|
79
85
|
gsub('<<to_wildcards>>', '.*')
|
|
80
86
|
else
|
|
81
|
-
glob
|
|
87
|
+
"#{glob}.*"
|
|
82
88
|
end
|
|
83
89
|
|
|
84
90
|
Regexp.new("^#{regexp}$", Regexp::IGNORECASE)
|
|
@@ -86,7 +92,7 @@ module Reek
|
|
|
86
92
|
|
|
87
93
|
def error_message_for_invalid_smell_type(klass)
|
|
88
94
|
"You are trying to configure smell type #{klass} but we can't find one with that name.\n" \
|
|
89
|
-
"Please make sure you spelled it right. (See 'docs/defaults.reek' in the Reek\n" \
|
|
95
|
+
"Please make sure you spelled it right. (See 'docs/defaults.reek.yml' in the Reek\n" \
|
|
90
96
|
'repository for a list of all available smell types.)'
|
|
91
97
|
end
|
|
92
98
|
end
|
|
@@ -66,6 +66,8 @@ module Reek
|
|
|
66
66
|
CodeComment.new(comment: exp.leading_comment).descriptive?
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
CONSTANT_SEXP_TYPES = [:casgn, :class, :module].freeze
|
|
70
|
+
|
|
69
71
|
# A namespace module is a module (or class) that is only there for namespacing
|
|
70
72
|
# purposes, and thus contains only nested constants, modules or classes.
|
|
71
73
|
#
|
|
@@ -78,7 +80,7 @@ module Reek
|
|
|
78
80
|
return false if exp.type == :casgn
|
|
79
81
|
|
|
80
82
|
children = exp.direct_children
|
|
81
|
-
children.any? && children.all? { |child|
|
|
83
|
+
children.any? && children.all? { |child| CONSTANT_SEXP_TYPES.include? child.type }
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def track_visibility(visibility, names)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'module_context'
|
|
4
|
+
|
|
5
|
+
module Reek
|
|
6
|
+
module Context
|
|
7
|
+
#
|
|
8
|
+
# A context wrapper for any refinement blocks found in a syntax tree.
|
|
9
|
+
#
|
|
10
|
+
class RefinementContext < ModuleContext
|
|
11
|
+
def full_name
|
|
12
|
+
exp.call.args.first.name
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/reek/context_builder.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative 'context/class_context'
|
|
|
5
5
|
require_relative 'context/ghost_context'
|
|
6
6
|
require_relative 'context/method_context'
|
|
7
7
|
require_relative 'context/module_context'
|
|
8
|
+
require_relative 'context/refinement_context'
|
|
8
9
|
require_relative 'context/root_context'
|
|
9
10
|
require_relative 'context/send_context'
|
|
10
11
|
require_relative 'context/singleton_attribute_context'
|
|
@@ -20,7 +21,7 @@ module Reek
|
|
|
20
21
|
# counting. Ideally `ContextBuilder` would only build up the context tree and leave the
|
|
21
22
|
# statement and reference counting to the contexts.
|
|
22
23
|
#
|
|
23
|
-
# @quality :reek:TooManyMethods { max_methods:
|
|
24
|
+
# @quality :reek:TooManyMethods { max_methods: 32 }
|
|
24
25
|
# @quality :reek:UnusedPrivateMethod { exclude: [ !ruby/regexp /process_/ ] }
|
|
25
26
|
# @quality :reek:DataClump
|
|
26
27
|
class ContextBuilder
|
|
@@ -263,9 +264,16 @@ module Reek
|
|
|
263
264
|
#
|
|
264
265
|
# Counts non-empty blocks as one statement.
|
|
265
266
|
#
|
|
267
|
+
# A refinement block is handled differently and causes a RefinementContext
|
|
268
|
+
# to be opened.
|
|
269
|
+
#
|
|
266
270
|
def process_block(exp, _parent)
|
|
267
271
|
increase_statement_count_by(exp.block)
|
|
268
|
-
|
|
272
|
+
if exp.call.name == :refine
|
|
273
|
+
handle_refinement_block(exp)
|
|
274
|
+
else
|
|
275
|
+
process(exp)
|
|
276
|
+
end
|
|
269
277
|
end
|
|
270
278
|
|
|
271
279
|
# Handles `begin` and `kwbegin` nodes. `begin` nodes are created implicitly
|
|
@@ -508,6 +516,12 @@ module Reek
|
|
|
508
516
|
end
|
|
509
517
|
end
|
|
510
518
|
|
|
519
|
+
def handle_refinement_block(exp)
|
|
520
|
+
inside_new_context(Context::RefinementContext, exp) do
|
|
521
|
+
process(exp)
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
511
525
|
def handle_send_for_modules(exp)
|
|
512
526
|
arg_names = exp.args.map { |arg| arg.children.first }
|
|
513
527
|
current_context.track_visibility(exp.name, arg_names)
|
|
@@ -59,7 +59,7 @@ BooleanParameter:
|
|
|
59
59
|
|
|
60
60
|
## Getting rid of the smell
|
|
61
61
|
|
|
62
|
-
This is highly
|
|
62
|
+
This is highly dependent on your exact architecture, but looking at the example above what you could do is:
|
|
63
63
|
|
|
64
64
|
* Move everything in the `if` branch into a separate method
|
|
65
65
|
* Move everything in the `else` branch into a separate method
|
|
@@ -19,6 +19,7 @@ module Reek
|
|
|
19
19
|
# @quality :reek:TooManyMethods { max_methods: 18 }
|
|
20
20
|
class BaseDetector
|
|
21
21
|
attr_reader :config
|
|
22
|
+
|
|
22
23
|
# The name of the config field that lists the names of code contexts
|
|
23
24
|
# that should not be checked. Add this field to the config for each
|
|
24
25
|
# smell that should ignore this code element.
|