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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +52 -0
  4. data/.rubocop.yml +2 -0
  5. data/.rubocop_todo.yml +27 -20
  6. data/CHANGELOG.md +16 -0
  7. data/Gemfile +5 -6
  8. data/README.md +10 -4
  9. data/docs/Boolean-Parameter.md +2 -2
  10. data/docs/templates/default/docstring/setup.rb +1 -3
  11. data/features/command_line_interface/options.feature +2 -2
  12. data/features/configuration_files/schema_validation.feature +1 -1
  13. data/features/reports/json.feature +3 -3
  14. data/features/reports/reports.feature +4 -4
  15. data/features/reports/yaml.feature +3 -3
  16. data/features/step_definitions/reek_steps.rb +1 -1
  17. data/features/step_definitions/sample_file_steps.rb +2 -2
  18. data/features/support/env.rb +0 -1
  19. data/lib/reek/ast/node.rb +1 -1
  20. data/lib/reek/cli/options.rb +1 -1
  21. data/lib/reek/configuration/app_configuration.rb +4 -3
  22. data/lib/reek/configuration/configuration_converter.rb +2 -2
  23. data/lib/reek/configuration/directory_directives.rb +9 -3
  24. data/lib/reek/configuration/excluded_paths.rb +2 -1
  25. data/lib/reek/context/code_context.rb +1 -1
  26. data/lib/reek/context/module_context.rb +3 -1
  27. data/lib/reek/context/refinement_context.rb +16 -0
  28. data/lib/reek/context_builder.rb +16 -2
  29. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  30. data/lib/reek/smell_detectors/base_detector.rb +1 -0
  31. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
  32. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
  33. data/lib/reek/smell_warning.rb +1 -2
  34. data/lib/reek/source/source_locator.rb +13 -10
  35. data/lib/reek/spec/smell_matcher.rb +2 -1
  36. data/lib/reek/version.rb +1 -1
  37. data/lib/reek.rb +1 -0
  38. data/reek.gemspec +10 -2
  39. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
  40. data/spec/quality/documentation_spec.rb +2 -1
  41. data/spec/reek/code_comment_spec.rb +20 -23
  42. data/spec/reek/configuration/directory_directives_spec.rb +6 -0
  43. data/spec/reek/configuration/excluded_paths_spec.rb +12 -3
  44. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
  45. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
  46. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  47. data/spec/reek/report/location_formatter_spec.rb +3 -3
  48. data/spec/reek/smell_detectors/base_detector_spec.rb +3 -3
  49. data/spec/reek/smell_detectors/utility_function_spec.rb +16 -0
  50. data/spec/reek/smell_warning_spec.rb +12 -12
  51. data/spec/reek/spec/should_reek_of_spec.rb +0 -1
  52. data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
  53. data/spec/reek/spec/smell_matcher_spec.rb +1 -1
  54. data/spec/spec_helper.rb +18 -5
  55. data/tasks/configuration.rake +1 -2
  56. metadata +21 -27
  57. data/.travis.yml +0 -36
  58. data/spec/factories/factories.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf5a72026003b4d6b44ec51ba559efda3de62733061d6889596d8661ec24a12c
4
- data.tar.gz: 142319663079b82d851245cf6aa0e3a07ea5418426d21c25171d4fae1adc8549
3
+ metadata.gz: 967e95555fe823e1924a78ff2a8c94c40bdb4d16d031bacd51b885d1475bce30
4
+ data.tar.gz: c9760389b64b3bb9f96f1896192a540a4de8b7f395808299b9a67e47238e8c42
5
5
  SHA512:
6
- metadata.gz: 8a626593f82fcb8307629380ca25374b73d013561a3c2b0ffb2a7b5175997632b1f2925add8fb2d7ff1fe10d3a6343ee8998d5d167d45ce09888ea59c8c2ec6e
7
- data.tar.gz: f081217d15f01c31cc014ef935b359614ee412c8aa7c0fbbb22e40db0caa1dd0429b727935c02542ea1e73ca7023b15cb25d639d644e8ab3af42af33870f0de6
6
+ metadata.gz: ea4c588166903c10bed44c2a459e43e4db479943f8f489ca1eaefbb6db375605e06ff678f5411def292e19ef8c2754245bca78eb24373532474091b0ab8eadbe
7
+ data.tar.gz: 9e0804841d54d4278149422d66c7e379597e3f99275ba8b9ab4aef6e7041bde6c928db5f3c62a3b5c3d1d6fc4da0216ba5d13aa5562f9e0b565ec31bb115d0fe
@@ -0,0 +1,9 @@
1
+ # Documentation for all configuration options:
2
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3
+
4
+ version: 2
5
+ updates:
6
+ - package-ecosystem: "bundler"
7
+ directory: "/"
8
+ schedule:
9
+ interval: "daily"
@@ -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 2019-12-22 13:19:30 +0100 using RuboCop version 0.78.0.
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: 3
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: 161
30
+ Max: 170
17
31
 
18
- # Offense count: 14
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: 32
48
- # Configuration parameters: AggregateFailuresByDefault.
50
+ # Offense count: 30
49
51
  RSpec/MultipleExpectations:
50
52
  Max: 5
51
53
 
52
- # Offense count: 25
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', '~> 3.0'
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', '~> 0.80.0'
18
- gem 'rubocop-performance', '~> 1.5.0'
19
- gem 'rubocop-rspec', '~> 1.38.1'
20
- gem 'simplecov', '~> 0.18.1'
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.reek.yml](docs/defaults.reek.yml) we set you can skip this completely.
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
 
@@ -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 dependant on your exact architecture, but looking at the example above what you could do is:
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 alltogether
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
@@ -27,9 +27,7 @@ def show_api_marker_section?
27
27
  return false if object.type == :root
28
28
 
29
29
  case api_text
30
- when 'public'
31
- false
32
- when 'private'
30
+ when 'public', 'private'
33
31
  false
34
32
  else
35
33
  true
@@ -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.0/docs/Code-Smells.md for a list of smells
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.0/docs/Code-Smells.md for a details on each detector
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.0/docs/Uncommunicative-Method-Name.md",
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.0/docs/Uncommunicative-Variable-Name.md",
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.0/docs/Irresponsible-Module.md"
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.0/docs/Uncommunicative-Method-Name.md]
186
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.0/docs/Uncommunicative-Variable-Name.md]
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.0/docs/Uncommunicative-Method-Name.md]
213
- UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.0/docs/Uncommunicative-Variable-Name.md]
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.0/docs/Uncommunicative-Method-Name.md
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.0/docs/Uncommunicative-Variable-Name.md
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.0/docs/Irresponsible-Module.md
51
+ documentation_link: https://github.com/troessner/reek/blob/v6.0.3/docs/Irresponsible-Module.md
52
52
  """
@@ -6,7 +6,7 @@ When 'I run the code climate reek runner' do
6
6
  run_command_and_stop 'code_climate_reek'
7
7
  end
8
8
 
9
- When /^I pass "([^\"]*)" to reek *(.*)$/ do |stdin, args|
9
+ When /^I pass "([^"]*)" to reek *(.*)$/ do |stdin, args|
10
10
  reek_with_pipe(stdin, args)
11
11
  end
12
12
 
@@ -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 SAMPLES_DIR.join('..').join('docs').join('defaults.reek.yml')
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|
@@ -1,7 +1,6 @@
1
1
  require_relative '../../lib/reek'
2
2
  require_relative '../../lib/reek/cli/application'
3
3
  require 'aruba/cucumber'
4
- require 'active_support/core_ext/string/strip'
5
4
 
6
5
  begin
7
6
  require 'pry-byebug'
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 block_given?
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
@@ -87,7 +87,7 @@ module Reek
87
87
 
88
88
  def set_banner
89
89
  program_name = parser.program_name
90
- parser.banner = <<-BANNER.gsub(/^[ ]+/, '')
90
+ parser.banner = <<-BANNER.gsub(/^ +/, '')
91
91
  Usage: #{program_name} [options] [files]
92
92
 
93
93
  Examples:
@@ -72,11 +72,12 @@ module Reek
72
72
 
73
73
  def load_values(values)
74
74
  values.each do |key, value|
75
- if key == EXCLUDE_PATHS_KEY
75
+ case key
76
+ when EXCLUDE_PATHS_KEY
76
77
  excluded_paths.add value
77
- elsif key == DIRECTORIES_KEY
78
+ when DIRECTORIES_KEY
78
79
  directory_directives.add value
79
- elsif key == DETECTORS_KEY
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.keys.each do |detector|
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.keys.each do |directory|
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 { |pathname| source_base_dir.to_s.match(glob_to_regexp(pathname.to_s)) }.
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
@@ -14,7 +14,8 @@ module Reek
14
14
  # @param paths [String]
15
15
  # @return [undefined]
16
16
  def add(paths)
17
- paths.each { |path| self << Pathname(path) }
17
+ paths.flat_map { |path| Dir[path] }.
18
+ each { |path| self << Pathname(path) }
18
19
  end
19
20
  end
20
21
  end
@@ -51,7 +51,7 @@ module Reek
51
51
  # @return [Enumerator]
52
52
  #
53
53
  def each(&block)
54
- return enum_for(:each) unless block_given?
54
+ return enum_for(:each) unless block
55
55
 
56
56
  yield self
57
57
  children.each do |child|
@@ -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| [:casgn, :class, :module].include? child.type }
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
@@ -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: 31 }
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
- process(exp)
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 dependant on your exact architecture, but looking at the example above what you could do is:
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.