reek 4.5.1 → 5.0.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/.codeclimate.yml +17 -12
- data/.rubocop.yml +88 -33
- data/.simplecov +1 -0
- data/.travis.yml +9 -11
- data/.yardopts +1 -1
- data/CHANGELOG.md +108 -3
- data/CONTRIBUTING.md +1 -1
- data/Dockerfile +6 -5
- data/Gemfile +10 -9
- data/README.md +118 -69
- data/Rakefile +16 -3
- data/bin/code_climate_reek +1 -0
- data/bin/reek +2 -3
- data/docs/API.md +2 -9
- data/docs/Basic-Smell-Options.md +51 -11
- data/docs/Code-Smells.md +1 -1
- data/docs/Command-Line-Options.md +14 -4
- data/docs/Duplicate-Method-Call.md +49 -1
- data/docs/Feature-Envy.md +44 -0
- data/docs/How-To-Write-New-Detectors.md +13 -13
- data/docs/Instance-Variable-Assumption.md +1 -1
- data/docs/Irresponsible-Module.md +8 -1
- data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +36 -7
- data/docs/Nil-Check.md +1 -1
- data/docs/RSpec-matchers.md +5 -10
- data/docs/Rake-Task.md +1 -1
- data/docs/Reek-4-to-Reek-5-migration.md +193 -0
- data/docs/Reek-Driven-Development.md +1 -1
- data/docs/Uncommunicative-Method-Name.md +45 -6
- data/docs/Uncommunicative-Module-Name.md +49 -7
- data/docs/Uncommunicative-Parameter-Name.md +43 -5
- data/docs/Uncommunicative-Variable-Name.md +73 -2
- data/docs/Unused-Private-Method.md +30 -3
- data/docs/defaults.reek.yml +129 -0
- data/docs/templates/default/docstring/setup.rb +1 -8
- data/docs/yard_plugin.rb +1 -0
- data/features/command_line_interface/basic_usage.feature +2 -2
- data/features/command_line_interface/options.feature +49 -3
- data/features/command_line_interface/show_progress.feature +4 -4
- data/features/command_line_interface/smell_selection.feature +1 -1
- data/features/command_line_interface/smells_count.feature +6 -6
- data/features/command_line_interface/stdin.feature +30 -4
- data/features/configuration_files/accept_setting.feature +45 -28
- data/features/configuration_files/directory_specific_directives.feature +80 -75
- data/features/configuration_files/exclude_directives.feature +11 -10
- data/features/configuration_files/exclude_paths_directives.feature +43 -0
- data/features/configuration_files/masking_smells.feature +38 -9
- data/features/configuration_files/mix_accept_reject_setting.feature +31 -28
- data/features/configuration_files/reject_setting.feature +52 -41
- data/features/configuration_files/schema_validation.feature +59 -0
- data/features/configuration_files/unused_private_method.feature +18 -16
- data/features/configuration_loading.feature +53 -10
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +3 -3
- data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
- data/features/locales.feature +32 -0
- data/features/rake_task/rake_task.feature +58 -18
- data/features/reports/codeclimate.feature +59 -0
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +34 -34
- data/features/reports/yaml.feature +3 -3
- data/features/rspec_matcher.feature +40 -0
- data/features/samples.feature +290 -295
- data/features/step_definitions/reek_steps.rb +19 -7
- data/features/step_definitions/sample_file_steps.rb +9 -4
- data/features/support/env.rb +2 -11
- data/features/todo_list.feature +27 -25
- data/lib/reek/ast/ast_node_class_map.rb +1 -0
- data/lib/reek/ast/builder.rb +16 -0
- data/lib/reek/ast/node.rb +50 -58
- data/lib/reek/ast/object_refs.rb +2 -1
- data/lib/reek/ast/reference_collector.rb +4 -7
- data/lib/reek/ast/sexp_extensions/arguments.rb +1 -5
- data/lib/reek/ast/sexp_extensions/attribute_assignments.rb +1 -0
- data/lib/reek/ast/sexp_extensions/begin.rb +17 -0
- data/lib/reek/ast/sexp_extensions/block.rb +1 -0
- data/lib/reek/ast/sexp_extensions/case.rb +2 -1
- data/lib/reek/ast/sexp_extensions/constant.rb +2 -0
- data/lib/reek/ast/sexp_extensions/if.rb +9 -1
- data/lib/reek/ast/sexp_extensions/lambda.rb +1 -0
- data/lib/reek/ast/sexp_extensions/literal.rb +1 -0
- data/lib/reek/ast/sexp_extensions/logical_operators.rb +2 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +5 -6
- data/lib/reek/ast/sexp_extensions/module.rb +55 -8
- data/lib/reek/ast/sexp_extensions/nested_assignables.rb +1 -0
- data/lib/reek/ast/sexp_extensions/self.rb +1 -0
- data/lib/reek/ast/sexp_extensions/send.rb +1 -4
- data/lib/reek/ast/sexp_extensions/super.rb +1 -0
- data/lib/reek/ast/sexp_extensions/symbols.rb +1 -0
- data/lib/reek/ast/sexp_extensions/variables.rb +1 -0
- data/lib/reek/ast/sexp_extensions/when.rb +1 -0
- data/lib/reek/ast/sexp_extensions/yield.rb +1 -0
- data/lib/reek/ast/sexp_extensions.rb +2 -0
- data/lib/reek/cli/application.rb +12 -11
- data/lib/reek/cli/command/base_command.rb +1 -0
- data/lib/reek/cli/command/report_command.rb +5 -3
- data/lib/reek/cli/command/todo_list_command.rb +9 -8
- data/lib/reek/cli/options.rb +56 -24
- data/lib/reek/cli/silencer.rb +15 -3
- data/lib/reek/cli/status.rb +11 -0
- data/lib/reek/code_comment.rb +18 -18
- data/lib/reek/configuration/app_configuration.rb +34 -28
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +67 -31
- data/lib/reek/configuration/configuration_validator.rb +13 -23
- data/lib/reek/configuration/default_directive.rb +18 -3
- data/lib/reek/configuration/directory_directives.rb +18 -11
- data/lib/reek/configuration/excluded_paths.rb +2 -1
- data/lib/reek/configuration/rake_task_converter.rb +29 -0
- data/lib/reek/configuration/schema.yml +210 -0
- data/lib/reek/configuration/schema_validator.rb +38 -0
- data/lib/reek/context/attribute_context.rb +4 -3
- data/lib/reek/context/class_context.rb +1 -0
- data/lib/reek/context/code_context.rb +49 -44
- data/lib/reek/context/ghost_context.rb +1 -3
- data/lib/reek/context/method_context.rb +26 -18
- data/lib/reek/context/module_context.rb +11 -11
- data/lib/reek/context/root_context.rb +1 -4
- data/lib/reek/context/send_context.rb +3 -2
- data/lib/reek/context/singleton_attribute_context.rb +1 -0
- data/lib/reek/context/singleton_method_context.rb +1 -0
- data/lib/reek/context/statement_counter.rb +1 -0
- data/lib/reek/context/visibility_tracker.rb +1 -0
- data/lib/reek/context_builder.rb +68 -43
- data/lib/reek/detector_repository.rb +65 -0
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +17 -14
- data/lib/reek/errors/bad_detector_in_comment_error.rb +15 -12
- data/lib/reek/errors/base_error.rb +12 -0
- data/lib/reek/errors/config_file_error.rb +11 -0
- data/lib/reek/errors/encoding_error.rb +43 -0
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +16 -13
- data/lib/reek/errors/incomprehensible_source_error.rb +46 -0
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +35 -58
- data/lib/reek/logging_error_handler.rb +18 -0
- data/lib/reek/rake/task.rb +8 -5
- data/lib/reek/report/base_report.rb +9 -12
- data/lib/reek/report/code_climate/code_climate_configuration.rb +2 -1
- data/lib/reek/report/code_climate/code_climate_configuration.yml +7 -7
- data/lib/reek/report/code_climate/code_climate_fingerprint.rb +1 -0
- data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -0
- data/lib/reek/report/code_climate/code_climate_report.rb +1 -0
- data/lib/reek/report/code_climate.rb +1 -0
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/html_report.rb +1 -0
- data/lib/reek/report/json_report.rb +2 -1
- data/lib/reek/report/location_formatter.rb +40 -0
- data/lib/reek/report/progress_formatter.rb +79 -0
- data/lib/reek/report/simple_warning_formatter.rb +34 -0
- data/lib/reek/report/text_report.rb +2 -2
- data/lib/reek/report/xml_report.rb +4 -3
- data/lib/reek/report/yaml_report.rb +2 -1
- data/lib/reek/report.rb +16 -10
- data/lib/reek/smell_configuration.rb +65 -0
- data/lib/reek/smell_detectors/attribute.rb +6 -13
- data/lib/reek/smell_detectors/base_detector.rb +36 -30
- data/lib/reek/smell_detectors/boolean_parameter.rb +4 -6
- data/lib/reek/smell_detectors/class_variable.rb +6 -15
- data/lib/reek/smell_detectors/control_parameter.rb +19 -34
- data/lib/reek/smell_detectors/data_clump.rb +16 -10
- data/lib/reek/smell_detectors/duplicate_method_call.rb +24 -18
- data/lib/reek/smell_detectors/feature_envy.rb +10 -8
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +15 -24
- data/lib/reek/smell_detectors/irresponsible_module.rb +6 -13
- data/lib/reek/smell_detectors/long_parameter_list.rb +11 -9
- data/lib/reek/smell_detectors/long_yield_list.rb +11 -8
- data/lib/reek/smell_detectors/manual_dispatch.rb +7 -9
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +45 -15
- data/lib/reek/smell_detectors/module_initialize.rb +7 -11
- data/lib/reek/smell_detectors/nested_iterators.rb +17 -25
- data/lib/reek/smell_detectors/nil_check.rb +9 -16
- data/lib/reek/smell_detectors/repeated_conditional.rb +14 -12
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +8 -9
- data/lib/reek/smell_detectors/too_many_constants.rb +11 -10
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +11 -7
- data/lib/reek/smell_detectors/too_many_methods.rb +12 -8
- data/lib/reek/smell_detectors/too_many_statements.rb +11 -7
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +11 -12
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +15 -19
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +18 -23
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +27 -28
- data/lib/reek/smell_detectors/unused_parameters.rb +5 -7
- data/lib/reek/smell_detectors/unused_private_method.rb +14 -22
- data/lib/reek/smell_detectors/utility_function.rb +13 -17
- data/lib/reek/smell_detectors.rb +2 -1
- data/lib/reek/smell_warning.rb +93 -0
- data/lib/reek/source/source_code.rb +65 -45
- data/lib/reek/source/source_locator.rb +24 -11
- data/lib/reek/spec/should_reek.rb +3 -2
- data/lib/reek/spec/should_reek_of.rb +13 -26
- data/lib/reek/spec/should_reek_only_of.rb +5 -4
- data/lib/reek/spec/smell_matcher.rb +2 -1
- data/lib/reek/spec.rb +12 -9
- data/lib/reek/tree_dresser.rb +9 -8
- data/lib/reek/version.rb +2 -1
- data/lib/reek.rb +1 -0
- data/reek.gemspec +5 -6
- data/samples/checkstyle.xml +1 -1
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
- data/samples/configuration/full_configuration.reek +8 -4
- data/samples/configuration/full_mask.reek +5 -4
- data/samples/configuration/partial_mask.reek +3 -2
- data/samples/configuration/regular_configuration/.reek.yml +4 -0
- data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
- data/samples/no_config_file/.keep +0 -0
- data/samples/paths.rb +5 -4
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
- data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
- data/spec/factories/factories.rb +4 -23
- data/spec/quality/reek_source_spec.rb +5 -3
- data/spec/reek/ast/node_spec.rb +103 -10
- data/spec/reek/ast/reference_collector_spec.rb +1 -18
- data/spec/reek/ast/sexp_extensions_spec.rb +15 -34
- data/spec/reek/cli/application_spec.rb +77 -43
- data/spec/reek/cli/command/report_command_spec.rb +2 -2
- data/spec/reek/cli/command/todo_list_command_spec.rb +18 -73
- data/spec/reek/cli/options_spec.rb +4 -0
- data/spec/reek/cli/silencer_spec.rb +28 -0
- data/spec/reek/code_comment_spec.rb +31 -31
- data/spec/reek/configuration/app_configuration_spec.rb +46 -33
- data/spec/reek/configuration/configuration_file_finder_spec.rb +140 -35
- data/spec/reek/configuration/default_directive_spec.rb +1 -1
- data/spec/reek/configuration/directory_directives_spec.rb +6 -7
- data/spec/reek/configuration/excluded_paths_spec.rb +6 -6
- data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
- data/spec/reek/configuration/schema_validator_spec.rb +165 -0
- data/spec/reek/context/code_context_spec.rb +72 -108
- data/spec/reek/context/ghost_context_spec.rb +9 -9
- data/spec/reek/context/method_context_spec.rb +3 -3
- data/spec/reek/context/module_context_spec.rb +8 -4
- data/spec/reek/context/root_context_spec.rb +1 -1
- data/spec/reek/context/statement_counter_spec.rb +1 -0
- data/spec/reek/context_builder_spec.rb +20 -0
- data/spec/reek/{smell_detectors/detector_repository_spec.rb → detector_repository_spec.rb} +3 -3
- data/spec/reek/documentation_link_spec.rb +20 -0
- data/spec/reek/errors/base_error_spec.rb +13 -0
- data/spec/reek/examiner_spec.rb +173 -66
- data/spec/reek/logging_error_handler_spec.rb +24 -0
- data/spec/reek/rake/task_spec.rb +25 -2
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -1
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +83 -79
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/code_climate/code_climate_report_spec.rb +22 -22
- data/spec/reek/report/json_report_spec.rb +13 -46
- data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
- data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
- data/spec/reek/report/text_report_spec.rb +4 -4
- data/spec/reek/report/xml_report_spec.rb +3 -3
- data/spec/reek/report/yaml_report_spec.rb +18 -47
- data/spec/reek/report_spec.rb +3 -3
- data/spec/reek/{smell_detectors/smell_configuration_spec.rb → smell_configuration_spec.rb} +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +4 -5
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
- data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
- data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +5 -5
- data/spec/reek/smell_detectors/feature_envy_spec.rb +65 -10
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +59 -21
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +13 -0
- data/spec/reek/smell_detectors/missing_safe_method_spec.rb +62 -0
- data/spec/reek/smell_detectors/module_initialize_spec.rb +37 -2
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +2 -2
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -5
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +36 -15
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +11 -11
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +4 -4
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +21 -10
- data/spec/reek/smell_detectors/utility_function_spec.rb +57 -5
- data/spec/reek/{smell_detectors/smell_warning_spec.rb → smell_warning_spec.rb} +21 -17
- data/spec/reek/source/source_code_spec.rb +27 -61
- data/spec/reek/source/source_locator_spec.rb +95 -33
- data/spec/reek/spec/should_reek_of_spec.rb +25 -30
- data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
- data/spec/reek/spec/should_reek_spec.rb +8 -8
- data/spec/reek/spec/smell_matcher_spec.rb +23 -23
- data/spec/reek/tree_dresser_spec.rb +12 -17
- data/spec/spec_helper.rb +8 -17
- data/tasks/configuration.rake +10 -7
- metadata +91 -45
- data/defaults.reek +0 -128
- data/lib/reek/report/formatter/heading_formatter.rb +0 -51
- data/lib/reek/report/formatter/location_formatter.rb +0 -41
- data/lib/reek/report/formatter/progress_formatter.rb +0 -80
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter.rb +0 -32
- 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/samples/configuration/non_public_modifiers_mask.reek +0 -3
- data/samples/smelly_with_inline_mask.rb +0 -8
- data/samples/smelly_with_modifiers.rb +0 -12
- data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
- data/spec/reek/smell_detectors/prima_donna_method_spec.rb +0 -50
- data/tasks/mutant.rake +0 -14
- /data/{samples/configuration/.reek → .reek.yml} +0 -0
- /data/samples/{clean.rb → clean_source/clean.rb} +0 -0
- /data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
- /data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
- /data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
- /data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
- /data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
- /data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- [Overview](#overview)
|
|
8
8
|
- [Quickstart](#quickstart)
|
|
9
9
|
- [Example](#example)
|
|
10
|
-
- [Supported
|
|
10
|
+
- [Supported Ruby versions](#supported-ruby-versions)
|
|
11
11
|
- [Fixing Smell Warnings](#fixing-smell-warnings)
|
|
12
12
|
- [Sources](#sources)
|
|
13
13
|
- [Code smells](#code-smells)
|
|
@@ -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)
|
|
@@ -38,13 +39,18 @@
|
|
|
38
39
|
* [](https://badge.fury.io/rb/reek)
|
|
39
40
|
* 
|
|
40
41
|
* 
|
|
41
|
-
* [](https://gemnasium.com/github.com/troessner/reek)
|
|
42
42
|
* [](https://inch-ci.org/github/troessner/reek)
|
|
43
43
|
* [](https://codeclimate.com/github/troessner/reek)
|
|
44
44
|
* [](https://codebeat.co/projects/github-com-troessner-reek)
|
|
45
45
|
* 
|
|
46
46
|
* 
|
|
47
47
|
|
|
48
|
+
## Reek 5 is out!
|
|
49
|
+
|
|
50
|
+
Reek 5 is out and with it a bunch of breaking changes. If you're a new user you can just
|
|
51
|
+
continue with the quickstart below. If you're a Reek 4 user and would like to upgrade to 5, don't
|
|
52
|
+
worry, this shouldn't take you more than 10 minutes. Check out our [Upgrade Guide](docs/Reek-4-to-Reek-5-migration.md).
|
|
53
|
+
|
|
48
54
|
## Quickstart
|
|
49
55
|
|
|
50
56
|
Reek is a tool that examines Ruby classes, modules and methods and reports any
|
|
@@ -52,7 +58,7 @@ Reek is a tool that examines Ruby classes, modules and methods and reports any
|
|
|
52
58
|
|
|
53
59
|
For an excellent introduction to
|
|
54
60
|
[Code Smells](docs/Code-Smells.md) and Reek check out [this blog post](https://blog.codeship.com/how-to-find-ruby-code-smells-with-reek/)
|
|
55
|
-
or [that one](https://troessner.svbtle.com/the-latest-and-greatest-additions-to-reek). There is also [this talk](https://www.youtube.com/watch?v=
|
|
61
|
+
or [that one](https://troessner.svbtle.com/the-latest-and-greatest-additions-to-reek). There is also [this talk](https://www.youtube.com/watch?v=pazYe7WRWRU) from [RubyConfBY](http://rubyconference.by/) (there is also a [slide deck](http://talks.chastell.net/rubyconf-by-lt-2016/) if you prefer that).
|
|
56
62
|
|
|
57
63
|
Install it via rubygems:
|
|
58
64
|
|
|
@@ -83,24 +89,24 @@ end
|
|
|
83
89
|
Reek will report the following code smells in this file:
|
|
84
90
|
|
|
85
91
|
```
|
|
86
|
-
$ reek demo.rb
|
|
92
|
+
$ reek --no-documentation demo.rb
|
|
87
93
|
Inspecting 1 file(s):
|
|
88
94
|
S
|
|
89
95
|
|
|
90
96
|
demo.rb -- 2 warnings:
|
|
91
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
92
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
97
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
98
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
93
99
|
```
|
|
94
100
|
|
|
95
|
-
## Supported
|
|
101
|
+
## Supported Ruby versions
|
|
96
102
|
|
|
97
|
-
Reek is officially
|
|
103
|
+
Reek is officially supported for the following CRuby versions:
|
|
98
104
|
|
|
99
|
-
- 2.1
|
|
100
|
-
- 2.2
|
|
101
105
|
- 2.3
|
|
106
|
+
- 2.4
|
|
107
|
+
- 2.5
|
|
102
108
|
|
|
103
|
-
Other
|
|
109
|
+
Other Ruby implementations (like Rubinius or JRuby) are not officially supported but should work as well.
|
|
104
110
|
|
|
105
111
|
## Fixing Smell Warnings
|
|
106
112
|
|
|
@@ -251,12 +257,13 @@ For a summary of those CLI options see [Command-Line Options](docs/Command-Line-
|
|
|
251
257
|
#### Configuration loading
|
|
252
258
|
|
|
253
259
|
Configuring Reek via a configuration file is by far the most powerful way.
|
|
260
|
+
Reek expects this filename to be `.reek.yml` but you can override this via the CLI `-c` switch (see below).
|
|
254
261
|
|
|
255
|
-
There are three ways of passing Reek
|
|
262
|
+
There are three ways of passing Reek the configuration file:
|
|
256
263
|
|
|
257
264
|
1. Using the CLI `-c` switch (see [_Command-line interface_](#command-line-interface) above)
|
|
258
|
-
2. Having
|
|
259
|
-
3. Having
|
|
265
|
+
2. Having the configuration file either in your current working directory or in a parent directory (more on that later)
|
|
266
|
+
3. Having the configuration file in your home directory
|
|
260
267
|
|
|
261
268
|
The order in which Reek tries to find such a configuration
|
|
262
269
|
file is exactly the above: first it checks if we have given
|
|
@@ -274,43 +281,46 @@ of how many `*.reek` files you might have on your filesystem.
|
|
|
274
281
|
|
|
275
282
|
We put a lot of effort into making Reek's configuration as self explanatory as possible so the
|
|
276
283
|
best way to understand it is by looking at a simple
|
|
277
|
-
example (e.g.
|
|
284
|
+
example (e.g. `.reek.yml` in your project directory):
|
|
278
285
|
|
|
279
286
|
```yaml
|
|
280
287
|
---
|
|
281
288
|
|
|
282
289
|
### Generic smell configuration
|
|
283
290
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
#
|
|
290
|
-
# because you
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
#
|
|
298
|
-
#
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
291
|
+
detectors:
|
|
292
|
+
# You can disable smells completely
|
|
293
|
+
IrresponsibleModule:
|
|
294
|
+
enabled: false
|
|
295
|
+
|
|
296
|
+
# You can use filters to silence Reek warnings.
|
|
297
|
+
# Either because you simply disagree with Reek (we are not the police) or
|
|
298
|
+
# because you want to fix this at a later point in time.
|
|
299
|
+
NestedIterators:
|
|
300
|
+
exclude:
|
|
301
|
+
- "MyWorker#self.class_method" # should be refactored
|
|
302
|
+
- "AnotherWorker#instance_method" # should be refactored as well
|
|
303
|
+
|
|
304
|
+
# A lot of smells allow fine tuning their configuration. You can look up all available options
|
|
305
|
+
# in the corresponding smell documentation in /docs. In most cases you probably can just go
|
|
306
|
+
# with the defaults as documented in defaults.reek.yml.
|
|
307
|
+
DataClump:
|
|
308
|
+
max_copies: 3
|
|
309
|
+
min_clump_size: 3
|
|
302
310
|
|
|
303
311
|
### Directory specific configuration
|
|
304
312
|
|
|
305
313
|
# You can configure smells on a per-directory base.
|
|
306
314
|
# E.g. the classic Rails case: controllers smell of NestedIterators (see /docs/Nested-Iterators.md) and
|
|
307
315
|
# helpers smell of UtilityFunction (see docs/Utility-Function.md)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
316
|
+
# Note that we only allow configuration on a directory level, not a file level, so all paths have to point to directories.
|
|
317
|
+
directories:
|
|
318
|
+
"web_app/app/controllers":
|
|
319
|
+
NestedIterators:
|
|
320
|
+
enabled: false
|
|
321
|
+
"web_app/app/helpers":
|
|
322
|
+
UtilityFunction:
|
|
323
|
+
enabled: false
|
|
314
324
|
|
|
315
325
|
### Excluding directories
|
|
316
326
|
|
|
@@ -320,6 +330,14 @@ exclude_paths:
|
|
|
320
330
|
- lib/rake/legacy_tasks
|
|
321
331
|
```
|
|
322
332
|
|
|
333
|
+
As you see above, Reek's configuration consists of 3 different sections denoted by 3 different keys:
|
|
334
|
+
|
|
335
|
+
* detectors
|
|
336
|
+
* directories
|
|
337
|
+
* exclude_paths
|
|
338
|
+
|
|
339
|
+
Whatever you add to your configuration should be scoped under one of those keys.
|
|
340
|
+
|
|
323
341
|
If you have a directory directive for which a default directive exists, the more specific
|
|
324
342
|
one (which is the directory directive) will take precedence.
|
|
325
343
|
|
|
@@ -327,15 +345,12 @@ This configuration for instance:
|
|
|
327
345
|
|
|
328
346
|
```yaml
|
|
329
347
|
---
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
max_statements: 5
|
|
335
|
-
|
|
336
|
-
"app/controllers":
|
|
348
|
+
detectors:
|
|
349
|
+
IrresponsibleModule:
|
|
350
|
+
enabled: false
|
|
351
|
+
|
|
337
352
|
TooManyStatements:
|
|
338
|
-
max_statements:
|
|
353
|
+
max_statements: 5
|
|
339
354
|
```
|
|
340
355
|
|
|
341
356
|
translates to:
|
|
@@ -344,16 +359,29 @@ translates to:
|
|
|
344
359
|
* TooManyStatements#max_statements is 10 in "app/controllers"
|
|
345
360
|
* TooManyStatements#max_statements is 5 everywhere else
|
|
346
361
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
types offer a configuration that goes beyond that of the basic smell options, for instance
|
|
362
|
+
Every smell detector supports our [Basic Smell Options](docs/Basic-Smell-Options.md). As you can see above,
|
|
363
|
+
certain smell types offer a configuration that goes beyond that of the basic smell options, for instance
|
|
350
364
|
[Data Clump](docs/Data-Clump.md).
|
|
351
365
|
All options that go beyond the [Basic Smell Options](docs/Basic-Smell-Options.md)
|
|
352
366
|
are documented in the corresponding smell type /docs page (if you want to get a quick overview over all possible
|
|
353
|
-
configurations you can also check out [the `
|
|
367
|
+
configurations you can also check out [the `defaults.reek.yml` file in this repository](docs/defaults.reek.yml).
|
|
354
368
|
|
|
355
369
|
Note that you do not need a configuration file at all.
|
|
356
|
-
If you're fine with all the [defaults](defaults.reek) we set you can skip this completely.
|
|
370
|
+
If you're fine with all the [defaults.reek.yml](docs/defaults.reek.yml) we set you can skip this completely.
|
|
371
|
+
|
|
372
|
+
Don't worry about introducing a mistake in your configuration file that might go unnoticed - Reek uses a
|
|
373
|
+
schema to validate your configuration against on start up and will faily loudly in case you
|
|
374
|
+
misspelled an option or used the wrong data type for a value like this:
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Reek takes one configuration file and one configuration file only with `.reek.yml` being the default name.
|
|
381
|
+
|
|
382
|
+
In case you have to have one or more configuration files in the directory (e.g. you're
|
|
383
|
+
toying around with different, mutually exclusive settings) you need to tell Reek
|
|
384
|
+
explicitly which file to use via `reek -c config.reek`.
|
|
357
385
|
|
|
358
386
|
### Source code comments
|
|
359
387
|
|
|
@@ -377,7 +405,7 @@ def smelly_method foo
|
|
|
377
405
|
end
|
|
378
406
|
```
|
|
379
407
|
|
|
380
|
-
This is an
|
|
408
|
+
This is an incredibly powerful feature and further explained under [Smell Suppresion](docs/Smell-Suppression.md).
|
|
381
409
|
|
|
382
410
|
### Generating a 'todo' list
|
|
383
411
|
|
|
@@ -470,7 +498,9 @@ You can also run:
|
|
|
470
498
|
bundle exec rake ci
|
|
471
499
|
```
|
|
472
500
|
|
|
473
|
-
This will run everything the default task runs and also
|
|
501
|
+
This will run everything the default task runs and also
|
|
502
|
+
[Ataru](https://github.com/CodePadawans/ataru). This is the task that we run on
|
|
503
|
+
Travis as well and that determines if your pull request is green or red.
|
|
474
504
|
|
|
475
505
|
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
506
|
|
|
@@ -512,6 +542,20 @@ If you don't feel like getting your hands dirty with code there are still other
|
|
|
512
542
|
* Open up an [issue](https://github.com/troessner/reek/issues) and report bugs
|
|
513
543
|
* Suggest other improvements like additional smells for instance
|
|
514
544
|
|
|
545
|
+
### Running Code Climate locally
|
|
546
|
+
|
|
547
|
+
If you run into Code Climate issues (e.g., go over code duplication
|
|
548
|
+
threshold) you might want to be able to run Code Climate against
|
|
549
|
+
the Reek codebase locally. To do this, you need to do the following:
|
|
550
|
+
|
|
551
|
+
* [install Docker CE](https://docs.docker.com/engine/installation/)
|
|
552
|
+
* [install Code Climate CLI](https://github.com/codeclimate/codeclimate#installation)
|
|
553
|
+
* `gem install codeclimate`
|
|
554
|
+
* `codeclimate engines:install`
|
|
555
|
+
|
|
556
|
+
Now you can run various Code Climate engines,
|
|
557
|
+
e.g., `codeclimate analyze -e duplication`
|
|
558
|
+
|
|
515
559
|
## Output formats
|
|
516
560
|
|
|
517
561
|
Reek supports 5 output formats:
|
|
@@ -528,20 +572,24 @@ Making Reek "Rails"-friendly is fairly simple since we support directory specifi
|
|
|
528
572
|
Just add this to your configuration file:
|
|
529
573
|
|
|
530
574
|
```Yaml
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
575
|
+
directories:
|
|
576
|
+
"app/controllers":
|
|
577
|
+
IrresponsibleModule:
|
|
578
|
+
enabled: false
|
|
579
|
+
NestedIterators:
|
|
580
|
+
max_allowed_nesting: 2
|
|
581
|
+
UnusedPrivateMethod:
|
|
582
|
+
enabled: false
|
|
583
|
+
InstanceVariableAssumption:
|
|
584
|
+
enabled: false
|
|
585
|
+
"app/helpers":
|
|
586
|
+
IrresponsibleModule:
|
|
587
|
+
enabled: false
|
|
588
|
+
UtilityFunction:
|
|
589
|
+
enabled: false
|
|
590
|
+
"app/mailers":
|
|
591
|
+
InstanceVariableAssumption:
|
|
592
|
+
enabled: false
|
|
545
593
|
```
|
|
546
594
|
|
|
547
595
|
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.
|
|
@@ -554,6 +602,7 @@ Be careful though, Reek does not merge your configuration entries, so if you alr
|
|
|
554
602
|
* [TextMate Bundle](https://github.com/peeyush1234/reek.tmbundle)
|
|
555
603
|
* [Atom plugin](https://atom.io/packages/linter-reek)
|
|
556
604
|
* [SublimeLinter plugin](https://packagecontrol.io/packages/SublimeLinter-contrib-reek)
|
|
605
|
+
* [VS Code plugin](https://github.com/rubyide/vscode-ruby)
|
|
557
606
|
* [Emacs plugin](https://github.com/hanmoi-choi/reek-emacs)
|
|
558
607
|
|
|
559
608
|
### Projects that use or support us
|
data/Rakefile
CHANGED
|
@@ -3,6 +3,19 @@ require 'rake/clean'
|
|
|
3
3
|
|
|
4
4
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
|
5
5
|
|
|
6
|
-
task
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
task :ci do
|
|
7
|
+
[
|
|
8
|
+
'test:spec',
|
|
9
|
+
'configuration:update_default_configuration',
|
|
10
|
+
'test:features',
|
|
11
|
+
:rubocop,
|
|
12
|
+
'test:quality',
|
|
13
|
+
:ataru
|
|
14
|
+
].each do |name|
|
|
15
|
+
puts "\n=== Running #{name}...\n"
|
|
16
|
+
Rake::Task[name].invoke
|
|
17
|
+
puts "\n=== Running #{name} -> Done\n"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
task default: :ci
|
data/bin/code_climate_reek
CHANGED
data/bin/reek
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
|
|
3
4
|
#
|
|
4
5
|
# Reek examines Ruby source code for smells.
|
|
5
|
-
# Visit https://
|
|
6
|
-
#
|
|
7
|
-
# Author: Kevin Rutherford
|
|
6
|
+
# Visit https://github.com/troessner/reek for docs etc.
|
|
8
7
|
#
|
|
9
8
|
|
|
10
9
|
require_relative '../lib/reek'
|
data/docs/API.md
CHANGED
|
@@ -89,7 +89,7 @@ XMLReport
|
|
|
89
89
|
|
|
90
90
|
## Configuration
|
|
91
91
|
|
|
92
|
-
Given you have the following configuration file called
|
|
92
|
+
Given you have the following configuration file called `.reek.yml` in your root directory:
|
|
93
93
|
|
|
94
94
|
```Yaml
|
|
95
95
|
---
|
|
@@ -106,7 +106,7 @@ You can now use either
|
|
|
106
106
|
Reek::Configuration::AppConfiguration.from_path Pathname.new('config.reek')
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
but you can also pass a hash with the contents of the
|
|
109
|
+
but you can also pass a hash with the contents of the `.reek.yml` YAML file
|
|
110
110
|
to `Reek::Configuration::AppConfiguration.from_hash`.
|
|
111
111
|
|
|
112
112
|
Given the example above you would load that as follows:
|
|
@@ -140,13 +140,6 @@ string -- 2 warnings:
|
|
|
140
140
|
Dirty#call_me has the parameter name 'b' (UncommunicativeParameterName)
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
Instead of the smell detector names you can also use the full detector class in
|
|
144
|
-
your configuration hash, for example:
|
|
145
|
-
|
|
146
|
-
```ruby
|
|
147
|
-
config_hash = { Reek::SmellDetectors::IrresponsibleModule => { 'enabled' => false } }
|
|
148
|
-
```
|
|
149
|
-
|
|
150
143
|
Of course, directory specific configuration and excluded paths are supported as
|
|
151
144
|
well:
|
|
152
145
|
|
data/docs/Basic-Smell-Options.md
CHANGED
|
@@ -7,14 +7,14 @@ Every smell detector in Reek offers at least the following configuration options
|
|
|
7
7
|
| Option | Value | Effect |
|
|
8
8
|
| ---------------|-------------|---------|
|
|
9
9
|
| `enabled` | Boolean | Determines whether the smell detector is active. Defaults to `true` |
|
|
10
|
-
| `exclude` | an array of strings
|
|
10
|
+
| `exclude` | an array of strings that will be converted into regular expressions | Ignores any context whose full description matches any element of this array. |
|
|
11
11
|
|
|
12
|
-
The file `defaults.reek` (shipped with the Reek gem) lists any default
|
|
12
|
+
The file `docs/defaults.reek.yml` (shipped with the Reek gem) lists any default
|
|
13
13
|
exclusions for each smell.
|
|
14
14
|
|
|
15
15
|
## Examples
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
**An easy one:**
|
|
18
18
|
|
|
19
19
|
To stop Reek reporting smells in any method called `write` you might create a configuration file containing this:
|
|
20
20
|
|
|
@@ -24,15 +24,9 @@ DuplicateMethodCall:
|
|
|
24
24
|
- write
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Internally Reek will convert this to the Regexp /write/.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
DuplicateMethodCall:
|
|
31
|
-
exclude:
|
|
32
|
-
- !ruby/regexp /write/
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
<u>A more sophisticated one:</u>
|
|
29
|
+
**A more sophisticated one:**
|
|
36
30
|
|
|
37
31
|
```yaml
|
|
38
32
|
FeatureEnvy:
|
|
@@ -43,3 +37,49 @@ FeatureEnvy:
|
|
|
43
37
|
```
|
|
44
38
|
|
|
45
39
|
This would not report FeatureEnvy for the instance method `MyModel#do_things`, the whole module `MyHelper` and the `respond` instance method of `ApplicationController`
|
|
40
|
+
|
|
41
|
+
## Advanced configuration
|
|
42
|
+
|
|
43
|
+
Sometimes just strings are not enough for configuration. E.g. consider this code sample:
|
|
44
|
+
|
|
45
|
+
```Ruby
|
|
46
|
+
class Klass
|
|
47
|
+
def foo1; end
|
|
48
|
+
def foo1bar; end
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
Both "Klass#foo1" and "Klass#foo1bar" will smell of UncommunicativeMethodName. Now let's assume
|
|
52
|
+
you are ok with "Klass#foo1" but not "Klass#foo1bar".
|
|
53
|
+
Just having this configuration
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
UncommunicativeMethodName:
|
|
57
|
+
exclude:
|
|
58
|
+
- "Klass#foo1"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
wouldn't work because now "Klass#foo1bar" wouldn't smell as well.
|
|
62
|
+
|
|
63
|
+
For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
|
|
64
|
+
Everything within the forward slashes will be loaded as a regex.
|
|
65
|
+
|
|
66
|
+
A possible configuration that hat excludes "Klass#foo1" from this scan but not "Klass#foo1bar" could look like this:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
UncommunicativeMethodName:
|
|
70
|
+
exclude:
|
|
71
|
+
- "/Klass#foo1$/"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Reek 4
|
|
75
|
+
|
|
76
|
+
In Reek 4 you could also pass regexes to `exclude`, meaning this was perfectly valid as well:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
DuplicateMethodCall:
|
|
80
|
+
exclude:
|
|
81
|
+
- !ruby/regexp /write/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
|
|
85
|
+
You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
|
data/docs/Code-Smells.md
CHANGED
|
@@ -23,7 +23,7 @@ Reek currently includes checks for the following smells:
|
|
|
23
23
|
* [Utility Function](Utility-Function.md)
|
|
24
24
|
* [Module Initialize](Module-Initialize.md)
|
|
25
25
|
* [Nested Iterators](Nested-Iterators.md)
|
|
26
|
-
* [
|
|
26
|
+
* [Missing Safe Method](Missing-Safe-Method.md), formerly known as Prima Donna Method
|
|
27
27
|
* [Simulated Polymorphism](Simulated-Polymorphism.md), including
|
|
28
28
|
* [Manual Dispatch](Manual-Dispatch.md)
|
|
29
29
|
* [Nil Check](Nil-Check.md)
|
|
@@ -12,6 +12,16 @@ reek -h
|
|
|
12
12
|
|
|
13
13
|
for details.
|
|
14
14
|
|
|
15
|
+
## Telling Reek to use a specific configuration file
|
|
16
|
+
|
|
17
|
+
In case your configuration file is not in the standard location (that would be your project directory or
|
|
18
|
+
whatever directory you're running Reek from) you can specify a configuration file with the `-c` option
|
|
19
|
+
like this:
|
|
20
|
+
|
|
21
|
+
```Bash
|
|
22
|
+
reek -c /somewhere/on/your/filesystem/reek_config.yml lib/
|
|
23
|
+
```
|
|
24
|
+
|
|
15
25
|
## Telling Reek Which Code to Check
|
|
16
26
|
|
|
17
27
|
Probably the most standard use case would be to check all Ruby files in the lib directory:
|
|
@@ -91,10 +101,10 @@ mess.rb -- 2 warnings:
|
|
|
91
101
|
[2]:x has the name 'x' (UncommunicativeMethodName)
|
|
92
102
|
```
|
|
93
103
|
|
|
94
|
-
### Enable the
|
|
104
|
+
### Enable the verbose mode
|
|
95
105
|
|
|
96
|
-
_reek_ has a
|
|
97
|
-
This mode can be enabled via the "-U" or "--
|
|
106
|
+
_reek_ has a verbose mode which you might find helpful as a beginner. "verbose" just means that behind each warning a helpful link will be displayed which leads directly to the corresponding _reek_ documentation page.
|
|
107
|
+
This mode can be enabled via the "-U" or "--documentation" flag.
|
|
98
108
|
|
|
99
109
|
So for instance, if your test file would smell of _ClassVariable_, this is what the _reek_ output would look like:
|
|
100
110
|
|
|
@@ -103,7 +113,7 @@ reek -U test.rb
|
|
|
103
113
|
```
|
|
104
114
|
```
|
|
105
115
|
test.rb -- 1 warning:
|
|
106
|
-
[2]:Dummy declares the class variable @@class_variable (ClassVariable) [https://github.com/troessner/reek/
|
|
116
|
+
[2]:Dummy declares the class variable @@class_variable (ClassVariable) [https://github.com/troessner/reek/blob/master/docs/Class-Variable.md]
|
|
107
117
|
```
|
|
108
118
|
|
|
109
119
|
Note the link at the end.
|
|
@@ -42,7 +42,55 @@ The approach you take will depend on balancing other factors in your code.
|
|
|
42
42
|
|
|
43
43
|
## Current support in Reek
|
|
44
44
|
|
|
45
|
-
Reek's Duplicate Method Call detector checks for repeated identical method calls within
|
|
45
|
+
Reek's Duplicate Method Call detector checks for repeated identical method calls within
|
|
46
|
+
any one method definition. This is intended to complement the checks performed by tools
|
|
47
|
+
such as [Flay](http://ruby.sadi.st/Flay.html) and [Simian](http://www.redhillconsulting.com.au/products/simian/).
|
|
48
|
+
|
|
49
|
+
## Edge cases
|
|
50
|
+
|
|
51
|
+
Be aware that there are some edge cases like this code:
|
|
52
|
+
|
|
53
|
+
```Ruby
|
|
54
|
+
class Foo
|
|
55
|
+
def bar(switch)
|
|
56
|
+
case switch
|
|
57
|
+
when :a
|
|
58
|
+
->(arg) { arg.call_me(:maybe); do_something }
|
|
59
|
+
when :b
|
|
60
|
+
->(arg) { arg.call_me(:maybe); do_something_else }
|
|
61
|
+
when :c
|
|
62
|
+
->(arg) { arg.call_me(:maybe); do_something_different }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Reek cannot reliably detect that each call's receiver is a different arg and will report:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
[5, 7, 9]:DuplicateMethodCall: Foo#bar calls 'arg.call_me(:maybe)' 3 times
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If you're running into this problem you can disable this smell detector for this method either via
|
|
75
|
+
configuration:
|
|
76
|
+
|
|
77
|
+
```Yaml
|
|
78
|
+
---
|
|
79
|
+
DuplicateMethodCall:
|
|
80
|
+
exclude:
|
|
81
|
+
- 'Foo#bar'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
or via source code comment:
|
|
85
|
+
|
|
86
|
+
```Ruby
|
|
87
|
+
class Foo
|
|
88
|
+
# :reek:DuplicateMethodCall
|
|
89
|
+
def bar(switch)
|
|
90
|
+
# ....
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
```
|
|
46
94
|
|
|
47
95
|
## Configuration
|
|
48
96
|
|
data/docs/Feature-Envy.md
CHANGED
|
@@ -40,6 +40,50 @@ belongs to the Item class, not the Warehouse.
|
|
|
40
40
|
|
|
41
41
|
_Feature Envy_ reports any method that refers to self less often than it refers to (ie. send messages to) some other object.
|
|
42
42
|
|
|
43
|
+
## Edge cases
|
|
44
|
+
|
|
45
|
+
Be aware that there are some edge cases like this code:
|
|
46
|
+
|
|
47
|
+
```Ruby
|
|
48
|
+
class Foo
|
|
49
|
+
def initialize
|
|
50
|
+
@map = {
|
|
51
|
+
a: ->(arg) { arg.css('table') },
|
|
52
|
+
b: ->(arg) { arg.css('div') },
|
|
53
|
+
c: ->(arg) { arg.css('span') }
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Reek cannot reliably detect that each call's receiver is a different arg and will report:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
[4, 5, 6]:FeatureEnvy: Foo#initialize refers to 'arg' more than self (maybe move it to another class?)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If you're running into this problem you can disable this smell detector for this method either via
|
|
66
|
+
configuration:
|
|
67
|
+
|
|
68
|
+
```Yaml
|
|
69
|
+
---
|
|
70
|
+
FeatureEnvy:
|
|
71
|
+
exclude:
|
|
72
|
+
- 'Foo#bar'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
or via source code comment:
|
|
76
|
+
|
|
77
|
+
```Ruby
|
|
78
|
+
class Foo
|
|
79
|
+
# :reek:FeatureEnvy
|
|
80
|
+
def initialize
|
|
81
|
+
@map = {
|
|
82
|
+
# ....
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
```
|
|
86
|
+
|
|
43
87
|
## Differences to _Utility Function_
|
|
44
88
|
|
|
45
89
|
_Feature Envy_ is only triggered if there are some references to self and _[Utility Function](Utility-Function.md)_ is triggered if there are no references to self.
|