reek 4.5.0 → 4.6.0
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/.rubocop.yml +10 -7
- data/.travis.yml +13 -9
- data/CHANGELOG.md +36 -3
- data/Dockerfile +6 -5
- data/Gemfile +8 -7
- data/README.md +45 -27
- data/docs/How-To-Write-New-Detectors.md +6 -6
- data/docs/Irresponsible-Module.md +8 -1
- data/docs/Nil-Check.md +1 -1
- data/docs/Prima-Donna-Method.md +27 -0
- data/docs/RSpec-matchers.md +5 -10
- data/docs/Unused-Private-Method.md +27 -0
- data/docs/templates/default/docstring/setup.rb +1 -8
- data/features/command_line_interface/options.feature +5 -1
- data/features/command_line_interface/stdin.feature +1 -1
- data/features/configuration_files/exclude_paths_directives.feature +43 -0
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +44 -0
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +15 -0
- data/features/samples.feature +3 -8
- data/features/step_definitions/reek_steps.rb +5 -5
- data/features/todo_list.feature +1 -2
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/arguments.rb +0 -5
- data/lib/reek/ast/sexp_extensions/constant.rb +1 -0
- data/lib/reek/cli/application.rb +7 -8
- data/lib/reek/cli/command/report_command.rb +3 -1
- data/lib/reek/cli/options.rb +29 -13
- data/lib/reek/cli/status.rb +10 -0
- data/lib/reek/code_comment.rb +48 -6
- data/lib/reek/configuration/configuration_file_finder.rb +87 -27
- data/lib/reek/context/ghost_context.rb +1 -2
- data/lib/reek/context_builder.rb +26 -1
- data/lib/reek/detector_repository.rb +64 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +37 -0
- data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -1
- data/lib/reek/errors/base_error.rb +9 -0
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -1
- data/lib/reek/errors/incomprehensible_source_error.rb +47 -0
- data/lib/reek/errors/parse_error.rb +19 -0
- data/lib/reek/examiner.rb +17 -41
- data/lib/reek/logging_error_handler.rb +15 -0
- data/lib/reek/report/code_climate/code_climate_configuration.rb +12 -0
- data/lib/reek/report/code_climate/code_climate_configuration.yml +156 -0
- data/lib/reek/report/code_climate/code_climate_fingerprint.rb +4 -2
- data/lib/reek/report/code_climate/code_climate_formatter.rb +2 -2
- data/lib/reek/smell_configuration.rb +64 -0
- data/lib/reek/smell_detectors/attribute.rb +0 -2
- data/lib/reek/smell_detectors/base_detector.rb +24 -4
- data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
- data/lib/reek/smell_detectors/class_variable.rb +0 -1
- data/lib/reek/smell_detectors/control_parameter.rb +0 -1
- data/lib/reek/smell_detectors/data_clump.rb +0 -1
- data/lib/reek/smell_detectors/duplicate_method_call.rb +0 -1
- data/lib/reek/smell_detectors/feature_envy.rb +0 -1
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +0 -1
- data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
- data/lib/reek/smell_detectors/long_parameter_list.rb +0 -2
- data/lib/reek/smell_detectors/long_yield_list.rb +0 -1
- data/lib/reek/smell_detectors/manual_dispatch.rb +4 -6
- data/lib/reek/smell_detectors/module_initialize.rb +5 -8
- data/lib/reek/smell_detectors/nested_iterators.rb +0 -1
- data/lib/reek/smell_detectors/nil_check.rb +0 -1
- data/lib/reek/smell_detectors/prima_donna_method.rb +30 -1
- data/lib/reek/smell_detectors/repeated_conditional.rb +0 -1
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
- data/lib/reek/smell_detectors/too_many_constants.rb +0 -1
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +0 -1
- data/lib/reek/smell_detectors/too_many_methods.rb +0 -1
- data/lib/reek/smell_detectors/too_many_statements.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +0 -1
- data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
- data/lib/reek/smell_detectors/unused_private_method.rb +0 -2
- data/lib/reek/smell_detectors/utility_function.rb +0 -1
- data/lib/reek/smell_warning.rb +85 -0
- data/lib/reek/source/source_code.rb +2 -1
- data/lib/reek/source/source_locator.rb +15 -3
- data/lib/reek/spec/should_reek_of.rb +1 -1
- data/lib/reek/spec.rb +6 -4
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +1 -1
- data/samples/configuration/more_than_one_configuration_file/todo.reek +0 -0
- data/samples/configuration/single_configuration_file/.reek +0 -0
- data/spec/factories/factories.rb +2 -10
- data/spec/quality/reek_source_spec.rb +5 -3
- data/spec/reek/ast/reference_collector_spec.rb +0 -17
- data/spec/reek/cli/application_spec.rb +25 -1
- data/spec/reek/cli/command/report_command_spec.rb +2 -2
- data/spec/reek/cli/command/todo_list_command_spec.rb +14 -71
- data/spec/reek/cli/options_spec.rb +4 -0
- data/spec/reek/code_comment_spec.rb +47 -0
- data/spec/reek/configuration/configuration_file_finder_spec.rb +38 -15
- data/spec/reek/context/code_context_spec.rb +10 -10
- data/spec/reek/context/method_context_spec.rb +1 -1
- data/spec/reek/context/module_context_spec.rb +8 -4
- data/spec/reek/{smell_detectors/detector_repository_spec.rb → detector_repository_spec.rb} +3 -3
- data/spec/reek/examiner_spec.rb +39 -40
- data/spec/reek/logging_error_handler_spec.rb +24 -0
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +24 -0
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +9 -9
- data/spec/reek/report/yaml_report_spec.rb +4 -4
- data/spec/reek/{smell_detectors/smell_configuration_spec.rb → smell_configuration_spec.rb} +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +18 -0
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +2 -2
- data/spec/reek/smell_detectors/feature_envy_spec.rb +18 -8
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +13 -0
- data/spec/reek/smell_detectors/module_initialize_spec.rb +23 -2
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
- data/spec/reek/smell_detectors/prima_donna_method_spec.rb +12 -0
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -5
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +2 -2
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +1 -1
- data/spec/reek/{smell_detectors/smell_warning_spec.rb → smell_warning_spec.rb} +9 -9
- data/spec/reek/source/source_code_spec.rb +6 -29
- data/spec/reek/source/source_locator_spec.rb +48 -16
- data/spec/reek/spec/should_reek_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +4 -4
- data/spec/spec_helper.rb +4 -3
- data/tasks/configuration.rake +2 -2
- metadata +26 -14
- data/lib/reek/smell_detectors/detector_repository.rb +0 -66
- data/lib/reek/smell_detectors/smell_configuration.rb +0 -66
- data/lib/reek/smell_detectors/smell_warning.rb +0 -88
- data/tasks/mutant.rake +0 -14
- /data/samples/configuration/{.reek → more_than_one_configuration_file/regular.reek} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c827e3718e3a4f1524fdaf0d6c28df6e86b671b
|
|
4
|
+
data.tar.gz: 9755661abe970fb1499ee2b9de2f6d701b8c8ee2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77122032bb96bbd32994195c9745acc214ecfbfff7963348aff01239402deefb74032883eed3762df8eda34c6054447a5ca076dfe707a9a1460a5c14bc85ddf7
|
|
7
|
+
data.tar.gz: e86a819d479502f6f091c6d6f8b7d1b6c1aae20779131a3e6e62445eb048db3f1f0e1226b59a0b11ca82e9f3c4471578ce4c71c19d0a1fdff96b51f8f5e7d752
|
data/.rubocop.yml
CHANGED
|
@@ -8,6 +8,15 @@ AllCops:
|
|
|
8
8
|
- 'vendor/**/*'
|
|
9
9
|
TargetRubyVersion: 2.1
|
|
10
10
|
|
|
11
|
+
Lint/HandleExceptions:
|
|
12
|
+
Exclude:
|
|
13
|
+
- 'spec/reek/configuration/configuration_file_finder_spec.rb'
|
|
14
|
+
|
|
15
|
+
# Spec blocks can be any size
|
|
16
|
+
Metrics/BlockLength:
|
|
17
|
+
Exclude:
|
|
18
|
+
- 'spec/**/*'
|
|
19
|
+
|
|
11
20
|
# FIXME: Make the class shorter
|
|
12
21
|
Metrics/ClassLength:
|
|
13
22
|
Exclude:
|
|
@@ -64,16 +73,10 @@ RSpec/NestedGroups:
|
|
|
64
73
|
Exclude:
|
|
65
74
|
- 'spec/reek/cli/application_spec.rb'
|
|
66
75
|
|
|
67
|
-
# FIXME: Update specs to avoid offenses
|
|
68
|
-
RSpec/VerifiedDoubles:
|
|
69
|
-
Exclude:
|
|
70
|
-
- 'spec/reek/context/code_context_spec.rb'
|
|
71
|
-
- 'spec/reek/context/method_context_spec.rb'
|
|
72
|
-
- 'spec/reek/context/module_context_spec.rb'
|
|
73
|
-
|
|
74
76
|
# rubocop-rspec expects a CodeClimate namespace to go with the code_climate directory.
|
|
75
77
|
RSpec/FilePath:
|
|
76
78
|
Exclude:
|
|
79
|
+
- 'spec/reek/report/code_climate/code_climate_configuration_spec.rb'
|
|
77
80
|
- 'spec/reek/report/code_climate/code_climate_fingerprint_spec.rb'
|
|
78
81
|
- 'spec/reek/report/code_climate/code_climate_formatter_spec.rb'
|
|
79
82
|
- 'spec/reek/report/code_climate/code_climate_report_spec.rb'
|
data/.travis.yml
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
sudo: false
|
|
2
|
+
dist: trusty
|
|
2
3
|
cache: bundler
|
|
3
4
|
language: ruby
|
|
4
5
|
bundler_args: --without debugging
|
|
@@ -6,21 +7,24 @@ script: bundle exec rake ci
|
|
|
6
7
|
rvm:
|
|
7
8
|
- 2.1
|
|
8
9
|
- 2.2
|
|
9
|
-
- 2.3
|
|
10
|
-
-
|
|
10
|
+
- 2.3
|
|
11
|
+
- 2.4
|
|
12
|
+
- jruby-9.1.7.0
|
|
13
|
+
- jruby-head
|
|
11
14
|
- ruby-head
|
|
15
|
+
- rubinius-3
|
|
12
16
|
matrix:
|
|
13
|
-
include:
|
|
14
|
-
- rvm: jruby
|
|
15
|
-
env: JRUBY_OPTS='--2.0 --server -Xcompile.invokedynamic=false'
|
|
16
|
-
- rvm: jruby-head
|
|
17
|
-
env: JRUBY_OPTS='--server -Xcompile.invokedynamic=false'
|
|
18
17
|
allow_failures:
|
|
19
|
-
- rvm: jruby
|
|
18
|
+
- rvm: jruby-9.1.7.0
|
|
20
19
|
- rvm: jruby-head
|
|
21
|
-
- rvm: rbx-2
|
|
22
20
|
- rvm: ruby-head
|
|
21
|
+
- rvm: rubinius-3
|
|
23
22
|
fast_finish: true
|
|
23
|
+
before_install:
|
|
24
|
+
- rvm use @global
|
|
25
|
+
- gem uninstall bundler -x
|
|
26
|
+
- gem install bundler --version=1.13.7
|
|
27
|
+
- bundler --version
|
|
24
28
|
notifications:
|
|
25
29
|
email:
|
|
26
30
|
- timo.roessner@googlemail.com
|
data/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## 4.6.0 (2017-04-04)
|
|
4
|
+
|
|
5
|
+
* (IanWhitney) Implement `--force-exclusion` flag
|
|
6
|
+
* (mvz) Raise Reek-specific error on parse errors
|
|
7
|
+
|
|
8
|
+
## 4.5.6 (2017-02-17)
|
|
9
|
+
|
|
10
|
+
* (mvz) Raise on errors inside of Examiner#smells instead of outputting to STDERR
|
|
11
|
+
* (mvz) Update parser dependency
|
|
12
|
+
|
|
13
|
+
## 4.5.5 (2017-02-05)
|
|
14
|
+
|
|
15
|
+
* (mvz) Load YAML in code comments safely
|
|
16
|
+
* (mvz) Combine lines for manual dispatch smells
|
|
17
|
+
* (mvz) Respect exclude_paths when passing sources on the command line
|
|
18
|
+
* (mvz) Ensure explicit arguments of super() are processed
|
|
19
|
+
|
|
20
|
+
## 4.5.4 (2017-01-17)
|
|
21
|
+
|
|
22
|
+
* (troessner) Improve documentation and fix PrimaDonnaMethod detector configuration via comment.
|
|
23
|
+
|
|
24
|
+
## 4.5.3 (2016-12-05)
|
|
25
|
+
|
|
26
|
+
* (jhubert) Stop reporting FeatureEnvy with super and arguments.
|
|
27
|
+
|
|
28
|
+
## 4.5.2 (2016-11-06)
|
|
29
|
+
|
|
30
|
+
* (troessner) Warn about multiple configuration files.
|
|
31
|
+
|
|
32
|
+
## 4.5.1 (2016-10-16)
|
|
33
|
+
|
|
34
|
+
* (troessner) Validate configuration keys in code comments.
|
|
35
|
+
|
|
3
36
|
## 4.5.0 (2016-10-12)
|
|
4
37
|
|
|
5
|
-
* (maxjacobson) Emit fingerprints in Code Climate reporter
|
|
6
|
-
* (mvz) Disable progress for piped output
|
|
7
|
-
* (mvz) Update progress formatter to match changed file location
|
|
8
38
|
* (jhubert) Add progress formatters for showing progress on each file
|
|
39
|
+
* (mvz) Update progress formatter to match changed file location
|
|
40
|
+
* (mvz) Disable progress for piped output
|
|
41
|
+
* (maxjacobson) Emit fingerprints in Code Climate reporter
|
|
9
42
|
|
|
10
43
|
## 4.4.4 (2016-09-29)
|
|
11
44
|
|
data/Dockerfile
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Build and run via:
|
|
4
4
|
# docker build -t codeclimate/codeclimate-reek . && docker run codeclimate/codeclimate-reek
|
|
5
5
|
|
|
6
|
-
FROM
|
|
6
|
+
FROM ruby:2.3.3-alpine
|
|
7
7
|
|
|
8
8
|
MAINTAINER The Reek core team
|
|
9
9
|
|
|
@@ -12,17 +12,18 @@ ENV app_dir /usr/src/app
|
|
|
12
12
|
ENV user app
|
|
13
13
|
|
|
14
14
|
RUN apk --update add git
|
|
15
|
-
|
|
16
15
|
ADD . ${app_dir}
|
|
17
16
|
|
|
17
|
+
RUN adduser -u 9000 -D ${user}
|
|
18
|
+
RUN chown -R ${user}:${user} ${app_dir}
|
|
19
|
+
USER ${user}
|
|
20
|
+
|
|
18
21
|
WORKDIR ${app_dir}
|
|
19
22
|
|
|
23
|
+
RUN gem install rake
|
|
20
24
|
RUN bundle install --without debugging development
|
|
21
|
-
RUN adduser -u 9000 -D ${user}
|
|
22
|
-
RUN chown -R ${user}:${user} ${app_dir}
|
|
23
25
|
|
|
24
26
|
VOLUME ${code_dir}
|
|
25
27
|
WORKDIR ${code_dir}
|
|
26
|
-
USER ${user}
|
|
27
28
|
|
|
28
29
|
CMD [ "/usr/src/app/bin/code_climate_reek" ]
|
data/Gemfile
CHANGED
|
@@ -2,25 +2,26 @@ source 'https://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
|
+
ruby RUBY_VERSION
|
|
6
|
+
|
|
5
7
|
group :development do
|
|
8
|
+
gem 'activesupport', '>= 4.2'
|
|
6
9
|
gem 'aruba', '~> 0.14.0'
|
|
7
10
|
gem 'ataru', '~> 0.2.0'
|
|
8
11
|
gem 'cucumber', '~> 2.0'
|
|
9
12
|
gem 'factory_girl', '~> 4.0'
|
|
10
|
-
gem '
|
|
11
|
-
gem 'rake', '~> 11.1'
|
|
13
|
+
gem 'rake', '~> 12.0'
|
|
12
14
|
gem 'rspec', '~> 3.0'
|
|
13
|
-
gem 'simplecov', '~> 0.
|
|
15
|
+
gem 'simplecov', '~> 0.14.0'
|
|
14
16
|
gem 'yard', '~> 0.9.5'
|
|
15
|
-
gem 'activesupport', '~> 4.2'
|
|
16
17
|
|
|
17
18
|
if RUBY_VERSION >= '2.3'
|
|
18
|
-
gem 'rubocop', '~> 0.
|
|
19
|
-
gem 'rubocop-rspec', '~> 1.
|
|
19
|
+
gem 'rubocop', '~> 0.47.1'
|
|
20
|
+
gem 'rubocop-rspec', '~> 1.13.0'
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
platforms :mri do
|
|
23
|
-
gem 'redcarpet', '~> 3.
|
|
24
|
+
gem 'redcarpet', '~> 3.4.0'
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
|
data/README.md
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
- [Configuration file](#configuration-file)
|
|
17
17
|
- [Configuration loading](#configuration-loading)
|
|
18
18
|
- [Configuration options](#configuration-options)
|
|
19
|
-
- [Source code comments](#source-code-comments)
|
|
20
19
|
- [Generating a 'todo' list](#generating-a-todo-list)
|
|
20
|
+
- [Beware of multiple configuration files](#beware-of-multiple-configuration-files)
|
|
21
|
+
- [Source code comments](#source-code-comments)
|
|
21
22
|
- [Usage](#usage)
|
|
22
23
|
- [Developing Reek / Contributing](#developing-reek--contributing)
|
|
23
24
|
- [Output formats](#output-formats)
|
|
@@ -355,30 +356,6 @@ configurations you can also check out [the `default.reek` file in this repositor
|
|
|
355
356
|
Note that you do not need a configuration file at all.
|
|
356
357
|
If you're fine with all the [defaults](defaults.reek) we set you can skip this completely.
|
|
357
358
|
|
|
358
|
-
### Source code comments
|
|
359
|
-
|
|
360
|
-
In case you need to suppress a smell warning and you can't or don't want to
|
|
361
|
-
use configuration files for whatever reasons you can also use special
|
|
362
|
-
source code comments like this:
|
|
363
|
-
|
|
364
|
-
```Ruby
|
|
365
|
-
# This method smells of :reek:NestedIterators
|
|
366
|
-
def smelly_method foo
|
|
367
|
-
foo.each {|bar| bar.each {|baz| baz.qux}}
|
|
368
|
-
end
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
You can even pass in smell specific configuration settings:
|
|
372
|
-
|
|
373
|
-
```Ruby
|
|
374
|
-
# :reek:NestedIterators { max_allowed_nesting: 2 }
|
|
375
|
-
def smelly_method foo
|
|
376
|
-
foo.each {|bar| bar.each {|baz| baz.qux}}
|
|
377
|
-
end
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
This is an incredible powerful feature and further explained under [Smell Suppresion](docs/Smell-Suppression.md).
|
|
381
|
-
|
|
382
359
|
### Generating a 'todo' list
|
|
383
360
|
|
|
384
361
|
Integrating tools like Reek into an existing larger codebase can be daunting when you have to fix
|
|
@@ -425,6 +402,42 @@ reek -c other_configuration.reek --todo lib/
|
|
|
425
402
|
`other_configuration.reek` will simply be ignored (as outlined before, Reek
|
|
426
403
|
is supposed to have one configuration file and one file only).
|
|
427
404
|
|
|
405
|
+
### Beware of multiple configuration files
|
|
406
|
+
|
|
407
|
+
Reek takes one configuration file and one configuration file only.
|
|
408
|
+
|
|
409
|
+
If you have more than one configuration file in the same directory Reek
|
|
410
|
+
will not know what configuration file to use. If this happens Reek will
|
|
411
|
+
print a warning on STDERR and exit with the failure exit status 1.
|
|
412
|
+
|
|
413
|
+
In case you have to have one or more configuration files in the directory (e.g. you're
|
|
414
|
+
toying around with different, mutually exclusive settings) you need to tell Reek
|
|
415
|
+
explicitly which file to use via `reek -c config.reek`.
|
|
416
|
+
|
|
417
|
+
### Source code comments
|
|
418
|
+
|
|
419
|
+
In case you need to suppress a smell warning and you can't or don't want to
|
|
420
|
+
use configuration files for whatever reasons you can also use special
|
|
421
|
+
source code comments like this:
|
|
422
|
+
|
|
423
|
+
```Ruby
|
|
424
|
+
# This method smells of :reek:NestedIterators
|
|
425
|
+
def smelly_method foo
|
|
426
|
+
foo.each {|bar| bar.each {|baz| baz.qux}}
|
|
427
|
+
end
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
You can even pass in smell specific configuration settings:
|
|
431
|
+
|
|
432
|
+
```Ruby
|
|
433
|
+
# :reek:NestedIterators { max_allowed_nesting: 2 }
|
|
434
|
+
def smelly_method foo
|
|
435
|
+
foo.each {|bar| bar.each {|baz| baz.qux}}
|
|
436
|
+
end
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
This is an incredible powerful feature and further explained under [Smell Suppresion](docs/Smell-Suppression.md).
|
|
440
|
+
|
|
428
441
|
## Usage
|
|
429
442
|
|
|
430
443
|
Besides the obvious
|
|
@@ -462,7 +475,7 @@ Or just run the whole test suite:
|
|
|
462
475
|
bundle exec rake
|
|
463
476
|
```
|
|
464
477
|
|
|
465
|
-
This will run the
|
|
478
|
+
This will run the RSpec tests, RuboCop and Reek itself.
|
|
466
479
|
|
|
467
480
|
You can also run:
|
|
468
481
|
|
|
@@ -470,7 +483,9 @@ You can also run:
|
|
|
470
483
|
bundle exec rake ci
|
|
471
484
|
```
|
|
472
485
|
|
|
473
|
-
This will run everything the default task runs and also
|
|
486
|
+
This will run everything the default task runs and also
|
|
487
|
+
our Cucumber features and [Ataru](https://github.com/CodePadawans/ataru). This is the task that we run on
|
|
488
|
+
Travis as well and that determines if your pull request is green or red.
|
|
474
489
|
|
|
475
490
|
Another useful Rake task is the `console` task. This will throw you right into an environment where you can play around with Reeks modules and classes:
|
|
476
491
|
|
|
@@ -542,6 +557,9 @@ Just add this to your configuration file:
|
|
|
542
557
|
enabled: false
|
|
543
558
|
UtilityFunction:
|
|
544
559
|
enabled: false
|
|
560
|
+
"app/mailers":
|
|
561
|
+
InstanceVariableAssumption:
|
|
562
|
+
enabled: false
|
|
545
563
|
```
|
|
546
564
|
|
|
547
565
|
Be careful though, Reek does not merge your configuration entries, so if you already have a directory directive for "app/controllers" or "app/helpers" you need to update those directives instead of copying the above YAML sample into your configuration file.
|
|
@@ -9,19 +9,19 @@ it covers and the overall rationale behind it.
|
|
|
9
9
|
|
|
10
10
|
### Structure
|
|
11
11
|
|
|
12
|
-
All smell detectors reside in `lib/reek/
|
|
12
|
+
All smell detectors reside in `lib/reek/smell_detectors` and have the following base structure:
|
|
13
13
|
|
|
14
14
|
```Ruby
|
|
15
|
-
require_relative '
|
|
15
|
+
require_relative 'base_detector'
|
|
16
16
|
require_relative 'smell_warning'
|
|
17
17
|
|
|
18
18
|
module Reek
|
|
19
|
-
module
|
|
19
|
+
module SmellDetectors
|
|
20
20
|
#
|
|
21
21
|
# Here goes your introduction for this detector.
|
|
22
22
|
#
|
|
23
23
|
# See {file:docs/Your-Detector.md} for details.
|
|
24
|
-
class YourDetector <
|
|
24
|
+
class YourDetector < BaseDetector
|
|
25
25
|
def self.contexts
|
|
26
26
|
[:class] # In case you're operating on class contexts only - just an example.
|
|
27
27
|
end
|
|
@@ -37,7 +37,7 @@ module Reek
|
|
|
37
37
|
# This can just be a method but it can also be a more sophisticated set up.
|
|
38
38
|
# Check out other smell detectors to get a feeling for what to do here.
|
|
39
39
|
found_smells(ctx).map do |smell|
|
|
40
|
-
# "smell_warning" is defined in
|
|
40
|
+
# "smell_warning" is defined in BaseDetector and should be used by you
|
|
41
41
|
# to construct smell warnings
|
|
42
42
|
smell_warning(
|
|
43
43
|
context: ctx,
|
|
@@ -59,7 +59,7 @@ module Reek
|
|
|
59
59
|
end
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
For your detector to be properly loaded you need to require it in `lib/reek/
|
|
62
|
+
For your detector to be properly loaded you need to require it in `lib/reek/smell_detectors.rb` as well.
|
|
63
63
|
|
|
64
64
|
### defaults.reek
|
|
65
65
|
|
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
Classes and modules are the units of reuse and release. It is therefore
|
|
5
|
+
Classes and modules are the units of reuse and release. It is therefore
|
|
6
|
+
considered good practice to annotate every class and module with a brief
|
|
7
|
+
comment outlining its responsibilities.
|
|
8
|
+
|
|
9
|
+
For further guideline on how to write good documentation in Ruby, see these
|
|
10
|
+
links:
|
|
11
|
+
- [Rails API documentation guidelines](http://edgeguides.rubyonrails.org/api_documentation_guidelines.html)
|
|
12
|
+
- [Comments tell you why](https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/)
|
|
6
13
|
|
|
7
14
|
## Example
|
|
8
15
|
|
data/docs/Nil-Check.md
CHANGED
data/docs/Prima-Donna-Method.md
CHANGED
|
@@ -61,3 +61,30 @@ method `foo` of the `Dangerous` module.
|
|
|
61
61
|
## Configuration
|
|
62
62
|
|
|
63
63
|
_Prima Donna Method_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
|
64
|
+
|
|
65
|
+
## Example configuration via source comment
|
|
66
|
+
|
|
67
|
+
Imagine code like this:
|
|
68
|
+
|
|
69
|
+
```Ruby
|
|
70
|
+
class Alfa
|
|
71
|
+
def bravo!
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This would report:
|
|
77
|
+
|
|
78
|
+
>>
|
|
79
|
+
ruby.rb -- 1 warning:
|
|
80
|
+
[1]:PrimaDonnaMethod: Alfa has prima donna method 'bravo!'
|
|
81
|
+
|
|
82
|
+
If you want to suppress this warning you can do this via source comment like this:
|
|
83
|
+
|
|
84
|
+
```Ruby
|
|
85
|
+
# :reek:PrimaDonnaMethod: { exclude: [ bravo! ] }
|
|
86
|
+
class Alfa
|
|
87
|
+
def bravo!
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
```
|
data/docs/RSpec-matchers.md
CHANGED
|
@@ -74,15 +74,10 @@ See the "Quickstart" example from above.
|
|
|
74
74
|
Checks the target source code for instances of "smell type"
|
|
75
75
|
and returns true only if it can find one of them that matches.
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
"smell type" UtilityFunction, which is represented as a concrete class
|
|
79
|
-
in Reek but it could also be "Duplication" which is a "smell categgory".
|
|
77
|
+
You can pass the smell type you want to check for as String or as Symbol:
|
|
80
78
|
|
|
81
|
-
You could pass many different types of input here:
|
|
82
79
|
- `:UtilityFunction`
|
|
83
80
|
- `"UtilityFunction"`
|
|
84
|
-
- `Reek::Smells::UtilityFunction` (the right way if you really want to pass a
|
|
85
|
-
class)
|
|
86
81
|
|
|
87
82
|
It is recommended to pass this as a symbol like `:UtilityFunction`. However we
|
|
88
83
|
don't enforce this.
|
|
@@ -106,20 +101,20 @@ So in a nutshell `reek_of` takes the following two arguments:
|
|
|
106
101
|
|
|
107
102
|
```Ruby
|
|
108
103
|
reek_of(:FeatureEnvy)
|
|
109
|
-
reek_of(
|
|
104
|
+
reek_of(:UtilityFunction)
|
|
110
105
|
```
|
|
111
106
|
|
|
112
107
|
With smell_details:
|
|
113
108
|
|
|
114
109
|
```Ruby
|
|
115
|
-
reek_of(UncommunicativeParameterName, name: 'x2')
|
|
116
|
-
reek_of(DataClump, count: 3)
|
|
110
|
+
reek_of(:UncommunicativeParameterName, name: 'x2')
|
|
111
|
+
reek_of(:DataClump, count: 3)
|
|
117
112
|
```
|
|
118
113
|
|
|
119
114
|
**Examples from a real spec**
|
|
120
115
|
|
|
121
116
|
```Ruby
|
|
122
|
-
expect(src).to reek_of(
|
|
117
|
+
expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
|
|
123
118
|
```
|
|
124
119
|
|
|
125
120
|
### reek_only_of
|
|
@@ -48,6 +48,33 @@ end
|
|
|
48
48
|
Note that disabling this detector via comment works on a class scope, not
|
|
49
49
|
a method scope (like you can see above).
|
|
50
50
|
|
|
51
|
+
Another simple example would be:
|
|
52
|
+
|
|
53
|
+
```Ruby
|
|
54
|
+
class Alfa
|
|
55
|
+
private
|
|
56
|
+
def bravo
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This would report:
|
|
62
|
+
|
|
63
|
+
>>
|
|
64
|
+
ruby.rb -- 1 warning:
|
|
65
|
+
[3]:UnusedPrivateMethod: Alfa has the unused private instance method 'bravo'
|
|
66
|
+
|
|
67
|
+
If you want to suppress this warning you can do this via source comment like this:
|
|
68
|
+
|
|
69
|
+
```Ruby
|
|
70
|
+
# :reek:UnusedPrivateMethod: { exclude: bravo }
|
|
71
|
+
class Alfa
|
|
72
|
+
private
|
|
73
|
+
def bravo
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
51
78
|
## Known limitations
|
|
52
79
|
|
|
53
80
|
* Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
|
|
@@ -10,14 +10,7 @@ end
|
|
|
10
10
|
|
|
11
11
|
def api_marker
|
|
12
12
|
return if object.type == :root
|
|
13
|
-
|
|
14
|
-
when 'public'
|
|
15
|
-
# erb(:public_api_marker)
|
|
16
|
-
when 'private'
|
|
17
|
-
# Let section 'private' handle this.
|
|
18
|
-
else
|
|
19
|
-
erb(:private)
|
|
20
|
-
end
|
|
13
|
+
erb(:private) unless ['public', 'private'].include? api_text
|
|
21
14
|
end
|
|
22
15
|
|
|
23
16
|
private
|
|
@@ -41,7 +41,9 @@ Feature: Reek can be controlled using command-line options
|
|
|
41
41
|
|
|
42
42
|
Configuration:
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
|
44
|
-
--smell SMELL
|
|
44
|
+
--smell SMELL Only look for a specific smell.
|
|
45
|
+
Call it like this: reek --smell PrimaDonnaMethod source.rb
|
|
46
|
+
Check out https://github.com/troessner/reek/blob/master/docs/Code-Smells.md for a list of smells
|
|
45
47
|
|
|
46
48
|
Generate a todo list:
|
|
47
49
|
-t, --todo Generate a todo list
|
|
@@ -65,6 +67,8 @@ Feature: Reek can be controlled using command-line options
|
|
|
65
67
|
--sort-by SORTING Sort reported files by the given criterium:
|
|
66
68
|
smelliness ("smelliest" files first)
|
|
67
69
|
none (default - output in processing order)
|
|
70
|
+
--force-exclusion Force excluding files specified in the configuration `exclude_paths`
|
|
71
|
+
even if they are explicitly passed as arguments
|
|
68
72
|
|
|
69
73
|
Exit codes:
|
|
70
74
|
--success-exit-code CODE The exit code when no smells are found (default: 0)
|
|
@@ -35,5 +35,5 @@ Feature: Reek reads from $stdin when no files are given
|
|
|
35
35
|
Scenario: syntax error causes the source to be ignored
|
|
36
36
|
When I pass "= invalid syntax =" to reek
|
|
37
37
|
Then it reports a parsing error
|
|
38
|
-
|
|
38
|
+
And the exit status indicates an error
|
|
39
39
|
And it reports nothing
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Feature: Exclude paths directives
|
|
2
|
+
In order to avoid Reek wasting time on files that cannot be fixed
|
|
3
|
+
As a user
|
|
4
|
+
I want to be able to exclude specific paths from being checked
|
|
5
|
+
|
|
6
|
+
Scenario: Exclude some paths
|
|
7
|
+
Given a file named "bad_files_live_here/smelly.rb" with:
|
|
8
|
+
"""
|
|
9
|
+
# A smelly example class
|
|
10
|
+
class Smelly
|
|
11
|
+
def alfa(bravo); end
|
|
12
|
+
end
|
|
13
|
+
"""
|
|
14
|
+
When I run `reek .`
|
|
15
|
+
Then the exit status indicates smells
|
|
16
|
+
Given a file named "config.reek" with:
|
|
17
|
+
"""
|
|
18
|
+
---
|
|
19
|
+
exclude_paths:
|
|
20
|
+
- bad_files_live_here
|
|
21
|
+
"""
|
|
22
|
+
When I run `reek -c config.reek .`
|
|
23
|
+
Then it succeeds
|
|
24
|
+
And it reports nothing
|
|
25
|
+
Scenario: Using a file name within an excluded directory
|
|
26
|
+
Given a file named "bad_files_live_here/smelly.rb" with:
|
|
27
|
+
"""
|
|
28
|
+
# A smelly example class
|
|
29
|
+
class Smelly
|
|
30
|
+
def alfa(bravo); end
|
|
31
|
+
end
|
|
32
|
+
"""
|
|
33
|
+
And a file named "config.reek" with:
|
|
34
|
+
"""
|
|
35
|
+
---
|
|
36
|
+
exclude_paths:
|
|
37
|
+
- bad_files_live_here
|
|
38
|
+
"""
|
|
39
|
+
When I run `reek -c config.reek bad_files_live_here/smelly.rb`
|
|
40
|
+
Then the exit status indicates smells
|
|
41
|
+
When I run `reek -c config.reek --force-exclusion bad_files_live_here/smelly.rb`
|
|
42
|
+
Then it succeeds
|
|
43
|
+
And it reports nothing
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Feature: Warn on multiple configuration files
|
|
2
|
+
Reek is designed for one configuration file and for one configuration file only.
|
|
3
|
+
We should make this clear to the user by warning him when we detect multiple
|
|
4
|
+
configuration files and then exiting the program.
|
|
5
|
+
|
|
6
|
+
Scenario: Warn on more than one configuration file
|
|
7
|
+
Given the smelly file 'smelly.rb'
|
|
8
|
+
And a file named "config.reek" with:
|
|
9
|
+
"""
|
|
10
|
+
---
|
|
11
|
+
UncommunicativeMethodName:
|
|
12
|
+
enabled: false
|
|
13
|
+
"""
|
|
14
|
+
And a file named ".todo.reek" with:
|
|
15
|
+
"""
|
|
16
|
+
---
|
|
17
|
+
UtilityFunction:
|
|
18
|
+
enabled: false
|
|
19
|
+
"""
|
|
20
|
+
When I run reek smelly.rb
|
|
21
|
+
Then it reports the error "Error: Found multiple configuration files '.todo.reek', 'config.reek'"
|
|
22
|
+
And it reports the error "Reek supports only one configuration file. You have 2 options now:"
|
|
23
|
+
And it reports the error "1) Remove all offending files"
|
|
24
|
+
And it reports the error "2) Be specific about which one you want to load via the -c switch"
|
|
25
|
+
And the exit status indicates an error
|
|
26
|
+
|
|
27
|
+
Scenario: Do not warn on more than one when we explicitly specify one configuration file
|
|
28
|
+
Given the smelly file 'smelly.rb'
|
|
29
|
+
And a file named "config.reek" with:
|
|
30
|
+
"""
|
|
31
|
+
---
|
|
32
|
+
UncommunicativeMethodName:
|
|
33
|
+
enabled: false
|
|
34
|
+
"""
|
|
35
|
+
And a file named ".todo.reek" with:
|
|
36
|
+
"""
|
|
37
|
+
---
|
|
38
|
+
UtilityFunction:
|
|
39
|
+
enabled: false
|
|
40
|
+
"""
|
|
41
|
+
When I run reek -c config.reek smelly.rb
|
|
42
|
+
Then the exit status indicates smells
|
|
43
|
+
And it reports no errors
|
|
44
|
+
|
|
@@ -51,3 +51,18 @@ Feature: Erroneous source comments are handled properly
|
|
|
51
51
|
And it reports the error "Unfortunately we can not parse the configuration you have given."
|
|
52
52
|
And it reports the error "The source is 'bad_comment.rb'"
|
|
53
53
|
And it reports the error "the comment belongs to the expression starting in line 3"
|
|
54
|
+
|
|
55
|
+
Scenario: Bad configuration key
|
|
56
|
+
Given a file named "bad_comment.rb" with:
|
|
57
|
+
"""
|
|
58
|
+
# Test class
|
|
59
|
+
# exclude -> elude and accept -> accipt are bad keys
|
|
60
|
+
# :reek:UncommunicativeMethodName { elude: 'foo', accipt: 'bar' }
|
|
61
|
+
def x
|
|
62
|
+
end
|
|
63
|
+
"""
|
|
64
|
+
When I run reek bad_comment.rb
|
|
65
|
+
Then it reports the error "Error: You are trying to configure the smell detector 'UncommunicativeMethodName'"
|
|
66
|
+
And it reports the error "in one of your source code comments with the unknown option 'elude', 'accipt'"
|
|
67
|
+
And it reports the error "The source is 'bad_comment.rb'"
|
|
68
|
+
And it reports the error "the comment belongs to the expression starting in line 4"
|