reek 6.0.2 → 6.1.4
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 +57 -0
- data/.rubocop.yml +6 -4
- data/.rubocop_todo.yml +6 -4
- data/CHANGELOG.md +42 -0
- data/CONTRIBUTING.md +4 -1
- data/Dockerfile +1 -1
- data/Gemfile +7 -7
- data/README.md +2 -2
- data/bin/code_climate_reek +2 -3
- data/lib/reek/ast/ast_node_class_map.rb +1 -1
- data/lib/reek/ast/node.rb +1 -1
- 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 +1 -1
- data/lib/reek/cli/command/todo_list_command.rb +2 -2
- data/lib/reek/cli/options.rb +6 -6
- data/lib/reek/code_comment.rb +22 -17
- data/lib/reek/configuration/configuration_file_finder.rb +2 -1
- data/lib/reek/configuration/excluded_paths.rb +2 -1
- data/lib/reek/context/code_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 +6 -0
- data/lib/reek/context_builder.rb +17 -3
- data/lib/reek/rake/task.rb +5 -5
- data/lib/reek/report/code_climate/code_climate_configuration.yml +3 -3
- data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -3
- 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/duplicate_method_call.rb +5 -5
- data/lib/reek/smell_detectors/unused_private_method.rb +1 -0
- data/lib/reek/smell_warning.rb +1 -1
- 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 +28 -25
- metadata +13 -240
- 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/docs/yard_plugin.rb +0 -17
- 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/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
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
## Introduction
|
|
2
|
-
|
|
3
|
-
Classes should use their private methods. Otherwise this is dead
|
|
4
|
-
code which is confusing and bad for maintenance.
|
|
5
|
-
|
|
6
|
-
The _Unused Private Method_ detector reports unused private instance
|
|
7
|
-
methods and instance methods only - class methods are ignored.
|
|
8
|
-
|
|
9
|
-
## Example
|
|
10
|
-
|
|
11
|
-
Given:
|
|
12
|
-
|
|
13
|
-
```Ruby
|
|
14
|
-
class Car
|
|
15
|
-
private
|
|
16
|
-
def drive; end
|
|
17
|
-
def start; end
|
|
18
|
-
end
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Reek would emit the following warning:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
2 warnings:
|
|
25
|
-
[3]:Car has the unused private instance method `drive` (UnusedPrivateMethod)
|
|
26
|
-
[4]:Car has the unused private instance method `start` (UnusedPrivateMethod)
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Configuration
|
|
30
|
-
|
|
31
|
-
_Unused Private Method_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
|
32
|
-
|
|
33
|
-
Private methods that are called via dynamic dispatch
|
|
34
|
-
will trigger a false alarm since detecting something like this is far out of
|
|
35
|
-
scope for Reek. In this case you can disable this detector via the `exclude`
|
|
36
|
-
configuration option (which is part of the [Basic Smell Options](Basic-Smell-Options.md))
|
|
37
|
-
for instance like this (an example from Reek's own codebase):
|
|
38
|
-
|
|
39
|
-
```Ruby
|
|
40
|
-
# :reek:UnusedPrivateMethod { exclude: [ process_ ] }
|
|
41
|
-
class ContextBuilder
|
|
42
|
-
def process_begin
|
|
43
|
-
# ....
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Note that disabling this detector via comment works on a class scope, not
|
|
49
|
-
a method scope (like you can see above).
|
|
50
|
-
|
|
51
|
-
Another simple example would be:
|
|
52
|
-
|
|
53
|
-
```Ruby
|
|
54
|
-
class Alfa
|
|
55
|
-
private
|
|
56
|
-
def bravo
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
This would report:
|
|
62
|
-
|
|
63
|
-
>>
|
|
64
|
-
ruby.rb -- 1 warning:
|
|
65
|
-
[3]:UnusedPrivateMethod: Alfa has the unused private instance method 'bravo'
|
|
66
|
-
|
|
67
|
-
If you want to suppress this warning you can do this via source comment like this:
|
|
68
|
-
|
|
69
|
-
```Ruby
|
|
70
|
-
# :reek:UnusedPrivateMethod: { exclude: bravo }
|
|
71
|
-
class Alfa
|
|
72
|
-
private
|
|
73
|
-
def bravo
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Known limitations
|
|
79
|
-
|
|
80
|
-
* Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
|
|
81
|
-
static tool for that matter) cannot detect.
|
|
82
|
-
* Method calls via callback like [Rails filters](http://guides.rubyonrails.org/action_controller_overview.html#filters)
|
|
83
|
-
will trigger this as well, e.g.:
|
|
84
|
-
|
|
85
|
-
```Ruby
|
|
86
|
-
class BankController < ActionController::Base
|
|
87
|
-
before_action :audit
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
def audit
|
|
91
|
-
# ....
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
```
|
|
95
|
-
* Reek works on a per-file base. This means that using something like the [template pattern](https://en.wikipedia.org/wiki/Template_method_pattern)
|
|
96
|
-
with private methods will trigger this detector.
|
|
97
|
-
We do believe though that using private methods to fill out a template in a
|
|
98
|
-
superclass is not a good idea in general so this probably isn't really a problem
|
|
99
|
-
but still worth mentioning it.
|
|
100
|
-
|
|
101
|
-
|
data/docs/Utility-Function.md
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Utility Function
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
A _Utility Function_ is any instance method that has no dependency on the state of the instance.
|
|
6
|
-
|
|
7
|
-
_Utility Function_ is heavily related to _[Feature Envy](Feature-Envy.md)_, please check out the explanation there why _Utility Function_ is something you should care about.
|
|
8
|
-
|
|
9
|
-
## Example
|
|
10
|
-
|
|
11
|
-
Given
|
|
12
|
-
|
|
13
|
-
```Ruby
|
|
14
|
-
class UtilityFunction
|
|
15
|
-
def showcase(argument)
|
|
16
|
-
argument.to_s + argument.to_i
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Reek would report:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
test.rb -- 2 warnings:
|
|
25
|
-
[2]:UtilityFunction#showcase doesn't depend on instance state (UtilityFunction)
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Current Support in Reek
|
|
29
|
-
|
|
30
|
-
_Utility Function_ will warn about any method that:
|
|
31
|
-
|
|
32
|
-
* is non-empty
|
|
33
|
-
* does not override an inherited method
|
|
34
|
-
* calls at least one method on another object
|
|
35
|
-
* doesn't use any of self's instance variables
|
|
36
|
-
* doesn't use any of self's methods
|
|
37
|
-
|
|
38
|
-
## Differences to _Feature Envy_
|
|
39
|
-
|
|
40
|
-
_[Feature Envy](Feature-Envy.md)_ is only triggered if there are some references to self and _Utility Function_ is triggered if there are no references to self.
|
|
41
|
-
|
|
42
|
-
## Configuration
|
|
43
|
-
|
|
44
|
-
Reek's _Utility Function_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
45
|
-
|
|
46
|
-
| Option | Value | Effect |
|
|
47
|
-
| ----------------------|-------------|---------|
|
|
48
|
-
| `public_methods_only` | Boolean | Disable this smell detector for non-public methods (which means "private" and "protected") |
|
|
49
|
-
|
|
50
|
-
A sample configuration file would look like this:
|
|
51
|
-
|
|
52
|
-
```Yaml
|
|
53
|
-
---
|
|
54
|
-
UtilityFunction:
|
|
55
|
-
public_methods_only: true
|
|
56
|
-
```
|
data/docs/Versioning-Policy.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Versioning Policy
|
|
2
|
-
|
|
3
|
-
* CLI interface: Adding options is a non-breaking change, and would warrant an update of the minor version. Removing options is a breaking change and requires a major version update (we did this going to Reek 2). Adding a report format probably also warrents a minor version upgrade.
|
|
4
|
-
* API: We haven't really defined a 'public' API for using Reek programmatically, and we've only just started testing it. So, this is basically a blank slate at the moment. We will work on this as a part of the Reek 3 release.
|
|
5
|
-
* List of detected smells: Adding a smell warrants a minor release, removing a smell is a breaking change. This makes sense if you consider that the CLI allows running a single smell detector.
|
|
6
|
-
* Consistency of detected smells: This is very hard to guarantee. If we fix a bug in one of the detectors, some fragrant code may become smelly, or vice versa. Right now we don't bother with this.
|
|
7
|
-
* Smell configuration: The detectors are quite tolerant regarding configuration options that they don't recognize, so we regard any change here as only requiring a minor release.
|
data/docs/YAML-Reports.md
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# YAML Reports
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
Reek's `--yaml` option writes on $stdout a YAML dump of the smells found. Each reported smell has a number of standard fields and a number of fields that are specific to the smell's type. The common fields are as follows:
|
|
6
|
-
|
|
7
|
-
| Field | Type | Value |
|
|
8
|
-
| ---------------|-------------|---------|
|
|
9
|
-
| source | string | The name of the source file containing the smell, or `$stdin` |
|
|
10
|
-
| lines | array | The source file line number(s) that contribute to this smell |
|
|
11
|
-
| context | string | The name of the class, module or method containing the smell |
|
|
12
|
-
| class | string | The class to which this smell belongs |
|
|
13
|
-
| subclass | string | This smell's subclass within the above class |
|
|
14
|
-
| message | string | The message that would have been printed in a standard Reek report |
|
|
15
|
-
| is_active | boolean | `false` if the smell is masked by a config file; `true` otherwise |
|
|
16
|
-
|
|
17
|
-
All of these fields are grouped into hashes `location`, `smell` and `status` (see the examples below).
|
|
18
|
-
|
|
19
|
-
## Examples
|
|
20
|
-
|
|
21
|
-
Duplication:
|
|
22
|
-
|
|
23
|
-
<pre>
|
|
24
|
-
- !ruby/object:Reek::SmellWarning
|
|
25
|
-
location:
|
|
26
|
-
source: spec/samples/masked/dirty.rb
|
|
27
|
-
lines:
|
|
28
|
-
- 5
|
|
29
|
-
- 7
|
|
30
|
-
context: Dirty#a
|
|
31
|
-
smell:
|
|
32
|
-
class: Duplication
|
|
33
|
-
subclass: DuplicateMethodCall
|
|
34
|
-
occurrences: 2
|
|
35
|
-
call: puts(@s.title)
|
|
36
|
-
message: calls puts(@s.title) twice
|
|
37
|
-
status:
|
|
38
|
-
is_active: true
|
|
39
|
-
</pre>
|
|
40
|
-
|
|
41
|
-
[Nested Iterators](Nested-Iterators.md):
|
|
42
|
-
|
|
43
|
-
<pre>
|
|
44
|
-
- !ruby/object:Reek::SmellWarning
|
|
45
|
-
location:
|
|
46
|
-
source: spec/samples/masked/dirty.rb
|
|
47
|
-
lines:
|
|
48
|
-
- 5
|
|
49
|
-
context: Dirty#a
|
|
50
|
-
smell:
|
|
51
|
-
class: NestedIterators
|
|
52
|
-
subclass: ""
|
|
53
|
-
depth: 2
|
|
54
|
-
message: contains iterators nested 2 deep
|
|
55
|
-
status:
|
|
56
|
-
is_active: true
|
|
57
|
-
</pre>
|
|
58
|
-
|
|
59
|
-
[Uncommunicative Method Name](Uncommunicative-Method-Name.md):
|
|
60
|
-
|
|
61
|
-
<pre>
|
|
62
|
-
- !ruby/object:Reek::SmellWarning
|
|
63
|
-
location:
|
|
64
|
-
source: spec/samples/masked/dirty.rb
|
|
65
|
-
lines:
|
|
66
|
-
- 3
|
|
67
|
-
context: Dirty#a
|
|
68
|
-
smell:
|
|
69
|
-
class: UncommunicativeName
|
|
70
|
-
subclass: UncommunicativeMethodName
|
|
71
|
-
method_name: a
|
|
72
|
-
message: has the name 'a'
|
|
73
|
-
status:
|
|
74
|
-
is_active: false
|
|
75
|
-
</pre>
|
|
76
|
-
|
|
77
|
-
[Uncommunicative Variable Name](Uncommunicative-Variable-Name.md):
|
|
78
|
-
|
|
79
|
-
<pre>
|
|
80
|
-
- !ruby/object:Reek::SmellWarning
|
|
81
|
-
location:
|
|
82
|
-
source: spec/samples/masked/dirty.rb
|
|
83
|
-
lines:
|
|
84
|
-
- 5
|
|
85
|
-
context: Dirty#a
|
|
86
|
-
smell:
|
|
87
|
-
class: UncommunicativeName
|
|
88
|
-
subclass: UncommunicativeVariableName
|
|
89
|
-
variable_name: x
|
|
90
|
-
message: has the variable name 'x'
|
|
91
|
-
status:
|
|
92
|
-
is_active: true
|
|
93
|
-
</pre>
|
data/docs/defaults.reek.yml
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
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
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
def init
|
|
2
|
-
super
|
|
3
|
-
return unless show_api_marker_section?
|
|
4
|
-
|
|
5
|
-
if sections.first
|
|
6
|
-
sections.first.place(:api_marker).before(:private)
|
|
7
|
-
else
|
|
8
|
-
sections :index, [:api_marker]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def api_marker
|
|
13
|
-
return if object.type == :root
|
|
14
|
-
|
|
15
|
-
erb(:private) unless ['public', 'private'].include? api_text
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def api_text
|
|
21
|
-
api_text = object.has_tag?(:api) && object.tag(:api).text
|
|
22
|
-
api_text = 'public' if object.has_tag?(:public)
|
|
23
|
-
api_text
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def show_api_marker_section?
|
|
27
|
-
return false if object.type == :root
|
|
28
|
-
|
|
29
|
-
case api_text
|
|
30
|
-
when 'public'
|
|
31
|
-
false
|
|
32
|
-
when 'private'
|
|
33
|
-
false
|
|
34
|
-
else
|
|
35
|
-
true
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.note.public { background: #c5ffc5; border-color: #aaecaa; }
|
data/docs/yard_plugin.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require 'yard'
|
|
2
|
-
|
|
3
|
-
# Template helper to modify processing of links in HTML generated from our
|
|
4
|
-
# markdown files.
|
|
5
|
-
module LocalLinkHelper
|
|
6
|
-
# Rewrites links to (assumed local) markdown files so they're processed as
|
|
7
|
-
# {file: } directives.
|
|
8
|
-
def resolve_links(text)
|
|
9
|
-
text = text.gsub(%r{<a href="([^"]*.md)">([^<]*)</a>}, '{file:\1 \2}')
|
|
10
|
-
super text
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
YARD::Templates::Template.extra_includes << LocalLinkHelper
|
|
15
|
-
YARD::Tags::Library.define_tag('Guaranteed public API', :public)
|
|
16
|
-
YARD::Tags::Library.define_tag('Code quality configuration', :quality)
|
|
17
|
-
YARD::Templates::Engine.register_template_path File.join(File.dirname(__FILE__), 'templates')
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
Feature: The Reek CLI maintains backwards compatibility
|
|
2
|
-
In order to use Reek without fuss
|
|
3
|
-
As a developer
|
|
4
|
-
I want to have a stable basic command line interface
|
|
5
|
-
|
|
6
|
-
Scenario: the example from README reports as expected
|
|
7
|
-
Given the smelly file 'smelly.rb'
|
|
8
|
-
When I run reek smelly.rb
|
|
9
|
-
Then the exit status indicates smells
|
|
10
|
-
And it reports:
|
|
11
|
-
"""
|
|
12
|
-
smelly.rb -- 2 warnings:
|
|
13
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
14
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
15
|
-
"""
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
Feature: Reek can be controlled using command-line options
|
|
2
|
-
In order to change Reek's default behaviour
|
|
3
|
-
As a developer
|
|
4
|
-
I want to supply options on the command line
|
|
5
|
-
|
|
6
|
-
Scenario: return non-zero status on bad option
|
|
7
|
-
When I run reek --no-such-option
|
|
8
|
-
Then the exit status indicates an error
|
|
9
|
-
And it reports the error "Error: invalid option: --no-such-option"
|
|
10
|
-
And there is no output on stdout
|
|
11
|
-
|
|
12
|
-
Scenario: display the current version number
|
|
13
|
-
When I run reek --version
|
|
14
|
-
Then it succeeds
|
|
15
|
-
And it reports the current version
|
|
16
|
-
|
|
17
|
-
Scenario: return given status code when using --failure-exit-code
|
|
18
|
-
Given the smelly file 'smelly.rb'
|
|
19
|
-
When I run reek smelly.rb --failure-exit-code 23
|
|
20
|
-
Then the exit status is 23
|
|
21
|
-
|
|
22
|
-
Scenario: return given status code when using --success-exit-code
|
|
23
|
-
Given the clean file "clean.rb"
|
|
24
|
-
When I run reek clean.rb --success-exit-code 42
|
|
25
|
-
Then the exit status is 42
|
|
26
|
-
|
|
27
|
-
Scenario: display the help information
|
|
28
|
-
When I run reek --help
|
|
29
|
-
Then it succeeds
|
|
30
|
-
And it reports:
|
|
31
|
-
"""
|
|
32
|
-
Usage: reek [options] [files]
|
|
33
|
-
|
|
34
|
-
Examples:
|
|
35
|
-
|
|
36
|
-
reek lib/*.rb
|
|
37
|
-
reek -s lib
|
|
38
|
-
cat my_class.rb | reek
|
|
39
|
-
|
|
40
|
-
See https://github.com/troessner/reek for detailed help.
|
|
41
|
-
|
|
42
|
-
Configuration:
|
|
43
|
-
-c, --config FILE Read configuration options from FILE
|
|
44
|
-
--smell SMELL Only look for a specific smell.
|
|
45
|
-
Call it like this: reek --smell MissingSafeMethod source.rb
|
|
46
|
-
Check out https://github.com/troessner/reek/blob/v6.0.2/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.
|
|
48
|
-
|
|
49
|
-
Generate a todo list:
|
|
50
|
-
-t, --todo Generate a todo list
|
|
51
|
-
|
|
52
|
-
Report format:
|
|
53
|
-
-f, --format FORMAT Report smells in the given format:
|
|
54
|
-
html
|
|
55
|
-
text (default)
|
|
56
|
-
yaml
|
|
57
|
-
json
|
|
58
|
-
xml
|
|
59
|
-
|
|
60
|
-
Text format options:
|
|
61
|
-
--[no-]color Use colors for the output (default: true)
|
|
62
|
-
-V, --[no-]empty-headings Show headings for smell-free source files (default: false)
|
|
63
|
-
-U, --[no-]documentation Show link to related documentation page for each smell (default: true)
|
|
64
|
-
--[no-]show-configuration-path
|
|
65
|
-
Show which configuration file Reek is using (default: false)
|
|
66
|
-
-n, --[no-]line-numbers Show line numbers in the output (default: true)
|
|
67
|
-
-s, --single-line Show location in editor-compatible single-line-per-smell format
|
|
68
|
-
-P, --[no-]progress Show progress of each source as it is examined (default: true)
|
|
69
|
-
--sort-by SORTING Sort reported files by the given criterium:
|
|
70
|
-
smelliness ("smelliest" files first)
|
|
71
|
-
none (default - output in processing order)
|
|
72
|
-
--force-exclusion Force excluding files specified in the configuration `exclude_paths`
|
|
73
|
-
even if they are explicitly passed as arguments
|
|
74
|
-
|
|
75
|
-
Exit codes:
|
|
76
|
-
--success-exit-code CODE The exit code when no smells are found (default: 0)
|
|
77
|
-
--failure-exit-code CODE The exit code when smells are found (default: 2)
|
|
78
|
-
|
|
79
|
-
Utility options:
|
|
80
|
-
-h, --help Show this message
|
|
81
|
-
-l, --list List all available smell detectors
|
|
82
|
-
-v, --version Show version
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
Scenario: List all available smell detectors
|
|
86
|
-
When I run reek --list
|
|
87
|
-
Then it succeeds
|
|
88
|
-
And it reports:
|
|
89
|
-
"""
|
|
90
|
-
All available smell detectors:
|
|
91
|
-
|
|
92
|
-
Attribute
|
|
93
|
-
BooleanParameter
|
|
94
|
-
ClassVariable
|
|
95
|
-
ControlParameter
|
|
96
|
-
DataClump
|
|
97
|
-
DuplicateMethodCall
|
|
98
|
-
FeatureEnvy
|
|
99
|
-
InstanceVariableAssumption
|
|
100
|
-
IrresponsibleModule
|
|
101
|
-
LongParameterList
|
|
102
|
-
LongYieldList
|
|
103
|
-
ManualDispatch
|
|
104
|
-
MissingSafeMethod
|
|
105
|
-
ModuleInitialize
|
|
106
|
-
NestedIterators
|
|
107
|
-
NilCheck
|
|
108
|
-
RepeatedConditional
|
|
109
|
-
SubclassedFromCoreClass
|
|
110
|
-
TooManyConstants
|
|
111
|
-
TooManyInstanceVariables
|
|
112
|
-
TooManyMethods
|
|
113
|
-
TooManyStatements
|
|
114
|
-
UncommunicativeMethodName
|
|
115
|
-
UncommunicativeModuleName
|
|
116
|
-
UncommunicativeParameterName
|
|
117
|
-
UncommunicativeVariableName
|
|
118
|
-
UnusedParameters
|
|
119
|
-
UnusedPrivateMethod
|
|
120
|
-
UtilityFunction
|
|
121
|
-
|
|
122
|
-
Check out https://github.com/troessner/reek/blob/v6.0.2/docs/Code-Smells.md for a details on each detector
|
|
123
|
-
"""
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
Feature: Show progress
|
|
2
|
-
In order to see the progress of the examiners
|
|
3
|
-
As a developer
|
|
4
|
-
I want to be able to selectively activate progress reporting
|
|
5
|
-
|
|
6
|
-
# Note that --progress is the default on TTYs, but needs to be explicitely
|
|
7
|
-
# enabled here because output in the cucumber scenarios does not go to a TTY.
|
|
8
|
-
Scenario: shows progress output on mixed files by default
|
|
9
|
-
Given a directory called 'mixed_files' containing some clean and smelly files
|
|
10
|
-
When I run reek --progress mixed_files
|
|
11
|
-
Then the exit status indicates smells
|
|
12
|
-
And it reports:
|
|
13
|
-
"""
|
|
14
|
-
Inspecting 2 file(s):
|
|
15
|
-
.S
|
|
16
|
-
|
|
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'
|
|
20
|
-
2 total warnings
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
Scenario: --no-progress disables progress output
|
|
24
|
-
Given a directory called 'mixed_files' containing some clean and smelly files
|
|
25
|
-
When I run reek --no-progress mixed_files
|
|
26
|
-
Then the exit status indicates smells
|
|
27
|
-
And it reports:
|
|
28
|
-
"""
|
|
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'
|
|
32
|
-
2 total warnings
|
|
33
|
-
"""
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
Feature: Smell selection
|
|
2
|
-
In order to focus on particular code smells
|
|
3
|
-
As a developer
|
|
4
|
-
I want to be able to selectively activate smell detectors
|
|
5
|
-
|
|
6
|
-
Scenario: --smell selects a smell to detect
|
|
7
|
-
Given the smelly file 'smelly.rb'
|
|
8
|
-
And a configuration file 'partial_mask.reek'
|
|
9
|
-
When I run reek --no-line-numbers --smell UncommunicativeVariableName smelly.rb
|
|
10
|
-
Then the exit status indicates smells
|
|
11
|
-
And it reports:
|
|
12
|
-
"""
|
|
13
|
-
smelly.rb -- 1 warning:
|
|
14
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
15
|
-
"""
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
Feature: Reports total number of code smells
|
|
2
|
-
In order to monitor the total number of smells
|
|
3
|
-
Reek outputs the total number of smells among all files inspected.
|
|
4
|
-
|
|
5
|
-
Scenario: Does not output total number of smells when inspecting single file
|
|
6
|
-
Given the smelly file 'smelly.rb'
|
|
7
|
-
When I run reek smelly.rb
|
|
8
|
-
Then the exit status indicates smells
|
|
9
|
-
And it reports:
|
|
10
|
-
"""
|
|
11
|
-
smelly.rb -- 2 warnings:
|
|
12
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
|
|
13
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
Scenario: Output total number of smells when inspecting multiple files
|
|
17
|
-
Given a directory called 'smelly' containing two smelly files
|
|
18
|
-
When I run reek smelly
|
|
19
|
-
Then the exit status indicates smells
|
|
20
|
-
And it reports:
|
|
21
|
-
"""
|
|
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'
|
|
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'
|
|
28
|
-
4 total warnings
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
Scenario: Output total number of smells even if total equals 0
|
|
32
|
-
Given a directory called 'clean' containing two clean files
|
|
33
|
-
When I run reek clean
|
|
34
|
-
Then it succeeds
|
|
35
|
-
And it reports:
|
|
36
|
-
"""
|
|
37
|
-
0 total warnings
|
|
38
|
-
"""
|