reek 6.0.2 → 6.5.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/.github/dependabot.yml +13 -0
- data/.github/workflows/ruby.yml +58 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +7 -20
- data/.rubocop_todo.yml +6 -4
- data/.simplecov +2 -0
- data/CHANGELOG.md +114 -0
- data/CONTRIBUTING.md +10 -10
- data/Dockerfile +1 -1
- data/Gemfile +17 -24
- data/README.md +38 -40
- data/Rakefile +2 -0
- data/bin/code_climate_reek +56 -8
- data/docs/yard_plugin.rb +3 -1
- data/lib/reek/ast/ast_node_class_map.rb +1 -1
- data/lib/reek/ast/node.rb +16 -10
- data/lib/reek/ast/sexp_extensions/arguments.rb +20 -0
- data/lib/reek/ast/sexp_extensions/case.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +1 -1
- data/lib/reek/ast/sexp_extensions/send.rb +22 -7
- data/lib/reek/cli/command/todo_list_command.rb +3 -3
- data/lib/reek/cli/options.rb +8 -8
- data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.rb +1 -1
- data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.yml +41 -41
- data/lib/reek/{report/code_climate → code_climate}/code_climate_fingerprint.rb +2 -2
- data/lib/reek/{report/code_climate → code_climate}/code_climate_formatter.rb +2 -4
- data/lib/reek/{report/code_climate → code_climate}/code_climate_report.rb +3 -3
- data/lib/reek/code_comment.rb +25 -20
- data/lib/reek/configuration/app_configuration.rb +5 -5
- data/lib/reek/configuration/configuration_converter.rb +1 -1
- data/lib/reek/configuration/configuration_file_finder.rb +5 -4
- data/lib/reek/configuration/default_directive.rb +1 -1
- data/lib/reek/configuration/directory_directives.rb +1 -1
- data/lib/reek/configuration/excluded_paths.rb +3 -2
- data/lib/reek/configuration/schema.rb +177 -0
- data/lib/reek/configuration/schema_validator.rb +12 -13
- data/lib/reek/context/attribute_context.rb +1 -1
- data/lib/reek/context/code_context.rb +3 -3
- data/lib/reek/context/method_context.rb +1 -1
- data/lib/reek/context/module_context.rb +4 -0
- data/lib/reek/context/refinement_context.rb +16 -0
- data/lib/reek/context/send_context.rb +7 -1
- data/lib/reek/context_builder.rb +17 -3
- data/lib/reek/documentation_link.rb +3 -5
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +2 -2
- data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -2
- data/lib/reek/errors/encoding_error.rb +1 -1
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -2
- data/lib/reek/errors/incomprehensible_source_error.rb +1 -1
- data/lib/reek/errors/legacy_comment_separator_error.rb +2 -2
- data/lib/reek/errors/syntax_error.rb +1 -1
- data/lib/reek/rake/task.rb +5 -5
- data/lib/reek/report/github_report.rb +55 -0
- data/lib/reek/report/text_report.rb +1 -1
- data/lib/reek/report.rb +7 -5
- data/lib/reek/smell_detectors/base_detector.rb +1 -1
- data/lib/reek/smell_detectors/class_variable.rb +2 -2
- data/lib/reek/smell_detectors/control_parameter_helpers/candidate.rb +6 -6
- data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +1 -1
- data/lib/reek/smell_detectors/data_clump.rb +1 -1
- data/lib/reek/smell_detectors/duplicate_method_call.rb +5 -5
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +8 -8
- data/lib/reek/smell_detectors/nested_iterators.rb +4 -3
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +1 -1
- data/lib/reek/smell_detectors/unused_private_method.rb +3 -2
- data/lib/reek/smell_warning.rb +1 -1
- data/lib/reek/source/source_code.rb +11 -5
- data/lib/reek/source/source_locator.rb +1 -3
- data/lib/reek/spec/should_reek_of.rb +11 -9
- data/lib/reek/spec.rb +1 -1
- data/lib/reek/version.rb +2 -2
- data/reek.gemspec +33 -25
- metadata +41 -238
- data/.travis.yml +0 -40
- data/docs/API.md +0 -174
- data/docs/Attribute.md +0 -39
- data/docs/Basic-Smell-Options.md +0 -85
- data/docs/Boolean-Parameter.md +0 -54
- data/docs/Class-Variable.md +0 -40
- data/docs/Code-Smells.md +0 -39
- data/docs/Command-Line-Options.md +0 -119
- data/docs/Control-Couple.md +0 -26
- data/docs/Control-Parameter.md +0 -32
- data/docs/Data-Clump.md +0 -46
- data/docs/Duplicate-Method-Call.md +0 -264
- data/docs/Feature-Envy.md +0 -93
- data/docs/How-To-Write-New-Detectors.md +0 -132
- data/docs/How-reek-works-internally.md +0 -114
- data/docs/Instance-Variable-Assumption.md +0 -163
- data/docs/Irresponsible-Module.md +0 -47
- data/docs/Large-Class.md +0 -16
- data/docs/Long-Parameter-List.md +0 -39
- data/docs/Long-Yield-List.md +0 -37
- data/docs/Manual-Dispatch.md +0 -30
- data/docs/Missing-Safe-Method.md +0 -92
- data/docs/Module-Initialize.md +0 -62
- data/docs/Nested-Iterators.md +0 -59
- data/docs/Nil-Check.md +0 -47
- data/docs/RSpec-matchers.md +0 -129
- data/docs/Rake-Task.md +0 -66
- data/docs/Reek-4-to-Reek-5-migration.md +0 -188
- data/docs/Reek-Driven-Development.md +0 -46
- data/docs/Repeated-Conditional.md +0 -47
- data/docs/Simulated-Polymorphism.md +0 -16
- data/docs/Smell-Suppression.md +0 -96
- data/docs/Style-Guide.md +0 -19
- data/docs/Subclassed-From-Core-Class.md +0 -79
- data/docs/Too-Many-Constants.md +0 -37
- data/docs/Too-Many-Instance-Variables.md +0 -43
- data/docs/Too-Many-Methods.md +0 -56
- data/docs/Too-Many-Statements.md +0 -54
- data/docs/Uncommunicative-Method-Name.md +0 -94
- data/docs/Uncommunicative-Module-Name.md +0 -92
- data/docs/Uncommunicative-Name.md +0 -18
- data/docs/Uncommunicative-Parameter-Name.md +0 -90
- data/docs/Uncommunicative-Variable-Name.md +0 -96
- data/docs/Unused-Parameters.md +0 -28
- data/docs/Unused-Private-Method.md +0 -101
- data/docs/Utility-Function.md +0 -56
- data/docs/Versioning-Policy.md +0 -7
- data/docs/YAML-Reports.md +0 -93
- data/docs/defaults.reek.yml +0 -129
- data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
- data/docs/templates/default/docstring/setup.rb +0 -37
- data/docs/templates/default/fulldoc/html/css/common.css +0 -1
- data/features/command_line_interface/basic_usage.feature +0 -15
- data/features/command_line_interface/options.feature +0 -123
- data/features/command_line_interface/show_progress.feature +0 -33
- data/features/command_line_interface/smell_selection.feature +0 -15
- data/features/command_line_interface/smells_count.feature +0 -38
- data/features/command_line_interface/stdin.feature +0 -65
- data/features/configuration_files/accept_setting.feature +0 -87
- data/features/configuration_files/directory_specific_directives.feature +0 -274
- data/features/configuration_files/exclude_directives.feature +0 -35
- data/features/configuration_files/exclude_paths_directives.feature +0 -42
- data/features/configuration_files/masking_smells.feature +0 -94
- data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
- data/features/configuration_files/reject_setting.feature +0 -89
- data/features/configuration_files/schema_validation.feature +0 -59
- data/features/configuration_files/show_configuration_file.feature +0 -44
- data/features/configuration_files/unused_private_method.feature +0 -68
- data/features/configuration_loading.feature +0 -91
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
- data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
- data/features/locales.feature +0 -32
- data/features/programmatic_access.feature +0 -41
- data/features/rake_task/rake_task.feature +0 -138
- data/features/reports/codeclimate.feature +0 -59
- data/features/reports/json.feature +0 -59
- data/features/reports/reports.feature +0 -219
- data/features/reports/yaml.feature +0 -52
- data/features/rspec_matcher.feature +0 -41
- data/features/samples.feature +0 -305
- data/features/step_definitions/.rubocop.yml +0 -5
- data/features/step_definitions/reek_steps.rb +0 -102
- data/features/step_definitions/sample_file_steps.rb +0 -63
- data/features/support/env.rb +0 -33
- data/features/todo_list.feature +0 -108
- data/lib/reek/configuration/schema.yml +0 -210
- data/samples/checkstyle.xml +0 -7
- data/samples/clean_source/clean.rb +0 -6
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
- data/samples/configuration/corrupt.reek +0 -1
- data/samples/configuration/empty.reek +0 -0
- data/samples/configuration/full_configuration.reek +0 -13
- data/samples/configuration/full_mask.reek +0 -6
- data/samples/configuration/home/home.reek.yml +0 -4
- data/samples/configuration/partial_mask.reek +0 -4
- data/samples/configuration/regular_configuration/.reek.yml +0 -4
- data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
- data/samples/configuration/with_excluded_paths.reek +0 -5
- data/samples/no_config_file/.keep +0 -0
- data/samples/paths.rb +0 -5
- data/samples/smelly_source/inline.rb +0 -704
- data/samples/smelly_source/optparse.rb +0 -1788
- data/samples/smelly_source/redcloth.rb +0 -1130
- data/samples/smelly_source/ruby.rb +0 -368
- data/samples/smelly_source/smelly.rb +0 -7
- data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
- data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
- data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
- data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
- data/samples/source_with_non_ruby_files/gibberish +0 -1
- data/samples/source_with_non_ruby_files/python_source.py +0 -1
- data/samples/source_with_non_ruby_files/ruby.rb +0 -6
- data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -15
- data/spec/quality/documentation_spec.rb +0 -41
- data/spec/quality/reek_source_spec.rb +0 -11
- data/spec/reek/ast/node_spec.rb +0 -211
- data/spec/reek/ast/object_refs_spec.rb +0 -83
- data/spec/reek/ast/reference_collector_spec.rb +0 -47
- data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
- data/spec/reek/cli/application_spec.rb +0 -168
- data/spec/reek/cli/command/report_command_spec.rb +0 -44
- data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
- data/spec/reek/cli/options_spec.rb +0 -51
- data/spec/reek/cli/silencer_spec.rb +0 -28
- data/spec/reek/code_comment_spec.rb +0 -184
- data/spec/reek/configuration/app_configuration_spec.rb +0 -195
- data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
- data/spec/reek/configuration/default_directive_spec.rb +0 -13
- data/spec/reek/configuration/directory_directives_spec.rb +0 -122
- data/spec/reek/configuration/excluded_paths_spec.rb +0 -16
- data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
- data/spec/reek/configuration/schema_validator_spec.rb +0 -165
- data/spec/reek/context/code_context_spec.rb +0 -192
- data/spec/reek/context/ghost_context_spec.rb +0 -60
- data/spec/reek/context/method_context_spec.rb +0 -72
- data/spec/reek/context/module_context_spec.rb +0 -55
- data/spec/reek/context/root_context_spec.rb +0 -12
- data/spec/reek/context/statement_counter_spec.rb +0 -24
- data/spec/reek/context_builder_spec.rb +0 -457
- data/spec/reek/detector_repository_spec.rb +0 -22
- data/spec/reek/documentation_link_spec.rb +0 -20
- data/spec/reek/errors/base_error_spec.rb +0 -13
- data/spec/reek/examiner_spec.rb +0 -309
- data/spec/reek/logging_error_handler_spec.rb +0 -24
- data/spec/reek/rake/task_spec.rb +0 -56
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
- data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
- data/spec/reek/report/html_report_spec.rb +0 -19
- data/spec/reek/report/json_report_spec.rb +0 -58
- data/spec/reek/report/location_formatter_spec.rb +0 -32
- data/spec/reek/report/progress_formatter_spec.rb +0 -68
- data/spec/reek/report/text_report_spec.rb +0 -89
- data/spec/reek/report/xml_report_spec.rb +0 -24
- data/spec/reek/report/yaml_report_spec.rb +0 -55
- data/spec/reek/report_spec.rb +0 -28
- data/spec/reek/smell_configuration_spec.rb +0 -56
- data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
- data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
- data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
- data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
- data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
- data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
- data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
- data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
- data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
- data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
- data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
- data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
- data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
- data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
- data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
- data/spec/reek/smell_detectors/utility_function_spec.rb +0 -293
- data/spec/reek/smell_warning_spec.rb +0 -137
- data/spec/reek/source/source_code_spec.rb +0 -79
- data/spec/reek/source/source_locator_spec.rb +0 -166
- data/spec/reek/spec/should_reek_of_spec.rb +0 -153
- data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
- data/spec/reek/spec/should_reek_spec.rb +0 -52
- data/spec/reek/spec/smell_matcher_spec.rb +0 -87
- data/spec/reek/tree_dresser_spec.rb +0 -46
- data/spec/spec_helper.rb +0 -110
- data/tasks/configuration.rake +0 -18
- data/tasks/console.rake +0 -5
- data/tasks/reek.rake +0 -6
- data/tasks/rubocop.rake +0 -11
- data/tasks/test.rake +0 -32
- /data/lib/reek/{report/code_climate.rb → code_climate.rb} +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dry/schema'
|
|
4
|
+
|
|
5
|
+
module Reek
|
|
6
|
+
module Configuration
|
|
7
|
+
#
|
|
8
|
+
# Configuration schema constants.
|
|
9
|
+
#
|
|
10
|
+
class Schema
|
|
11
|
+
# Enable the :info extension so we can introspect
|
|
12
|
+
# your keys and types
|
|
13
|
+
Dry::Schema.load_extensions(:info)
|
|
14
|
+
|
|
15
|
+
# rubocop:disable Metrics/BlockLength
|
|
16
|
+
ALL_DETECTORS_SCHEMA = Dry::Schema.Params do
|
|
17
|
+
optional(:Attribute).filled(:hash) do
|
|
18
|
+
optional(:enabled).filled(:bool)
|
|
19
|
+
optional(:exclude).array(:string)
|
|
20
|
+
end
|
|
21
|
+
optional(:BooleanParameter).filled(:hash) do
|
|
22
|
+
optional(:enabled).filled(:bool)
|
|
23
|
+
optional(:exclude).array(:string)
|
|
24
|
+
end
|
|
25
|
+
optional(:ClassVariable).filled(:hash) do
|
|
26
|
+
optional(:enabled).filled(:bool)
|
|
27
|
+
optional(:exclude).array(:string)
|
|
28
|
+
end
|
|
29
|
+
optional(:ControlParameter).filled(:hash) do
|
|
30
|
+
optional(:enabled).filled(:bool)
|
|
31
|
+
optional(:exclude).array(:string)
|
|
32
|
+
end
|
|
33
|
+
optional(:DataClump).filled(:hash) do
|
|
34
|
+
optional(:enabled).filled(:bool)
|
|
35
|
+
optional(:exclude).array(:string)
|
|
36
|
+
optional(:max_copies).filled(:integer)
|
|
37
|
+
optional(:min_clump_size).filled(:integer)
|
|
38
|
+
end
|
|
39
|
+
optional(:DuplicateMethodCall).filled(:hash) do
|
|
40
|
+
optional(:enabled).filled(:bool)
|
|
41
|
+
optional(:exclude).array(:string)
|
|
42
|
+
optional(:max_calls).filled(:integer)
|
|
43
|
+
optional(:allow_calls).array(:string)
|
|
44
|
+
end
|
|
45
|
+
optional(:FeatureEnvy).filled(:hash) do
|
|
46
|
+
optional(:enabled).filled(:bool)
|
|
47
|
+
optional(:exclude).array(:string)
|
|
48
|
+
end
|
|
49
|
+
optional(:InstanceVariableAssumption).filled(:hash) do
|
|
50
|
+
optional(:enabled).filled(:bool)
|
|
51
|
+
optional(:exclude).array(:string)
|
|
52
|
+
end
|
|
53
|
+
optional(:IrresponsibleModule).filled(:hash) do
|
|
54
|
+
optional(:enabled).filled(:bool)
|
|
55
|
+
optional(:exclude).array(:string)
|
|
56
|
+
end
|
|
57
|
+
optional(:LongParameterList).filled(:hash) do
|
|
58
|
+
optional(:enabled).filled(:bool)
|
|
59
|
+
optional(:exclude).array(:string)
|
|
60
|
+
optional(:max_params).filled(:integer)
|
|
61
|
+
optional(:overrides).filled(:hash) do
|
|
62
|
+
required(:initialize).filled(:hash) do
|
|
63
|
+
required(:max_params).filled(:integer)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
optional(:LongYieldList).filled(:hash) do
|
|
68
|
+
optional(:enabled).filled(:bool)
|
|
69
|
+
optional(:exclude).array(:string)
|
|
70
|
+
optional(:max_params).filled(:integer)
|
|
71
|
+
end
|
|
72
|
+
optional(:ManualDispatch).filled(:hash) do
|
|
73
|
+
optional(:enabled).filled(:bool)
|
|
74
|
+
optional(:exclude).array(:string)
|
|
75
|
+
end
|
|
76
|
+
optional(:MissingSafeMethod).filled(:hash) do
|
|
77
|
+
optional(:enabled).filled(:bool)
|
|
78
|
+
optional(:exclude).array(:string)
|
|
79
|
+
end
|
|
80
|
+
optional(:ModuleInitialize).filled(:hash) do
|
|
81
|
+
optional(:enabled).filled(:bool)
|
|
82
|
+
optional(:exclude).array(:string)
|
|
83
|
+
end
|
|
84
|
+
optional(:NestedIterators).filled(:hash) do
|
|
85
|
+
optional(:enabled).filled(:bool)
|
|
86
|
+
optional(:exclude).array(:string)
|
|
87
|
+
optional(:max_allowed_nesting).filled(:integer)
|
|
88
|
+
optional(:ignore_iterators) { array(:string) & filled? }
|
|
89
|
+
end
|
|
90
|
+
optional(:NilCheck).filled(:hash) do
|
|
91
|
+
optional(:enabled).filled(:bool)
|
|
92
|
+
optional(:exclude).array(:string)
|
|
93
|
+
end
|
|
94
|
+
optional(:RepeatedConditional).filled(:hash) do
|
|
95
|
+
optional(:enabled).filled(:bool)
|
|
96
|
+
optional(:exclude).array(:string)
|
|
97
|
+
optional(:max_ifs).filled(:integer)
|
|
98
|
+
end
|
|
99
|
+
optional(:SubclassedFromCoreClass).filled(:hash) do
|
|
100
|
+
optional(:enabled).filled(:bool)
|
|
101
|
+
optional(:exclude).array(:string)
|
|
102
|
+
end
|
|
103
|
+
optional(:TooManyConstants).filled(:hash) do
|
|
104
|
+
optional(:enabled).filled(:bool)
|
|
105
|
+
optional(:exclude).array(:string)
|
|
106
|
+
optional(:max_constants).filled(:integer)
|
|
107
|
+
end
|
|
108
|
+
optional(:TooManyInstanceVariables).filled(:hash) do
|
|
109
|
+
optional(:enabled).filled(:bool)
|
|
110
|
+
optional(:exclude).array(:string)
|
|
111
|
+
optional(:max_instance_variables).filled(:integer)
|
|
112
|
+
end
|
|
113
|
+
optional(:TooManyMethods).filled(:hash) do
|
|
114
|
+
optional(:enabled).filled(:bool)
|
|
115
|
+
optional(:exclude).array(:string)
|
|
116
|
+
optional(:max_methods).filled(:integer)
|
|
117
|
+
end
|
|
118
|
+
optional(:TooManyStatements).filled(:hash) do
|
|
119
|
+
optional(:enabled).filled(:bool)
|
|
120
|
+
optional(:exclude).array(:string)
|
|
121
|
+
optional(:max_statements).filled(:integer)
|
|
122
|
+
end
|
|
123
|
+
optional(:UncommunicativeMethodName).filled(:hash) do
|
|
124
|
+
optional(:enabled).filled(:bool)
|
|
125
|
+
optional(:exclude).array(:string)
|
|
126
|
+
optional(:reject).array(:string)
|
|
127
|
+
optional(:accept).array(:string)
|
|
128
|
+
end
|
|
129
|
+
optional(:UncommunicativeModuleName).filled(:hash) do
|
|
130
|
+
optional(:enabled).filled(:bool)
|
|
131
|
+
optional(:exclude).array(:string)
|
|
132
|
+
optional(:reject).array(:string)
|
|
133
|
+
optional(:accept).array(:string)
|
|
134
|
+
end
|
|
135
|
+
optional(:UncommunicativeParameterName).filled(:hash) do
|
|
136
|
+
optional(:enabled).filled(:bool)
|
|
137
|
+
optional(:exclude).array(:string)
|
|
138
|
+
optional(:reject).array(:string)
|
|
139
|
+
optional(:accept).array(:string)
|
|
140
|
+
end
|
|
141
|
+
optional(:UncommunicativeVariableName).filled(:hash) do
|
|
142
|
+
optional(:enabled).filled(:bool)
|
|
143
|
+
optional(:exclude).array(:string)
|
|
144
|
+
optional(:reject).array(:string)
|
|
145
|
+
optional(:accept).array(:string)
|
|
146
|
+
end
|
|
147
|
+
optional(:UnusedParameters).filled(:hash) do
|
|
148
|
+
optional(:enabled).filled(:bool)
|
|
149
|
+
optional(:exclude).array(:string)
|
|
150
|
+
end
|
|
151
|
+
optional(:UnusedPrivateMethod).filled(:hash) do
|
|
152
|
+
optional(:enabled).filled(:bool)
|
|
153
|
+
optional(:exclude).array(:string)
|
|
154
|
+
end
|
|
155
|
+
optional(:UtilityFunction).filled(:hash) do
|
|
156
|
+
optional(:enabled).filled(:bool)
|
|
157
|
+
optional(:exclude).array(:string)
|
|
158
|
+
optional(:public_methods_only).filled(:bool)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
# rubocop:enable Metrics/BlockLength
|
|
162
|
+
|
|
163
|
+
# @quality :reek:TooManyStatements { max_statements: 7 }
|
|
164
|
+
def self.schema(directories = [])
|
|
165
|
+
Dry::Schema.Params do
|
|
166
|
+
config.validate_keys = true
|
|
167
|
+
|
|
168
|
+
optional(:detectors).filled(ALL_DETECTORS_SCHEMA)
|
|
169
|
+
optional(:directories).filled(:hash) do
|
|
170
|
+
directories.each { |dir| optional(dir.to_sym).filled(ALL_DETECTORS_SCHEMA) }
|
|
171
|
+
end
|
|
172
|
+
optional(:exclude_paths).array(:string)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'yaml'
|
|
4
|
-
require_relative '../cli/silencer'
|
|
5
|
-
Reek::CLI::Silencer.without_warnings { require 'kwalify' }
|
|
6
3
|
require_relative '../errors/config_file_error'
|
|
4
|
+
require_relative 'schema'
|
|
7
5
|
|
|
8
6
|
module Reek
|
|
9
7
|
module Configuration
|
|
@@ -11,28 +9,29 @@ module Reek
|
|
|
11
9
|
# Schema validator module.
|
|
12
10
|
#
|
|
13
11
|
class SchemaValidator
|
|
14
|
-
SCHEMA_FILE_PATH = File.expand_path('./schema.yml', __dir__)
|
|
15
|
-
|
|
16
12
|
def initialize(configuration)
|
|
17
13
|
@configuration = configuration
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Kwalify::Validator.new(schema_file)
|
|
21
|
-
end
|
|
14
|
+
config_directories = configuration['directories']&.keys || []
|
|
15
|
+
@validator = Reek::Configuration::Schema.schema(config_directories)
|
|
22
16
|
end
|
|
23
17
|
|
|
24
18
|
def validate
|
|
25
|
-
|
|
26
|
-
return if
|
|
19
|
+
result = @validator.call(@configuration)
|
|
20
|
+
return if result.success?
|
|
27
21
|
|
|
28
|
-
raise Errors::ConfigFileError, error_message(errors)
|
|
22
|
+
raise Errors::ConfigFileError, error_message(result.errors)
|
|
23
|
+
rescue NoMethodError
|
|
24
|
+
raise Errors::ConfigFileError, 'unrecognized configuration data'
|
|
29
25
|
end
|
|
30
26
|
|
|
31
27
|
private
|
|
32
28
|
|
|
33
29
|
# :reek:UtilityFunction
|
|
34
30
|
def error_message(errors)
|
|
35
|
-
|
|
31
|
+
messages = errors.map do |error|
|
|
32
|
+
"[/#{error.path.join('/')}] #{error.text}."
|
|
33
|
+
end.join("\n")
|
|
34
|
+
"\n#{messages}"
|
|
36
35
|
end
|
|
37
36
|
end
|
|
38
37
|
end
|
|
@@ -38,9 +38,9 @@ module Reek
|
|
|
38
38
|
# @param type [Symbol] the type of the nodes we are looking for, e.g. :defs.
|
|
39
39
|
# @yield block that is executed for every node.
|
|
40
40
|
#
|
|
41
|
-
def local_nodes(type, ignored = [], &
|
|
41
|
+
def local_nodes(type, ignored = [], &)
|
|
42
42
|
ignored |= [:class, :module]
|
|
43
|
-
exp.each_node(type, ignored, &
|
|
43
|
+
exp.each_node(type, ignored, &)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# Iterate over `self` and child contexts.
|
|
@@ -51,7 +51,7 @@ module Reek
|
|
|
51
51
|
# @return [Enumerator]
|
|
52
52
|
#
|
|
53
53
|
def each(&block)
|
|
54
|
-
return enum_for(:each) unless
|
|
54
|
+
return enum_for(:each) unless block
|
|
55
55
|
|
|
56
56
|
yield self
|
|
57
57
|
children.each do |child|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'module_context'
|
|
4
|
+
|
|
5
|
+
module Reek
|
|
6
|
+
module Context
|
|
7
|
+
#
|
|
8
|
+
# A context wrapper for any refinement blocks found in a syntax tree.
|
|
9
|
+
#
|
|
10
|
+
class RefinementContext < ModuleContext
|
|
11
|
+
def full_name
|
|
12
|
+
exp.call.args.first.name
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/reek/context_builder.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative 'context/class_context'
|
|
|
5
5
|
require_relative 'context/ghost_context'
|
|
6
6
|
require_relative 'context/method_context'
|
|
7
7
|
require_relative 'context/module_context'
|
|
8
|
+
require_relative 'context/refinement_context'
|
|
8
9
|
require_relative 'context/root_context'
|
|
9
10
|
require_relative 'context/send_context'
|
|
10
11
|
require_relative 'context/singleton_attribute_context'
|
|
@@ -20,7 +21,7 @@ module Reek
|
|
|
20
21
|
# counting. Ideally `ContextBuilder` would only build up the context tree and leave the
|
|
21
22
|
# statement and reference counting to the contexts.
|
|
22
23
|
#
|
|
23
|
-
# @quality :reek:TooManyMethods { max_methods:
|
|
24
|
+
# @quality :reek:TooManyMethods { max_methods: 32 }
|
|
24
25
|
# @quality :reek:UnusedPrivateMethod { exclude: [ !ruby/regexp /process_/ ] }
|
|
25
26
|
# @quality :reek:DataClump
|
|
26
27
|
class ContextBuilder
|
|
@@ -263,9 +264,16 @@ module Reek
|
|
|
263
264
|
#
|
|
264
265
|
# Counts non-empty blocks as one statement.
|
|
265
266
|
#
|
|
267
|
+
# A refinement block is handled differently and causes a RefinementContext
|
|
268
|
+
# to be opened.
|
|
269
|
+
#
|
|
266
270
|
def process_block(exp, _parent)
|
|
267
271
|
increase_statement_count_by(exp.block)
|
|
268
|
-
|
|
272
|
+
if exp.call.name == :refine
|
|
273
|
+
handle_refinement_block(exp)
|
|
274
|
+
else
|
|
275
|
+
process(exp)
|
|
276
|
+
end
|
|
269
277
|
end
|
|
270
278
|
|
|
271
279
|
# Handles `begin` and `kwbegin` nodes. `begin` nodes are created implicitly
|
|
@@ -414,7 +422,7 @@ module Reek
|
|
|
414
422
|
# See `process_rescue` for additional reference.
|
|
415
423
|
#
|
|
416
424
|
def process_resbody(exp, _parent)
|
|
417
|
-
increase_statement_count_by(exp.children[1
|
|
425
|
+
increase_statement_count_by(exp.children[1..].compact)
|
|
418
426
|
process(exp)
|
|
419
427
|
end
|
|
420
428
|
|
|
@@ -508,6 +516,12 @@ module Reek
|
|
|
508
516
|
end
|
|
509
517
|
end
|
|
510
518
|
|
|
519
|
+
def handle_refinement_block(exp)
|
|
520
|
+
inside_new_context(Context::RefinementContext, exp) do
|
|
521
|
+
process(exp)
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
511
525
|
def handle_send_for_modules(exp)
|
|
512
526
|
arg_names = exp.args.map { |arg| arg.children.first }
|
|
513
527
|
current_context.track_visibility(exp.name, arg_names)
|
|
@@ -17,12 +17,10 @@ module Reek
|
|
|
17
17
|
Kernel.format(HELP_LINK_TEMPLATE, version: Version::STRING, item: name_to_param(subject))
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# Convert the given subject name to a form that is acceptable in a URL
|
|
20
|
+
# Convert the given subject name to a form that is acceptable in a URL, by
|
|
21
|
+
# dasherizeing it at the start of capitalized words. Spaces are discared.
|
|
21
22
|
def name_to_param(name)
|
|
22
|
-
|
|
23
|
-
# preceded by a space. The space is discarded, the start of the word is
|
|
24
|
-
# not.
|
|
25
|
-
name.split(/ *(?=[A-Z][a-z])/).join('-')
|
|
23
|
+
name.split(/([A-Z][a-z][a-z]*)/).map(&:strip).reject(&:empty?).join('-')
|
|
26
24
|
end
|
|
27
25
|
end
|
|
28
26
|
end
|
|
@@ -8,7 +8,7 @@ module Reek
|
|
|
8
8
|
# Gets raised when trying to configure a detector with an option
|
|
9
9
|
# which is unknown to it.
|
|
10
10
|
class BadDetectorConfigurationKeyInCommentError < BaseError
|
|
11
|
-
UNKNOWN_SMELL_DETECTOR_MESSAGE = <<-MESSAGE
|
|
11
|
+
UNKNOWN_SMELL_DETECTOR_MESSAGE = <<-MESSAGE.freeze
|
|
12
12
|
|
|
13
13
|
Error: You are trying to configure the smell detector '%<detector>s'
|
|
14
14
|
in one of your source code comments with the unknown option %<option>s.
|
|
@@ -32,7 +32,7 @@ module Reek
|
|
|
32
32
|
source: source,
|
|
33
33
|
line: line,
|
|
34
34
|
comment: original_comment)
|
|
35
|
-
super
|
|
35
|
+
super(message)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
end
|
|
@@ -9,7 +9,7 @@ module Reek
|
|
|
9
9
|
# This might happen for multiple reasons. The users might have a typo in
|
|
10
10
|
# his comment or he might use a detector that does not exist anymore.
|
|
11
11
|
class BadDetectorInCommentError < BaseError
|
|
12
|
-
UNKNOWN_SMELL_DETECTOR_MESSAGE = <<-MESSAGE
|
|
12
|
+
UNKNOWN_SMELL_DETECTOR_MESSAGE = <<-MESSAGE.freeze
|
|
13
13
|
|
|
14
14
|
Error: You are trying to configure an unknown smell detector '%<detector>s' in one
|
|
15
15
|
of your source code comments.
|
|
@@ -31,7 +31,7 @@ module Reek
|
|
|
31
31
|
source: source,
|
|
32
32
|
line: line,
|
|
33
33
|
comment: original_comment)
|
|
34
|
-
super
|
|
34
|
+
super(message)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -8,7 +8,7 @@ module Reek
|
|
|
8
8
|
# Gets raised when trying to use a configuration for a detector
|
|
9
9
|
# that can't be parsed into a hash.
|
|
10
10
|
class GarbageDetectorConfigurationInCommentError < BaseError
|
|
11
|
-
BAD_DETECTOR_CONFIGURATION_MESSAGE = <<-MESSAGE
|
|
11
|
+
BAD_DETECTOR_CONFIGURATION_MESSAGE = <<-MESSAGE.freeze
|
|
12
12
|
|
|
13
13
|
Error: You are trying to configure the smell detector '%<detector>s'.
|
|
14
14
|
Unfortunately we cannot parse the configuration you have given.
|
|
@@ -30,7 +30,7 @@ module Reek
|
|
|
30
30
|
source: source,
|
|
31
31
|
line: line,
|
|
32
32
|
comment: original_comment)
|
|
33
|
-
super
|
|
33
|
+
super(message)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -6,7 +6,7 @@ module Reek
|
|
|
6
6
|
module Errors
|
|
7
7
|
# Gets raised for old-style comment configuration format.
|
|
8
8
|
class LegacyCommentSeparatorError < BaseError
|
|
9
|
-
MESSAGE = <<-MESSAGE
|
|
9
|
+
MESSAGE = <<-MESSAGE.freeze
|
|
10
10
|
Error: You are using the legacy configuration format (including three
|
|
11
11
|
colons) to configure Reek in one your source code comments.
|
|
12
12
|
|
|
@@ -29,7 +29,7 @@ module Reek
|
|
|
29
29
|
source: source,
|
|
30
30
|
line: line,
|
|
31
31
|
comment: original_comment)
|
|
32
|
-
super
|
|
32
|
+
super(message)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
end
|
data/lib/reek/rake/task.rb
CHANGED
|
@@ -69,15 +69,15 @@ module Reek
|
|
|
69
69
|
|
|
70
70
|
# @public
|
|
71
71
|
def initialize(name = :reek)
|
|
72
|
-
@config_file = ENV
|
|
72
|
+
@config_file = ENV.fetch('REEK_CFG', nil)
|
|
73
73
|
@name = name
|
|
74
|
-
@reek_opts = ENV
|
|
74
|
+
@reek_opts = ENV.fetch('REEK_OPTS', '')
|
|
75
75
|
@fail_on_error = true
|
|
76
76
|
@verbose = false
|
|
77
77
|
|
|
78
78
|
yield self if block_given?
|
|
79
79
|
|
|
80
|
-
if (reek_src = ENV
|
|
80
|
+
if (reek_src = ENV.fetch('REEK_SRC', nil))
|
|
81
81
|
@source_files = FileList[reek_src]
|
|
82
82
|
end
|
|
83
83
|
@source_files ||= FileList['lib/**/*.rb']
|
|
@@ -87,8 +87,8 @@ module Reek
|
|
|
87
87
|
# @public
|
|
88
88
|
def source_files=(files)
|
|
89
89
|
unless files.is_a?(String) || files.is_a?(FileList)
|
|
90
|
-
raise ArgumentError, 'File list should be a FileList or a String that can contain'\
|
|
91
|
-
|
|
90
|
+
raise ArgumentError, 'File list should be a FileList or a String that can contain ' \
|
|
91
|
+
"a glob pattern, e.g. '{app,lib,spec}/**/*.rb'"
|
|
92
92
|
end
|
|
93
93
|
@source_files = FileList[files]
|
|
94
94
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_report'
|
|
4
|
+
|
|
5
|
+
module Reek
|
|
6
|
+
module Report
|
|
7
|
+
#
|
|
8
|
+
# Displays smells as GitHub Workflow commands.
|
|
9
|
+
#
|
|
10
|
+
# @public
|
|
11
|
+
#
|
|
12
|
+
class GithubReport < BaseReport
|
|
13
|
+
def show(out = $stdout)
|
|
14
|
+
out.print(workflow_commands.join)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def workflow_commands
|
|
20
|
+
smells.map do |smell|
|
|
21
|
+
WorkflowCommand.new(smell)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Represents a smell as a GitHub Workflow command.
|
|
26
|
+
class WorkflowCommand
|
|
27
|
+
def initialize(smell)
|
|
28
|
+
@smell = smell
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
format(
|
|
33
|
+
"::warning file=%<file>s,line=%<line>d::%<message>s\n",
|
|
34
|
+
file: file,
|
|
35
|
+
line: line,
|
|
36
|
+
message: message)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def file
|
|
42
|
+
@smell.source
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def line
|
|
46
|
+
@smell.lines.first
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def message
|
|
50
|
+
@smell.base_message.gsub('%', '%25').gsub("\r", '%0D').gsub("\n", '%0A')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/reek/report.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'report/github_report'
|
|
3
4
|
require_relative 'report/html_report'
|
|
4
5
|
require_relative 'report/json_report'
|
|
5
6
|
require_relative 'report/text_report'
|
|
@@ -16,11 +17,12 @@ module Reek
|
|
|
16
17
|
# Reek reporting functionality.
|
|
17
18
|
module Report
|
|
18
19
|
REPORT_CLASSES = {
|
|
19
|
-
yaml:
|
|
20
|
-
json:
|
|
21
|
-
html:
|
|
22
|
-
xml:
|
|
23
|
-
text:
|
|
20
|
+
yaml: YAMLReport,
|
|
21
|
+
json: JSONReport,
|
|
22
|
+
html: HTMLReport,
|
|
23
|
+
xml: XMLReport,
|
|
24
|
+
text: TextReport,
|
|
25
|
+
github: GithubReport
|
|
24
26
|
}.freeze
|
|
25
27
|
|
|
26
28
|
LOCATION_FORMATTERS = {
|
|
@@ -25,8 +25,8 @@ module Reek
|
|
|
25
25
|
# @return [Array<SmellWarning>]
|
|
26
26
|
#
|
|
27
27
|
def sniff
|
|
28
|
-
class_variables_in_context.map do |variable,
|
|
29
|
-
lines =
|
|
28
|
+
class_variables_in_context.map do |variable, occurrences|
|
|
29
|
+
lines = occurrences.map(&:line)
|
|
30
30
|
smell_warning(
|
|
31
31
|
lines: lines,
|
|
32
32
|
message: "declares the class variable '#{variable}'",
|
|
@@ -9,20 +9,20 @@ module Reek
|
|
|
9
9
|
class Candidate
|
|
10
10
|
#
|
|
11
11
|
# @param parameter [Symbol] the parameter name
|
|
12
|
-
# @param
|
|
12
|
+
# @param occurrences [Array<Reek::AST::Node>] the occurrences of the ControlParameter smell
|
|
13
13
|
# e.g. [s(:lvar, :bravo), s(:lvar, :bravo)]
|
|
14
14
|
#
|
|
15
|
-
def initialize(parameter,
|
|
15
|
+
def initialize(parameter, occurrences)
|
|
16
16
|
@parameter = parameter
|
|
17
|
-
@
|
|
17
|
+
@occurrences = occurrences
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def smells?
|
|
21
|
-
|
|
21
|
+
occurrences.any?
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def lines
|
|
25
|
-
|
|
25
|
+
occurrences.map(&:line)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def name
|
|
@@ -31,7 +31,7 @@ module Reek
|
|
|
31
31
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
|
-
attr_reader :
|
|
34
|
+
attr_reader :occurrences, :parameter
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|