reek 4.7.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 +36 -7
- data/.simplecov +1 -0
- data/.travis.yml +3 -9
- data/.yardopts +1 -1
- data/CHANGELOG.md +59 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +5 -5
- data/README.md +134 -104
- data/Rakefile +16 -3
- data/bin/reek +1 -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 +30 -8
- 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/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 +2 -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/builder.rb +1 -1
- data/lib/reek/ast/node.rb +40 -58
- data/lib/reek/ast/object_refs.rb +1 -1
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/case.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +8 -1
- data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +4 -6
- data/lib/reek/ast/sexp_extensions/send.rb +0 -4
- data/lib/reek/cli/application.rb +4 -3
- data/lib/reek/cli/command/report_command.rb +1 -2
- data/lib/reek/cli/command/todo_list_command.rb +8 -8
- data/lib/reek/cli/options.rb +31 -16
- data/lib/reek/cli/silencer.rb +14 -3
- data/lib/reek/code_comment.rb +14 -16
- data/lib/reek/configuration/app_configuration.rb +32 -27
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +16 -41
- data/lib/reek/configuration/configuration_validator.rb +12 -23
- data/lib/reek/configuration/default_directive.rb +17 -3
- data/lib/reek/configuration/directory_directives.rb +17 -11
- data/lib/reek/configuration/excluded_paths.rb +1 -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 +3 -3
- data/lib/reek/context/code_context.rb +47 -43
- data/lib/reek/context/ghost_context.rb +0 -2
- data/lib/reek/context/method_context.rb +22 -15
- data/lib/reek/context/module_context.rb +5 -9
- data/lib/reek/context/root_context.rb +0 -4
- data/lib/reek/context/send_context.rb +2 -2
- data/lib/reek/context_builder.rb +43 -44
- data/lib/reek/detector_repository.rb +11 -11
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +14 -13
- data/lib/reek/errors/bad_detector_in_comment_error.rb +12 -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 +13 -12
- data/lib/reek/errors/incomprehensible_source_error.rb +22 -24
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +24 -26
- data/lib/reek/logging_error_handler.rb +7 -5
- data/lib/reek/rake/task.rb +8 -4
- data/lib/reek/report/base_report.rb +8 -12
- data/lib/reek/report/code_climate/code_climate_configuration.rb +1 -1
- data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -10
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/json_report.rb +1 -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 +1 -2
- data/lib/reek/report/xml_report.rb +3 -3
- data/lib/reek/report/yaml_report.rb +1 -1
- data/lib/reek/report.rb +15 -10
- data/lib/reek/smell_configuration.rb +2 -2
- data/lib/reek/smell_detectors/attribute.rb +5 -11
- data/lib/reek/smell_detectors/base_detector.rb +30 -26
- data/lib/reek/smell_detectors/boolean_parameter.rb +3 -5
- data/lib/reek/smell_detectors/class_variable.rb +5 -14
- data/lib/reek/smell_detectors/control_parameter.rb +18 -33
- data/lib/reek/smell_detectors/data_clump.rb +15 -9
- data/lib/reek/smell_detectors/duplicate_method_call.rb +23 -17
- data/lib/reek/smell_detectors/feature_envy.rb +9 -7
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +14 -23
- data/lib/reek/smell_detectors/irresponsible_module.rb +5 -12
- data/lib/reek/smell_detectors/long_parameter_list.rb +10 -7
- data/lib/reek/smell_detectors/long_yield_list.rb +10 -7
- data/lib/reek/smell_detectors/manual_dispatch.rb +4 -5
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +20 -20
- data/lib/reek/smell_detectors/module_initialize.rb +3 -5
- data/lib/reek/smell_detectors/nested_iterators.rb +16 -24
- data/lib/reek/smell_detectors/nil_check.rb +8 -15
- data/lib/reek/smell_detectors/repeated_conditional.rb +13 -11
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +7 -8
- data/lib/reek/smell_detectors/too_many_constants.rb +10 -9
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +10 -6
- data/lib/reek/smell_detectors/too_many_methods.rb +11 -7
- data/lib/reek/smell_detectors/too_many_statements.rb +10 -6
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +10 -11
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +14 -18
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +17 -22
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +26 -27
- data/lib/reek/smell_detectors/unused_parameters.rb +4 -6
- data/lib/reek/smell_detectors/unused_private_method.rb +11 -18
- data/lib/reek/smell_detectors/utility_function.rb +12 -16
- data/lib/reek/smell_detectors.rb +1 -2
- data/lib/reek/smell_warning.rb +15 -8
- data/lib/reek/source/source_code.rb +57 -58
- data/lib/reek/source/source_locator.rb +8 -8
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +9 -16
- data/lib/reek/spec/should_reek_only_of.rb +4 -4
- data/lib/reek/spec.rb +6 -6
- data/lib/reek/tree_dresser.rb +8 -8
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +5 -7
- 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 +14 -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_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 +136 -29
- data/spec/reek/rake/task_spec.rb +25 -2
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- 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 +9 -38
- 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 +0 -11
- 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 +22 -21
- data/spec/reek/source/source_locator_spec.rb +17 -17
- data/spec/reek/spec/should_reek_of_spec.rb +25 -29
- 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 +6 -17
- data/tasks/configuration.rake +8 -5
- metadata +74 -41
- data/defaults.reek +0 -131
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/report/formatter/heading_formatter.rb +0 -52
- data/lib/reek/report/formatter/location_formatter.rb +0 -42
- data/lib/reek/report/formatter/progress_formatter.rb +0 -81
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -36
- data/lib/reek/report/formatter.rb +0 -33
- data/lib/reek/smell_detectors/syntax.rb +0 -37
- 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/syntax_spec.rb +0 -17
- /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
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: map
|
|
3
|
+
mapping:
|
|
4
|
+
"detectors":
|
|
5
|
+
type: map
|
|
6
|
+
mapping: &all_detectors
|
|
7
|
+
Attribute:
|
|
8
|
+
type: map
|
|
9
|
+
mapping: &detector_base
|
|
10
|
+
"enabled":
|
|
11
|
+
type: bool
|
|
12
|
+
"exclude":
|
|
13
|
+
type: seq
|
|
14
|
+
sequence:
|
|
15
|
+
- type: str
|
|
16
|
+
BooleanParameter:
|
|
17
|
+
type: map
|
|
18
|
+
mapping:
|
|
19
|
+
<<: *detector_base
|
|
20
|
+
ClassVariable:
|
|
21
|
+
type: map
|
|
22
|
+
mapping:
|
|
23
|
+
<<: *detector_base
|
|
24
|
+
ControlParameter:
|
|
25
|
+
type: map
|
|
26
|
+
mapping:
|
|
27
|
+
<<: *detector_base
|
|
28
|
+
DataClump:
|
|
29
|
+
type: map
|
|
30
|
+
mapping:
|
|
31
|
+
<<: *detector_base
|
|
32
|
+
max_copies:
|
|
33
|
+
type: number
|
|
34
|
+
min_clump_size:
|
|
35
|
+
type: number
|
|
36
|
+
DuplicateMethodCall:
|
|
37
|
+
type: map
|
|
38
|
+
mapping:
|
|
39
|
+
<<: *detector_base
|
|
40
|
+
max_calls:
|
|
41
|
+
type: number
|
|
42
|
+
allow_calls:
|
|
43
|
+
type: seq
|
|
44
|
+
sequence:
|
|
45
|
+
- type: str
|
|
46
|
+
FeatureEnvy:
|
|
47
|
+
type: map
|
|
48
|
+
mapping:
|
|
49
|
+
<<: *detector_base
|
|
50
|
+
InstanceVariableAssumption:
|
|
51
|
+
type: map
|
|
52
|
+
mapping:
|
|
53
|
+
<<: *detector_base
|
|
54
|
+
IrresponsibleModule:
|
|
55
|
+
type: map
|
|
56
|
+
mapping:
|
|
57
|
+
<<: *detector_base
|
|
58
|
+
LongParameterList:
|
|
59
|
+
type: map
|
|
60
|
+
mapping:
|
|
61
|
+
<<: *detector_base
|
|
62
|
+
max_params:
|
|
63
|
+
type: number
|
|
64
|
+
overrides:
|
|
65
|
+
type: map
|
|
66
|
+
mapping:
|
|
67
|
+
initialize:
|
|
68
|
+
type: map
|
|
69
|
+
mapping:
|
|
70
|
+
max_params:
|
|
71
|
+
type: number
|
|
72
|
+
LongYieldList:
|
|
73
|
+
type: map
|
|
74
|
+
mapping:
|
|
75
|
+
<<: *detector_base
|
|
76
|
+
max_params:
|
|
77
|
+
type: number
|
|
78
|
+
ManualDispatch:
|
|
79
|
+
type: map
|
|
80
|
+
mapping:
|
|
81
|
+
<<: *detector_base
|
|
82
|
+
MissingSafeMethod:
|
|
83
|
+
type: map
|
|
84
|
+
mapping:
|
|
85
|
+
<<: *detector_base
|
|
86
|
+
ModuleInitialize:
|
|
87
|
+
type: map
|
|
88
|
+
mapping:
|
|
89
|
+
<<: *detector_base
|
|
90
|
+
NestedIterators:
|
|
91
|
+
type: map
|
|
92
|
+
mapping:
|
|
93
|
+
<<: *detector_base
|
|
94
|
+
max_allowed_nesting:
|
|
95
|
+
type: number
|
|
96
|
+
ignore_iterators:
|
|
97
|
+
type: seq
|
|
98
|
+
sequence:
|
|
99
|
+
- type: str
|
|
100
|
+
NilCheck:
|
|
101
|
+
type: map
|
|
102
|
+
mapping:
|
|
103
|
+
<<: *detector_base
|
|
104
|
+
RepeatedConditional:
|
|
105
|
+
type: map
|
|
106
|
+
mapping:
|
|
107
|
+
<<: *detector_base
|
|
108
|
+
max_ifs:
|
|
109
|
+
type: number
|
|
110
|
+
SubclassedFromCoreClass:
|
|
111
|
+
type: map
|
|
112
|
+
mapping:
|
|
113
|
+
<<: *detector_base
|
|
114
|
+
Syntax:
|
|
115
|
+
type: map
|
|
116
|
+
mapping:
|
|
117
|
+
<<: *detector_base
|
|
118
|
+
TooManyConstants:
|
|
119
|
+
type: map
|
|
120
|
+
mapping:
|
|
121
|
+
<<: *detector_base
|
|
122
|
+
max_constants:
|
|
123
|
+
type: number
|
|
124
|
+
TooManyInstanceVariables:
|
|
125
|
+
type: map
|
|
126
|
+
mapping:
|
|
127
|
+
<<: *detector_base
|
|
128
|
+
max_instance_variables:
|
|
129
|
+
type: number
|
|
130
|
+
TooManyMethods:
|
|
131
|
+
type: map
|
|
132
|
+
mapping:
|
|
133
|
+
<<: *detector_base
|
|
134
|
+
max_methods:
|
|
135
|
+
type: number
|
|
136
|
+
TooManyStatements:
|
|
137
|
+
type: map
|
|
138
|
+
mapping:
|
|
139
|
+
<<: *detector_base
|
|
140
|
+
max_statements:
|
|
141
|
+
type: number
|
|
142
|
+
UncommunicativeMethodName:
|
|
143
|
+
type: map
|
|
144
|
+
mapping:
|
|
145
|
+
<<: *detector_base
|
|
146
|
+
reject: &reject_settings
|
|
147
|
+
type: seq
|
|
148
|
+
sequence:
|
|
149
|
+
- type: str
|
|
150
|
+
accept: &accept_settings
|
|
151
|
+
type: seq
|
|
152
|
+
sequence:
|
|
153
|
+
- type: str
|
|
154
|
+
UncommunicativeModuleName:
|
|
155
|
+
type: map
|
|
156
|
+
mapping:
|
|
157
|
+
<<: *detector_base
|
|
158
|
+
reject: *reject_settings
|
|
159
|
+
accept: *accept_settings
|
|
160
|
+
UncommunicativeParameterName:
|
|
161
|
+
type: map
|
|
162
|
+
mapping:
|
|
163
|
+
<<: *detector_base
|
|
164
|
+
reject: *reject_settings
|
|
165
|
+
accept: *accept_settings
|
|
166
|
+
UncommunicativeVariableName:
|
|
167
|
+
type: map
|
|
168
|
+
mapping:
|
|
169
|
+
<<: *detector_base
|
|
170
|
+
reject: *reject_settings
|
|
171
|
+
accept: *accept_settings
|
|
172
|
+
UnusedParameters:
|
|
173
|
+
type: map
|
|
174
|
+
mapping:
|
|
175
|
+
<<: *detector_base
|
|
176
|
+
UnusedPrivateMethod:
|
|
177
|
+
type: map
|
|
178
|
+
mapping:
|
|
179
|
+
<<: *detector_base
|
|
180
|
+
UtilityFunction:
|
|
181
|
+
type: map
|
|
182
|
+
mapping:
|
|
183
|
+
<<: *detector_base
|
|
184
|
+
public_methods_only:
|
|
185
|
+
type: bool
|
|
186
|
+
|
|
187
|
+
"directories":
|
|
188
|
+
type: map
|
|
189
|
+
mapping:
|
|
190
|
+
# For any given key that is not matched somewhere else we'll apply the schema below.
|
|
191
|
+
# So this will just slurp in every directory we throw at it and then validate everything under
|
|
192
|
+
# it against all detectors - for instance:
|
|
193
|
+
#
|
|
194
|
+
# directories:
|
|
195
|
+
# "web_app/app/controllers":
|
|
196
|
+
# NestedIterators:
|
|
197
|
+
# enabled: false
|
|
198
|
+
# "web_app/app/helpers":
|
|
199
|
+
# UtilityFunction:
|
|
200
|
+
# enabled: false
|
|
201
|
+
#
|
|
202
|
+
# For details check out: http://www.kuwata-lab.com/kwalify/ruby/users-guide.02.html#tips-default
|
|
203
|
+
=:
|
|
204
|
+
type: map
|
|
205
|
+
mapping: *all_detectors
|
|
206
|
+
|
|
207
|
+
"exclude_paths":
|
|
208
|
+
type: seq
|
|
209
|
+
sequence:
|
|
210
|
+
- type: str
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require_relative '../cli/silencer'
|
|
5
|
+
Reek::CLI::Silencer.without_warnings { require 'kwalify' }
|
|
6
|
+
require_relative '../errors/config_file_error'
|
|
7
|
+
|
|
8
|
+
module Reek
|
|
9
|
+
module Configuration
|
|
10
|
+
#
|
|
11
|
+
# Schema validator module.
|
|
12
|
+
#
|
|
13
|
+
class SchemaValidator
|
|
14
|
+
SCHEMA_FILE_PATH = File.expand_path('./schema.yml', __dir__)
|
|
15
|
+
|
|
16
|
+
def initialize(configuration)
|
|
17
|
+
@configuration = configuration
|
|
18
|
+
@validator = CLI::Silencer.without_warnings do
|
|
19
|
+
schema_file = Kwalify::Yaml.load_file(SCHEMA_FILE_PATH)
|
|
20
|
+
Kwalify::Validator.new(schema_file)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate
|
|
25
|
+
errors = CLI::Silencer.without_warnings { @validator.validate @configuration }
|
|
26
|
+
return if !errors || errors.empty?
|
|
27
|
+
raise Errors::ConfigFileError, error_message(errors)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# :reek:UtilityFunction
|
|
33
|
+
def error_message(errors)
|
|
34
|
+
"We found some problems with your configuration file: #{CLI::Silencer.silently { errors.join(', ') }}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -7,14 +7,14 @@ module Reek
|
|
|
7
7
|
#
|
|
8
8
|
# A context wrapper for attribute definitions found in a syntax tree.
|
|
9
9
|
#
|
|
10
|
-
# :reek:Attribute
|
|
10
|
+
# @quality :reek:Attribute
|
|
11
11
|
class AttributeContext < CodeContext
|
|
12
12
|
attr_accessor :visibility
|
|
13
13
|
|
|
14
|
-
def initialize(
|
|
14
|
+
def initialize(exp, send_expression)
|
|
15
15
|
@visibility = :public
|
|
16
16
|
@send_expression = send_expression
|
|
17
|
-
super
|
|
17
|
+
super exp
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def full_comment
|
|
@@ -14,51 +14,19 @@ module Reek
|
|
|
14
14
|
# code element. CodeContexts form a tree in the same way the code does,
|
|
15
15
|
# with each context holding a reference to a unique outer context.
|
|
16
16
|
#
|
|
17
|
-
# :reek:TooManyMethods
|
|
18
|
-
# :reek:TooManyInstanceVariables
|
|
17
|
+
# @quality :reek:TooManyMethods { max_methods: 19 }
|
|
18
|
+
# @quality :reek:TooManyInstanceVariables { max_instance_variables: 8 }
|
|
19
19
|
class CodeContext
|
|
20
20
|
include Enumerable
|
|
21
21
|
extend Forwardable
|
|
22
|
-
delegate each_node: :exp
|
|
23
22
|
delegate [:name, :type] => :exp
|
|
24
23
|
|
|
25
24
|
attr_reader :children, :parent, :exp, :statement_counter
|
|
26
25
|
|
|
27
26
|
# Initializes a new CodeContext.
|
|
28
27
|
#
|
|
29
|
-
# @param _parent [CodeContext, nil] The parent context
|
|
30
28
|
# @param exp [Reek::AST::Node] The code described by this context
|
|
31
|
-
|
|
32
|
-
# For example, given the following code:
|
|
33
|
-
#
|
|
34
|
-
# class Omg
|
|
35
|
-
# def foo(x)
|
|
36
|
-
# puts x
|
|
37
|
-
# end
|
|
38
|
-
# end
|
|
39
|
-
#
|
|
40
|
-
# The {ContextBuilder} object first instantiates a {RootContext}, which has no parent.
|
|
41
|
-
#
|
|
42
|
-
# Next, it instantiates a {ModuleContext}, with +parent+ being the
|
|
43
|
-
# {RootContext} just created, and +exp+ looking like this:
|
|
44
|
-
#
|
|
45
|
-
# (class
|
|
46
|
-
# (const nil :Omg) nil
|
|
47
|
-
# (def :foo
|
|
48
|
-
# (args
|
|
49
|
-
# (arg :x))
|
|
50
|
-
# (send nil :puts
|
|
51
|
-
# (lvar :x))))
|
|
52
|
-
#
|
|
53
|
-
# Finally, {ContextBuilder} will instantiate a {MethodContext}. This time,
|
|
54
|
-
# +parent+ is the {ModuleContext} created above, and +exp+ is:
|
|
55
|
-
#
|
|
56
|
-
# (def :foo
|
|
57
|
-
# (args
|
|
58
|
-
# (arg :x))
|
|
59
|
-
# (send nil :puts
|
|
60
|
-
# (lvar :x)))
|
|
61
|
-
def initialize(_parent, exp)
|
|
29
|
+
def initialize(exp)
|
|
62
30
|
@exp = exp
|
|
63
31
|
@children = []
|
|
64
32
|
@statement_counter = StatementCounter.new
|
|
@@ -71,12 +39,12 @@ module Reek
|
|
|
71
39
|
# @yield block that is executed for every node.
|
|
72
40
|
#
|
|
73
41
|
def local_nodes(type, ignored = [], &blk)
|
|
74
|
-
ignored
|
|
75
|
-
each_node(type, ignored, &blk)
|
|
42
|
+
ignored |= [:class, :module]
|
|
43
|
+
exp.each_node(type, ignored, &blk)
|
|
76
44
|
end
|
|
77
45
|
|
|
78
46
|
# Iterate over `self` and child contexts.
|
|
79
|
-
# The main difference (among others) to `
|
|
47
|
+
# The main difference (among others) to `local_nodes` is that we are traversing
|
|
80
48
|
# `CodeContexts` here, not AST nodes (see `Reek::AST::Node`).
|
|
81
49
|
#
|
|
82
50
|
# @yield block that is executed for every node.
|
|
@@ -91,6 +59,44 @@ module Reek
|
|
|
91
59
|
end
|
|
92
60
|
end
|
|
93
61
|
|
|
62
|
+
# Link the present context to its parent.
|
|
63
|
+
#
|
|
64
|
+
# @param parent [Reek::AST::Node] The parent context of the code described by this context
|
|
65
|
+
#
|
|
66
|
+
# For example, given the following code:
|
|
67
|
+
#
|
|
68
|
+
# class Omg
|
|
69
|
+
# def foo(x)
|
|
70
|
+
# puts x
|
|
71
|
+
# end
|
|
72
|
+
# end
|
|
73
|
+
#
|
|
74
|
+
# The {ContextBuilder} object first instantiates a {RootContext}, which has no parent.
|
|
75
|
+
#
|
|
76
|
+
# Next, it instantiates a {ModuleContext}, with +exp+ looking like this:
|
|
77
|
+
#
|
|
78
|
+
# (class
|
|
79
|
+
# (const nil :Omg) nil
|
|
80
|
+
# (def :foo
|
|
81
|
+
# (args
|
|
82
|
+
# (arg :x))
|
|
83
|
+
# (send nil :puts
|
|
84
|
+
# (lvar :x))))
|
|
85
|
+
#
|
|
86
|
+
# It will then call #register_with_parent on the {ModuleContext}, passing
|
|
87
|
+
# in the parent {RootContext}.
|
|
88
|
+
#
|
|
89
|
+
# Finally, {ContextBuilder} will instantiate a {MethodContext}. This time,
|
|
90
|
+
# +exp+ is:
|
|
91
|
+
#
|
|
92
|
+
# (def :foo
|
|
93
|
+
# (args
|
|
94
|
+
# (arg :x))
|
|
95
|
+
# (send nil :puts
|
|
96
|
+
# (lvar :x)))
|
|
97
|
+
#
|
|
98
|
+
# Then it will call #register_with_parent on the {MethodContext}, passing
|
|
99
|
+
# in the parent {ModuleContext}.
|
|
94
100
|
def register_with_parent(parent)
|
|
95
101
|
@parent = parent.append_child_context(self) if parent
|
|
96
102
|
end
|
|
@@ -104,17 +110,15 @@ module Reek
|
|
|
104
110
|
self
|
|
105
111
|
end
|
|
106
112
|
|
|
107
|
-
# :reek:TooManyStatements
|
|
108
|
-
# :reek:FeatureEnvy
|
|
113
|
+
# @quality :reek:TooManyStatements { max_statements: 6 }
|
|
114
|
+
# @quality :reek:FeatureEnvy
|
|
109
115
|
def record_call_to(exp)
|
|
110
116
|
receiver = exp.receiver
|
|
111
117
|
type = receiver ? receiver.type : :self
|
|
112
118
|
line = exp.line
|
|
113
119
|
case type
|
|
114
120
|
when :lvar, :lvasgn
|
|
115
|
-
unless exp.object_creation_call?
|
|
116
|
-
refs.record_reference(name: receiver.name, line: line)
|
|
117
|
-
end
|
|
121
|
+
refs.record_reference(name: receiver.name, line: line) unless exp.object_creation_call?
|
|
118
122
|
when :self
|
|
119
123
|
refs.record_reference(name: :self, line: line)
|
|
120
124
|
end
|
|
@@ -7,14 +7,15 @@ module Reek
|
|
|
7
7
|
#
|
|
8
8
|
# A context wrapper for any method definition found in a syntax tree.
|
|
9
9
|
#
|
|
10
|
-
# :reek:Attribute
|
|
10
|
+
# @quality :reek:Attribute
|
|
11
11
|
class MethodContext < CodeContext
|
|
12
12
|
attr_accessor :visibility
|
|
13
13
|
attr_reader :refs
|
|
14
14
|
|
|
15
|
-
def initialize(
|
|
15
|
+
def initialize(exp, parent_exp)
|
|
16
|
+
@parent_exp = parent_exp
|
|
16
17
|
@visibility = :public
|
|
17
|
-
super
|
|
18
|
+
super exp
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def references_self?
|
|
@@ -22,29 +23,24 @@ module Reek
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def uses_param?(param)
|
|
25
|
-
#
|
|
26
|
+
# :lvasgn catches:
|
|
27
|
+
#
|
|
26
28
|
# def foo(bar); bar += 1; end
|
|
27
|
-
# In this example there is no `lvar` node present.
|
|
28
29
|
#
|
|
29
|
-
#
|
|
30
|
+
# :lvar catches:
|
|
31
|
+
#
|
|
30
32
|
# def foo(bar); other(bar); end
|
|
31
33
|
# def foo(bar); tmp = other(bar); tmp[0]; end
|
|
32
34
|
#
|
|
33
|
-
|
|
34
|
-
# This means that if we would just search for [:lvar, :lvasgn]
|
|
35
|
-
# (e.g. via Reek::AST::Node#find_nodes) this would fail for this example since we would
|
|
36
|
-
# stop at the `lvasgn` and not detect the contained `lvar`.
|
|
37
|
-
# Hence we first get all `lvar` nodes followed by all `lvasgn` nodes.
|
|
38
|
-
#
|
|
39
|
-
(local_nodes(:lvar) + local_nodes(:lvasgn)).find { |node| node.var_name == param.to_sym }
|
|
35
|
+
local_nodes([:lvar, :lvasgn]).find { |node| node.var_name == param.name }
|
|
40
36
|
end
|
|
41
37
|
|
|
42
|
-
# :reek:FeatureEnvy
|
|
38
|
+
# @quality :reek:FeatureEnvy
|
|
43
39
|
def unused_params
|
|
44
40
|
exp.arguments.reject do |param|
|
|
45
41
|
param.anonymous_splat? ||
|
|
46
42
|
param.marked_unused? ||
|
|
47
|
-
uses_param?(param
|
|
43
|
+
uses_param?(param)
|
|
48
44
|
end
|
|
49
45
|
end
|
|
50
46
|
|
|
@@ -80,6 +76,17 @@ module Reek
|
|
|
80
76
|
def non_public_visibility?
|
|
81
77
|
visibility != :public
|
|
82
78
|
end
|
|
79
|
+
|
|
80
|
+
def full_comment
|
|
81
|
+
own = super
|
|
82
|
+
return own unless own.empty?
|
|
83
|
+
return parent_exp.full_comment if parent_exp
|
|
84
|
+
''
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
attr_reader :parent_exp
|
|
83
90
|
end
|
|
84
91
|
end
|
|
85
92
|
end
|
|
@@ -13,9 +13,8 @@ module Reek
|
|
|
13
13
|
class ModuleContext < CodeContext
|
|
14
14
|
attr_reader :visibility_tracker
|
|
15
15
|
|
|
16
|
-
def initialize(
|
|
16
|
+
def initialize(exp)
|
|
17
17
|
super
|
|
18
|
-
|
|
19
18
|
@visibility_tracker = VisibilityTracker.new
|
|
20
19
|
end
|
|
21
20
|
|
|
@@ -44,9 +43,9 @@ module Reek
|
|
|
44
43
|
AttributeContext
|
|
45
44
|
end
|
|
46
45
|
|
|
47
|
-
def defined_instance_methods(visibility: :
|
|
46
|
+
def defined_instance_methods(visibility: :any)
|
|
48
47
|
instance_method_children.select do |context|
|
|
49
|
-
context.visibility == visibility
|
|
48
|
+
visibility == :any || context.visibility == visibility
|
|
50
49
|
end
|
|
51
50
|
end
|
|
52
51
|
|
|
@@ -60,7 +59,7 @@ module Reek
|
|
|
60
59
|
# @deprecated use `defined_instance_methods` instead
|
|
61
60
|
#
|
|
62
61
|
def node_instance_methods
|
|
63
|
-
local_nodes(:def)
|
|
62
|
+
local_nodes(:def).to_a
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
def descriptively_commented?
|
|
@@ -74,7 +73,7 @@ module Reek
|
|
|
74
73
|
#
|
|
75
74
|
# @return true if the module is a namespace module
|
|
76
75
|
#
|
|
77
|
-
# :reek:FeatureEnvy
|
|
76
|
+
# @quality :reek:FeatureEnvy
|
|
78
77
|
def namespace_module?
|
|
79
78
|
return false if exp.type == :casgn
|
|
80
79
|
children = exp.direct_children
|
|
@@ -85,9 +84,6 @@ module Reek
|
|
|
85
84
|
visibility_tracker.track_visibility children: instance_method_children,
|
|
86
85
|
visibility: visibility,
|
|
87
86
|
names: names
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def track_singleton_visibility(visibility, names)
|
|
91
87
|
visibility_tracker.track_singleton_visibility children: singleton_method_children,
|
|
92
88
|
visibility: visibility,
|
|
93
89
|
names: names
|