reek 4.6.0 → 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 +79 -26
- data/.simplecov +1 -0
- data/.travis.yml +3 -9
- data/.yardopts +1 -1
- data/CHANGELOG.md +76 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +5 -5
- data/README.md +138 -107
- 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 +7 -7
- data/docs/Instance-Variable-Assumption.md +1 -1
- data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
- 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 +3 -3
- data/docs/defaults.reek.yml +129 -0
- data/docs/yard_plugin.rb +1 -0
- data/features/command_line_interface/basic_usage.feature +2 -2
- data/features/command_line_interface/options.feature +46 -4
- 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 +31 -5
- 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 +4 -4
- 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 +287 -287
- data/features/step_definitions/reek_steps.rb +14 -2
- data/features/step_definitions/sample_file_steps.rb +9 -4
- data/features/support/env.rb +2 -11
- data/features/todo_list.feature +26 -23
- 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 +3 -4
- data/lib/reek/ast/sexp_extensions/arguments.rb +1 -0
- 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 +1 -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 +5 -3
- data/lib/reek/cli/command/base_command.rb +1 -0
- data/lib/reek/cli/command/report_command.rb +2 -2
- data/lib/reek/cli/command/todo_list_command.rb +9 -8
- data/lib/reek/cli/options.rb +32 -16
- data/lib/reek/cli/silencer.rb +15 -3
- data/lib/reek/cli/status.rb +1 -0
- data/lib/reek/code_comment.rb +14 -16
- 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 +17 -41
- 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 -2
- 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 +44 -44
- data/lib/reek/detector_repository.rb +12 -11
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +15 -13
- data/lib/reek/errors/bad_detector_in_comment_error.rb +13 -11
- data/lib/reek/errors/base_error.rb +3 -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 +14 -12
- data/lib/reek/errors/incomprehensible_source_error.rb +23 -24
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +24 -22
- data/lib/reek/logging_error_handler.rb +8 -5
- 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 +6 -6
- 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 +3 -2
- data/lib/reek/smell_detectors/attribute.rb +6 -11
- data/lib/reek/smell_detectors/base_detector.rb +31 -26
- data/lib/reek/smell_detectors/boolean_parameter.rb +4 -5
- data/lib/reek/smell_detectors/class_variable.rb +6 -14
- data/lib/reek/smell_detectors/control_parameter.rb +19 -33
- data/lib/reek/smell_detectors/data_clump.rb +16 -9
- data/lib/reek/smell_detectors/duplicate_method_call.rb +24 -17
- data/lib/reek/smell_detectors/feature_envy.rb +10 -7
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +15 -23
- data/lib/reek/smell_detectors/irresponsible_module.rb +6 -12
- data/lib/reek/smell_detectors/long_parameter_list.rb +11 -7
- data/lib/reek/smell_detectors/long_yield_list.rb +11 -7
- data/lib/reek/smell_detectors/manual_dispatch.rb +5 -5
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +21 -20
- data/lib/reek/smell_detectors/module_initialize.rb +4 -5
- data/lib/reek/smell_detectors/nested_iterators.rb +17 -24
- data/lib/reek/smell_detectors/nil_check.rb +9 -15
- data/lib/reek/smell_detectors/repeated_conditional.rb +14 -11
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +8 -8
- data/lib/reek/smell_detectors/too_many_constants.rb +11 -9
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +11 -6
- data/lib/reek/smell_detectors/too_many_methods.rb +12 -7
- data/lib/reek/smell_detectors/too_many_statements.rb +11 -6
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +11 -11
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +15 -18
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +18 -22
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +27 -27
- data/lib/reek/smell_detectors/unused_parameters.rb +5 -6
- data/lib/reek/smell_detectors/unused_private_method.rb +14 -20
- data/lib/reek/smell_detectors/utility_function.rb +13 -16
- data/lib/reek/smell_detectors.rb +2 -1
- data/lib/reek/smell_warning.rb +16 -8
- data/lib/reek/source/source_code.rb +65 -46
- data/lib/reek/source/source_locator.rb +9 -8
- 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 +7 -6
- 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/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 +2 -13
- data/spec/reek/ast/node_spec.rb +103 -10
- data/spec/reek/ast/reference_collector_spec.rb +1 -1
- data/spec/reek/ast/sexp_extensions_spec.rb +15 -34
- data/spec/reek/cli/application_spec.rb +52 -42
- data/spec/reek/cli/command/todo_list_command_spec.rb +6 -4
- data/spec/reek/cli/silencer_spec.rb +28 -0
- data/spec/reek/code_comment_spec.rb +31 -38
- data/spec/reek/configuration/app_configuration_spec.rb +46 -33
- data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -51
- 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 +70 -106
- data/spec/reek/context/ghost_context_spec.rb +9 -9
- data/spec/reek/context/method_context_spec.rb +2 -2
- data/spec/reek/context/module_context_spec.rb +3 -3
- 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/documentation_link_spec.rb +20 -0
- data/spec/reek/errors/base_error_spec.rb +13 -0
- data/spec/reek/examiner_spec.rb +137 -29
- data/spec/reek/rake/task_spec.rb +25 -2
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -78
- 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 +17 -46
- data/spec/reek/report_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 +3 -3
- data/spec/reek/smell_detectors/feature_envy_spec.rb +47 -2
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +59 -21
- data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +10 -10
- data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
- 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 +9 -9
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
- 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_warning_spec.rb +12 -8
- data/spec/reek/source/source_code_spec.rb +27 -38
- data/spec/reek/source/source_locator_spec.rb +42 -12
- data/spec/reek/spec/should_reek_of_spec.rb +25 -30
- data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
- 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 +7 -17
- data/tasks/configuration.rake +8 -5
- metadata +77 -40
- data/defaults.reek +0 -128
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/errors/parse_error.rb +0 -19
- 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/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/{samples/configuration/more_than_one_configuration_file/regular.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/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
- /data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +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
|
@@ -21,5 +21,76 @@ Reek's _Uncommunicative Variable Name_ detector supports the
|
|
|
21
21
|
|
|
22
22
|
| Option | Value | Effect |
|
|
23
23
|
| ---------------|-------------|---------|
|
|
24
|
-
| `reject` | array of
|
|
25
|
-
| `accept` | array of strings
|
|
24
|
+
| `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names, names ending with a number or names containing upper case letters. |
|
|
25
|
+
| `accept` | array of strings | Names that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to `_`.|
|
|
26
|
+
|
|
27
|
+
An example configuration could look like this:
|
|
28
|
+
|
|
29
|
+
```Yaml
|
|
30
|
+
---
|
|
31
|
+
UncommunicativeVariableName:
|
|
32
|
+
accept:
|
|
33
|
+
- x
|
|
34
|
+
- var1
|
|
35
|
+
reject:
|
|
36
|
+
- helper
|
|
37
|
+
- foobar
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Reek will convert whatever you give it as a string to the corresponding regex, so "foobar" from above will be converted to /foobar/ internally.
|
|
41
|
+
|
|
42
|
+
Applying a configuration to a source file like this:
|
|
43
|
+
|
|
44
|
+
```Ruby
|
|
45
|
+
def omg
|
|
46
|
+
x = 5 # Should not be reported
|
|
47
|
+
var1 = true # Should not be reported
|
|
48
|
+
helper = 42 # Should be reported
|
|
49
|
+
foobar = false # Should be reported
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Reek would report:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
smelly.rb -- 2 warnings:
|
|
57
|
+
[5]:UncommunicativeVariableName: omg has the variable name 'foobar' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
|
|
58
|
+
[4]:UncommunicativeVariableName: omg has the variable name 'helper' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Advanced configuration
|
|
62
|
+
|
|
63
|
+
Sometimes just strings are not enough for configuration. E.g. consider this code sample:
|
|
64
|
+
|
|
65
|
+
```Ruby
|
|
66
|
+
def omg
|
|
67
|
+
foo = 42
|
|
68
|
+
foobar = 4242
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
and now imagine that you want to reject the name "foo" but not "foobar". This wouldn't be possible with just using strings.
|
|
73
|
+
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.
|
|
74
|
+
Everything within the forward slashes will be loaded as a regex.
|
|
75
|
+
|
|
76
|
+
A possible configuration that allows "foobar" but rejects "foo" could look like this:
|
|
77
|
+
|
|
78
|
+
```Yaml
|
|
79
|
+
---
|
|
80
|
+
UncommunicativeVariableName:
|
|
81
|
+
reject:
|
|
82
|
+
- "/^foo$/"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Reek 4
|
|
86
|
+
|
|
87
|
+
In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
UncommunicativeVariableName:
|
|
91
|
+
accept:
|
|
92
|
+
- !ruby/regexp /write/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
|
|
96
|
+
You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
|
|
@@ -37,7 +37,7 @@ configuration option (which is part of the [Basic Smell Options](Basic-Smell-Opt
|
|
|
37
37
|
for instance like this (an example from Reek's own codebase):
|
|
38
38
|
|
|
39
39
|
```Ruby
|
|
40
|
-
# :reek:UnusedPrivateMethod { exclude: [
|
|
40
|
+
# :reek:UnusedPrivateMethod { exclude: [ process_ ] }
|
|
41
41
|
class ContextBuilder
|
|
42
42
|
def process_begin
|
|
43
43
|
# ....
|
|
@@ -78,13 +78,13 @@ end
|
|
|
78
78
|
## Known limitations
|
|
79
79
|
|
|
80
80
|
* Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
|
|
81
|
-
static tool for that matter)
|
|
81
|
+
static tool for that matter) cannot detect.
|
|
82
82
|
* Method calls via callback like [Rails filters](http://guides.rubyonrails.org/action_controller_overview.html#filters)
|
|
83
83
|
will trigger this as well, e.g.:
|
|
84
84
|
|
|
85
85
|
```Ruby
|
|
86
86
|
class BankController < ActionController::Base
|
|
87
|
-
|
|
87
|
+
before_action :audit
|
|
88
88
|
|
|
89
89
|
private
|
|
90
90
|
def audit
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
detectors:
|
|
3
|
+
Attribute:
|
|
4
|
+
enabled: true
|
|
5
|
+
exclude: []
|
|
6
|
+
BooleanParameter:
|
|
7
|
+
enabled: true
|
|
8
|
+
exclude: []
|
|
9
|
+
ClassVariable:
|
|
10
|
+
enabled: true
|
|
11
|
+
exclude: []
|
|
12
|
+
ControlParameter:
|
|
13
|
+
enabled: true
|
|
14
|
+
exclude: []
|
|
15
|
+
DataClump:
|
|
16
|
+
enabled: true
|
|
17
|
+
exclude: []
|
|
18
|
+
max_copies: 2
|
|
19
|
+
min_clump_size: 2
|
|
20
|
+
DuplicateMethodCall:
|
|
21
|
+
enabled: true
|
|
22
|
+
exclude: []
|
|
23
|
+
max_calls: 1
|
|
24
|
+
allow_calls: []
|
|
25
|
+
FeatureEnvy:
|
|
26
|
+
enabled: true
|
|
27
|
+
exclude: []
|
|
28
|
+
InstanceVariableAssumption:
|
|
29
|
+
enabled: true
|
|
30
|
+
exclude: []
|
|
31
|
+
IrresponsibleModule:
|
|
32
|
+
enabled: true
|
|
33
|
+
exclude: []
|
|
34
|
+
LongParameterList:
|
|
35
|
+
enabled: true
|
|
36
|
+
exclude: []
|
|
37
|
+
max_params: 3
|
|
38
|
+
overrides:
|
|
39
|
+
initialize:
|
|
40
|
+
max_params: 5
|
|
41
|
+
LongYieldList:
|
|
42
|
+
enabled: true
|
|
43
|
+
exclude: []
|
|
44
|
+
max_params: 3
|
|
45
|
+
ManualDispatch:
|
|
46
|
+
enabled: true
|
|
47
|
+
exclude: []
|
|
48
|
+
MissingSafeMethod:
|
|
49
|
+
enabled: true
|
|
50
|
+
exclude: []
|
|
51
|
+
ModuleInitialize:
|
|
52
|
+
enabled: true
|
|
53
|
+
exclude: []
|
|
54
|
+
NestedIterators:
|
|
55
|
+
enabled: true
|
|
56
|
+
exclude: []
|
|
57
|
+
max_allowed_nesting: 1
|
|
58
|
+
ignore_iterators:
|
|
59
|
+
- tap
|
|
60
|
+
NilCheck:
|
|
61
|
+
enabled: true
|
|
62
|
+
exclude: []
|
|
63
|
+
RepeatedConditional:
|
|
64
|
+
enabled: true
|
|
65
|
+
exclude: []
|
|
66
|
+
max_ifs: 2
|
|
67
|
+
SubclassedFromCoreClass:
|
|
68
|
+
enabled: true
|
|
69
|
+
exclude: []
|
|
70
|
+
TooManyConstants:
|
|
71
|
+
enabled: true
|
|
72
|
+
exclude: []
|
|
73
|
+
max_constants: 5
|
|
74
|
+
TooManyInstanceVariables:
|
|
75
|
+
enabled: true
|
|
76
|
+
exclude: []
|
|
77
|
+
max_instance_variables: 4
|
|
78
|
+
TooManyMethods:
|
|
79
|
+
enabled: true
|
|
80
|
+
exclude: []
|
|
81
|
+
max_methods: 15
|
|
82
|
+
TooManyStatements:
|
|
83
|
+
enabled: true
|
|
84
|
+
exclude:
|
|
85
|
+
- initialize
|
|
86
|
+
max_statements: 5
|
|
87
|
+
UncommunicativeMethodName:
|
|
88
|
+
enabled: true
|
|
89
|
+
exclude: []
|
|
90
|
+
reject:
|
|
91
|
+
- "/^[a-z]$/"
|
|
92
|
+
- "/[0-9]$/"
|
|
93
|
+
- "/[A-Z]/"
|
|
94
|
+
accept: []
|
|
95
|
+
UncommunicativeModuleName:
|
|
96
|
+
enabled: true
|
|
97
|
+
exclude: []
|
|
98
|
+
reject:
|
|
99
|
+
- "/^.$/"
|
|
100
|
+
- "/[0-9]$/"
|
|
101
|
+
accept: []
|
|
102
|
+
UncommunicativeParameterName:
|
|
103
|
+
enabled: true
|
|
104
|
+
exclude: []
|
|
105
|
+
reject:
|
|
106
|
+
- "/^.$/"
|
|
107
|
+
- "/[0-9]$/"
|
|
108
|
+
- "/[A-Z]/"
|
|
109
|
+
- "/^_/"
|
|
110
|
+
accept: []
|
|
111
|
+
UncommunicativeVariableName:
|
|
112
|
+
enabled: true
|
|
113
|
+
exclude: []
|
|
114
|
+
reject:
|
|
115
|
+
- "/^.$/"
|
|
116
|
+
- "/[0-9]$/"
|
|
117
|
+
- "/[A-Z]/"
|
|
118
|
+
accept:
|
|
119
|
+
- "/^_$/"
|
|
120
|
+
UnusedParameters:
|
|
121
|
+
enabled: true
|
|
122
|
+
exclude: []
|
|
123
|
+
UnusedPrivateMethod:
|
|
124
|
+
enabled: false
|
|
125
|
+
exclude: []
|
|
126
|
+
UtilityFunction:
|
|
127
|
+
enabled: true
|
|
128
|
+
exclude: []
|
|
129
|
+
public_methods_only: false
|
data/docs/yard_plugin.rb
CHANGED
|
@@ -13,4 +13,5 @@ end
|
|
|
13
13
|
|
|
14
14
|
YARD::Templates::Template.extra_includes << LocalLinkHelper
|
|
15
15
|
YARD::Tags::Library.define_tag('Guaranteed public API', :public)
|
|
16
|
+
YARD::Tags::Library.define_tag('Code quality configuration', :quality)
|
|
16
17
|
YARD::Templates::Engine.register_template_path File.join(File.dirname(__FILE__), 'templates')
|
|
@@ -10,6 +10,6 @@ Feature: The Reek CLI maintains backwards compatibility
|
|
|
10
10
|
And it reports:
|
|
11
11
|
"""
|
|
12
12
|
smelly.rb -- 2 warnings:
|
|
13
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
14
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
13
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
14
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
15
15
|
"""
|
|
@@ -37,13 +37,14 @@ Feature: Reek can be controlled using command-line options
|
|
|
37
37
|
reek -s lib
|
|
38
38
|
cat my_class.rb | reek
|
|
39
39
|
|
|
40
|
-
See https://
|
|
40
|
+
See https://github.com/troessner/reek for detailed help.
|
|
41
41
|
|
|
42
42
|
Configuration:
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
|
44
44
|
--smell SMELL Only look for a specific smell.
|
|
45
|
-
Call it like this: reek --smell
|
|
46
|
-
Check out https://github.com/troessner/reek/blob/
|
|
45
|
+
Call it like this: reek --smell MissingSafeMethod source.rb
|
|
46
|
+
Check out https://github.com/troessner/reek/blob/v5.0.0/docs/Code-Smells.md for a list of smells
|
|
47
|
+
--stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
|
|
47
48
|
|
|
48
49
|
Generate a todo list:
|
|
49
50
|
-t, --todo Generate a todo list
|
|
@@ -60,7 +61,7 @@ Feature: Reek can be controlled using command-line options
|
|
|
60
61
|
Text format options:
|
|
61
62
|
--[no-]color Use colors for the output (default: true)
|
|
62
63
|
-V, --[no-]empty-headings Show headings for smell-free source files (default: false)
|
|
63
|
-
-U, --[no-]
|
|
64
|
+
-U, --[no-]documentation Show link to related documentation page for each smell (default: true)
|
|
64
65
|
-n, --[no-]line-numbers Show line numbers in the output (default: true)
|
|
65
66
|
-s, --single-line Show location in editor-compatible single-line-per-smell format
|
|
66
67
|
-P, --[no-]progress Show progress of each source as it is examined (default: true)
|
|
@@ -76,5 +77,46 @@ Feature: Reek can be controlled using command-line options
|
|
|
76
77
|
|
|
77
78
|
Utility options:
|
|
78
79
|
-h, --help Show this message
|
|
80
|
+
-l, --list List all available smell detectors
|
|
79
81
|
-v, --version Show version
|
|
80
82
|
"""
|
|
83
|
+
|
|
84
|
+
Scenario: List all available smell detectors
|
|
85
|
+
When I run reek --list
|
|
86
|
+
Then it succeeds
|
|
87
|
+
And it reports:
|
|
88
|
+
"""
|
|
89
|
+
All available smell detectors:
|
|
90
|
+
|
|
91
|
+
Attribute
|
|
92
|
+
BooleanParameter
|
|
93
|
+
ClassVariable
|
|
94
|
+
ControlParameter
|
|
95
|
+
DataClump
|
|
96
|
+
DuplicateMethodCall
|
|
97
|
+
FeatureEnvy
|
|
98
|
+
InstanceVariableAssumption
|
|
99
|
+
IrresponsibleModule
|
|
100
|
+
LongParameterList
|
|
101
|
+
LongYieldList
|
|
102
|
+
ManualDispatch
|
|
103
|
+
MissingSafeMethod
|
|
104
|
+
ModuleInitialize
|
|
105
|
+
NestedIterators
|
|
106
|
+
NilCheck
|
|
107
|
+
RepeatedConditional
|
|
108
|
+
SubclassedFromCoreClass
|
|
109
|
+
TooManyConstants
|
|
110
|
+
TooManyInstanceVariables
|
|
111
|
+
TooManyMethods
|
|
112
|
+
TooManyStatements
|
|
113
|
+
UncommunicativeMethodName
|
|
114
|
+
UncommunicativeModuleName
|
|
115
|
+
UncommunicativeParameterName
|
|
116
|
+
UncommunicativeVariableName
|
|
117
|
+
UnusedParameters
|
|
118
|
+
UnusedPrivateMethod
|
|
119
|
+
UtilityFunction
|
|
120
|
+
|
|
121
|
+
Check out https://github.com/troessner/reek/blob/v5.0.0/docs/Code-Smells.md for a details on each detector
|
|
122
|
+
"""
|
|
@@ -15,8 +15,8 @@ Feature: Show progress
|
|
|
15
15
|
.S
|
|
16
16
|
|
|
17
17
|
mixed_files/dirty.rb -- 2 warnings:
|
|
18
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
19
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
18
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
19
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
20
20
|
2 total warnings
|
|
21
21
|
"""
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ Feature: Show progress
|
|
|
27
27
|
And it reports:
|
|
28
28
|
"""
|
|
29
29
|
mixed_files/dirty.rb -- 2 warnings:
|
|
30
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
31
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
30
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
31
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
32
32
|
2 total warnings
|
|
33
33
|
"""
|
|
@@ -11,5 +11,5 @@ Feature: Smell selection
|
|
|
11
11
|
And it reports:
|
|
12
12
|
"""
|
|
13
13
|
smelly.rb -- 1 warning:
|
|
14
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
14
|
+
UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
15
15
|
"""
|
|
@@ -9,8 +9,8 @@ Feature: Reports total number of code smells
|
|
|
9
9
|
And it reports:
|
|
10
10
|
"""
|
|
11
11
|
smelly.rb -- 2 warnings:
|
|
12
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
13
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
12
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
13
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
Scenario: Output total number of smells when inspecting multiple files
|
|
@@ -20,11 +20,11 @@ Feature: Reports total number of code smells
|
|
|
20
20
|
And it reports:
|
|
21
21
|
"""
|
|
22
22
|
smelly/dirty_one.rb -- 2 warnings:
|
|
23
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
24
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
23
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
24
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
25
25
|
smelly/dirty_two.rb -- 2 warnings:
|
|
26
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
27
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
26
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
27
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
28
28
|
4 total warnings
|
|
29
29
|
"""
|
|
30
30
|
|
|
@@ -27,13 +27,39 @@ Feature: Reek reads from $stdin when no files are given
|
|
|
27
27
|
And it reports:
|
|
28
28
|
"""
|
|
29
29
|
STDIN -- 3 warnings:
|
|
30
|
-
[1]:IrresponsibleModule: Turn has no descriptive comment
|
|
31
|
-
[1]:UncommunicativeMethodName: Turn#y has the name 'y'
|
|
32
|
-
[1]:UncommunicativeVariableName: Turn has the variable name '@x'
|
|
30
|
+
[1]:IrresponsibleModule: Turn has no descriptive comment
|
|
31
|
+
[1]:UncommunicativeMethodName: Turn#y has the name 'y'
|
|
32
|
+
[1]:UncommunicativeVariableName: Turn has the variable name '@x'
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
35
|
Scenario: syntax error causes the source to be ignored
|
|
36
36
|
When I pass "= invalid syntax =" to reek
|
|
37
|
-
Then it
|
|
38
|
-
And the
|
|
37
|
+
Then it succeeds
|
|
38
|
+
And it reports the error "Parser::SyntaxError: unexpected token tEQL"
|
|
39
|
+
|
|
40
|
+
Scenario: providing a filename to use for the config to match against
|
|
41
|
+
Given a file named "web_app/config.reek" with:
|
|
42
|
+
"""
|
|
43
|
+
---
|
|
44
|
+
directories:
|
|
45
|
+
"web_app/app/controllers":
|
|
46
|
+
IrresponsibleModule:
|
|
47
|
+
enabled: false
|
|
48
|
+
NestedIterators:
|
|
49
|
+
enabled: false
|
|
50
|
+
InstanceVariableAssumption:
|
|
51
|
+
enabled: false
|
|
52
|
+
"""
|
|
53
|
+
When I pass a stdin to reek --config web_app/config.reek --stdin-filename web_app/app/controllers/users_controller with:
|
|
54
|
+
"""
|
|
55
|
+
class UsersController < ApplicationController
|
|
56
|
+
def show
|
|
57
|
+
respond_with do |format|
|
|
58
|
+
format.json { |json| @user.to_custom_json }
|
|
59
|
+
format.xml { |xml| @user.to_fancy_xml }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
"""
|
|
64
|
+
Then it succeeds
|
|
39
65
|
And it reports nothing
|
|
@@ -3,20 +3,25 @@ Feature: `accept` configuration setting
|
|
|
3
3
|
As a user
|
|
4
4
|
I want to be able to accept specific patterns and names to exclude them from reporting
|
|
5
5
|
|
|
6
|
-
Scenario: Accept names
|
|
6
|
+
Scenario: Accept names
|
|
7
7
|
Given a file named "config.reek" with:
|
|
8
8
|
"""
|
|
9
9
|
---
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
detectors:
|
|
11
|
+
UncommunicativeMethodName:
|
|
12
|
+
accept:
|
|
13
|
+
- m1
|
|
14
|
+
- m2
|
|
15
|
+
UncommunicativeParameterName:
|
|
16
|
+
accept:
|
|
17
|
+
- a1
|
|
18
|
+
- a2
|
|
19
|
+
UncommunicativeModuleName:
|
|
20
|
+
accept:
|
|
21
|
+
- C1
|
|
22
|
+
UncommunicativeVariableName:
|
|
23
|
+
accept:
|
|
24
|
+
- var1
|
|
20
25
|
"""
|
|
21
26
|
And a file named "smelly.rb" with:
|
|
22
27
|
"""
|
|
@@ -28,28 +33,37 @@ Feature: `accept` configuration setting
|
|
|
28
33
|
def m2(a2); a2; end
|
|
29
34
|
# Should report UncommunicativeMethodName and UncommunicativeParameterName
|
|
30
35
|
def m3(a3); a3; end
|
|
36
|
+
var1 = 2 # Should not report UncommunicativeVariableName
|
|
37
|
+
myvar1 = 2 # Should not report UncommunicativeVariableName
|
|
38
|
+
var2 = 2 # Should report UncommunicativeVariableName
|
|
31
39
|
end
|
|
32
40
|
"""
|
|
33
|
-
When I run
|
|
41
|
+
When I run reek -c config.reek smelly.rb
|
|
34
42
|
Then it reports:
|
|
35
43
|
"""
|
|
36
|
-
smelly.rb --
|
|
37
|
-
[8]:UncommunicativeMethodName: C1#m3 has the name 'm3'
|
|
38
|
-
[8]:UncommunicativeParameterName: C1#m3 has the parameter name 'a3'
|
|
44
|
+
smelly.rb -- 3 warnings:
|
|
45
|
+
[8]:UncommunicativeMethodName: C1#m3 has the name 'm3'
|
|
46
|
+
[8]:UncommunicativeParameterName: C1#m3 has the parameter name 'a3'
|
|
47
|
+
[11]:UncommunicativeVariableName: C1 has the variable name 'var2'
|
|
39
48
|
"""
|
|
40
49
|
|
|
41
|
-
Scenario: Accept regexes
|
|
50
|
+
Scenario: Accept regexes
|
|
42
51
|
Given a file named "config.reek" with:
|
|
43
52
|
"""
|
|
44
53
|
---
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
detectors:
|
|
55
|
+
UncommunicativeMethodName:
|
|
56
|
+
accept:
|
|
57
|
+
- /oobar/
|
|
58
|
+
UncommunicativeParameterName:
|
|
59
|
+
accept:
|
|
60
|
+
- /ola/
|
|
61
|
+
UncommunicativeModuleName:
|
|
62
|
+
accept:
|
|
63
|
+
- /lassy/
|
|
64
|
+
UncommunicativeVariableName:
|
|
65
|
+
accept:
|
|
66
|
+
- /^var1/
|
|
53
67
|
"""
|
|
54
68
|
And a file named "smelly.rb" with:
|
|
55
69
|
"""
|
|
@@ -59,12 +73,15 @@ Feature: `accept` configuration setting
|
|
|
59
73
|
def foobar1(hola1); hola1; end
|
|
60
74
|
# Should report UncommunicativeMethodName and UncommunicativeParameterName
|
|
61
75
|
def m2(a2); a2; end
|
|
76
|
+
var1 = 2 # Should not report UncommunicativeVariableName
|
|
77
|
+
myvar1 = 2 # Should report UncommunicativeVariableName
|
|
62
78
|
end
|
|
63
79
|
"""
|
|
64
|
-
When I run
|
|
80
|
+
When I run reek -c config.reek smelly.rb
|
|
65
81
|
Then it reports:
|
|
66
82
|
"""
|
|
67
|
-
smelly.rb --
|
|
68
|
-
[6]:UncommunicativeMethodName: Classy1#m2 has the name 'm2'
|
|
69
|
-
[6]:UncommunicativeParameterName: Classy1#m2 has the parameter name 'a2'
|
|
83
|
+
smelly.rb -- 3 warnings:
|
|
84
|
+
[6]:UncommunicativeMethodName: Classy1#m2 has the name 'm2'
|
|
85
|
+
[6]:UncommunicativeParameterName: Classy1#m2 has the parameter name 'a2'
|
|
86
|
+
[8]:UncommunicativeVariableName: Classy1 has the variable name 'myvar1'
|
|
70
87
|
"""
|