reek 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -21
- data/.travis.yml +1 -0
- data/.yardopts +3 -6
- data/CHANGELOG +6 -0
- data/CONTRIBUTING.md +8 -3
- data/README.md +94 -42
- data/config/defaults.reek +0 -1
- data/docs/API.md +50 -0
- data/docs/Attribute.md +43 -0
- data/docs/Basic-Smell-Options.md +44 -0
- data/docs/Boolean-Parameter.md +52 -0
- data/docs/Class-Variable.md +40 -0
- data/docs/Code-Smells.md +34 -0
- data/docs/Command-Line-Options.md +84 -0
- data/docs/Configuration-Files.md +38 -0
- data/docs/Control-Couple.md +22 -0
- data/docs/Control-Parameter.md +29 -0
- data/docs/Data-Clump.md +44 -0
- data/docs/Duplicate-Method-Call.md +49 -0
- data/docs/Feature-Envy.md +29 -0
- data/docs/How-reek-works-internally.md +44 -0
- data/docs/Irresponsible-Module.md +39 -0
- data/docs/Large-Class.md +20 -0
- data/docs/Long-Parameter-List.md +38 -0
- data/docs/Long-Yield-List.md +36 -0
- data/docs/Module-Initialize.md +62 -0
- data/docs/Nested-Iterators.md +38 -0
- data/docs/Nil-Check.md +39 -0
- data/docs/Prima-Donna-Method.md +53 -0
- data/docs/RSpec-matchers.md +133 -0
- data/docs/Rake-Task.md +58 -0
- data/docs/Reek-Driven-Development.md +45 -0
- data/docs/Repeated-Conditional.md +44 -0
- data/docs/Simulated-Polymorphism.md +16 -0
- data/docs/Smell-Suppression.md +32 -0
- data/docs/Too-Many-Instance-Variables.md +43 -0
- data/docs/Too-Many-Methods.md +55 -0
- data/docs/Too-Many-Statements.md +50 -0
- data/docs/Uncommunicative-Method-Name.md +24 -0
- data/docs/Uncommunicative-Module-Name.md +23 -0
- data/docs/Uncommunicative-Name.md +16 -0
- data/docs/Uncommunicative-Parameter-Name.md +24 -0
- data/docs/Uncommunicative-Variable-Name.md +24 -0
- data/docs/Unused-Parameters.md +27 -0
- data/docs/Utility-Function.md +46 -0
- data/docs/Versioning-Policy.md +7 -0
- data/docs/YAML-Reports.md +111 -0
- data/docs/yard_plugin.rb +14 -0
- data/features/command_line_interface/options.feature +1 -0
- data/features/programmatic_access.feature +1 -1
- data/features/samples.feature +3 -3
- data/lib/reek.rb +2 -2
- data/lib/reek/cli/input.rb +2 -2
- data/lib/reek/cli/option_interpreter.rb +2 -0
- data/lib/reek/cli/options.rb +10 -4
- data/lib/reek/cli/reek_command.rb +2 -2
- data/lib/reek/cli/report/report.rb +60 -0
- data/lib/reek/cli/silencer.rb +13 -0
- data/lib/reek/{source → core}/ast_node.rb +1 -1
- data/lib/reek/{source → core}/ast_node_class_map.rb +10 -11
- data/lib/reek/{source → core}/code_comment.rb +1 -1
- data/lib/reek/core/code_context.rb +1 -1
- data/lib/reek/core/examiner.rb +85 -0
- data/lib/reek/core/method_context.rb +1 -1
- data/lib/reek/core/module_context.rb +2 -2
- data/lib/reek/core/reference_collector.rb +31 -0
- data/lib/reek/core/singleton_method_context.rb +0 -4
- data/lib/reek/core/smell_repository.rb +4 -2
- data/lib/reek/{source → core}/tree_dresser.rb +1 -1
- data/lib/reek/{source → sexp}/sexp_extensions.rb +5 -5
- data/lib/reek/sexp/sexp_formatter.rb +29 -0
- data/lib/reek/sexp/sexp_node.rb +91 -0
- data/lib/reek/smells.rb +4 -2
- data/lib/reek/smells/attribute.rb +35 -7
- data/lib/reek/smells/boolean_parameter.rb +1 -1
- data/lib/reek/smells/class_variable.rb +1 -1
- data/lib/reek/smells/control_parameter.rb +1 -1
- data/lib/reek/smells/data_clump.rb +1 -1
- data/lib/reek/smells/duplicate_method_call.rb +12 -4
- data/lib/reek/smells/feature_envy.rb +1 -1
- data/lib/reek/smells/irresponsible_module.rb +3 -3
- data/lib/reek/smells/long_parameter_list.rb +1 -1
- data/lib/reek/smells/long_yield_list.rb +1 -1
- data/lib/reek/smells/module_initialize.rb +1 -1
- data/lib/reek/smells/nested_iterators.rb +1 -1
- data/lib/reek/smells/nil_check.rb +3 -2
- data/lib/reek/smells/prima_donna_method.rb +18 -11
- data/lib/reek/smells/repeated_conditional.rb +3 -3
- data/lib/reek/smells/smell_detector.rb +5 -1
- data/lib/reek/smells/smell_warning.rb +99 -0
- data/lib/reek/smells/too_many_instance_variables.rb +1 -1
- data/lib/reek/smells/too_many_methods.rb +1 -1
- data/lib/reek/smells/too_many_statements.rb +1 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smells/unused_parameters.rb +1 -1
- data/lib/reek/smells/utility_function.rb +3 -16
- data/lib/reek/source/source_code.rb +31 -13
- data/lib/reek/source/source_locator.rb +16 -17
- data/lib/reek/source/source_repository.rb +10 -11
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +2 -2
- data/lib/reek/spec/should_reek_only_of.rb +2 -2
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +3 -4
- data/spec/factories/factories.rb +1 -1
- data/spec/gem/yard_spec.rb +1 -1
- data/spec/quality/reek_source_spec.rb +2 -2
- data/spec/reek/cli/html_report_spec.rb +3 -3
- data/spec/reek/cli/json_report_spec.rb +3 -3
- data/spec/reek/cli/{option_interperter_spec.rb → option_interpreter_spec.rb} +1 -1
- data/spec/reek/cli/options_spec.rb +19 -0
- data/spec/reek/cli/text_report_spec.rb +7 -7
- data/spec/reek/cli/xml_report_spec.rb +34 -0
- data/spec/reek/cli/yaml_report_spec.rb +3 -3
- data/spec/reek/configuration/app_configuration_spec.rb +1 -1
- data/spec/reek/configuration/configuration_file_finder_spec.rb +22 -1
- data/spec/reek/{source → core}/code_comment_spec.rb +14 -14
- data/spec/reek/core/code_context_spec.rb +1 -1
- data/spec/reek/{examiner_spec.rb → core/examiner_spec.rb} +12 -12
- data/spec/reek/core/method_context_spec.rb +27 -22
- data/spec/reek/core/module_context_spec.rb +2 -2
- data/spec/reek/core/object_refs_spec.rb +1 -1
- data/spec/reek/{source → core}/object_source_spec.rb +1 -1
- data/spec/reek/{source → core}/reference_collector_spec.rb +25 -16
- data/spec/reek/core/singleton_method_context_spec.rb +12 -2
- data/spec/reek/core/smell_configuration_spec.rb +1 -1
- data/spec/reek/core/smell_repository_spec.rb +12 -1
- data/spec/reek/core/stop_context_spec.rb +1 -1
- data/spec/reek/core/tree_dresser_spec.rb +16 -0
- data/spec/reek/core/tree_walker_spec.rb +3 -3
- data/spec/reek/core/warning_collector_spec.rb +6 -6
- data/spec/reek/{source → sexp}/sexp_extensions_spec.rb +8 -8
- data/spec/reek/{source → sexp}/sexp_formatter_spec.rb +11 -5
- data/spec/reek/{source → sexp}/sexp_node_spec.rb +3 -3
- data/spec/reek/smells/attribute_spec.rb +89 -85
- data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
- data/spec/reek/smells/class_variable_spec.rb +1 -1
- data/spec/reek/smells/control_parameter_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +2 -2
- data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
- data/spec/reek/smells/feature_envy_spec.rb +2 -2
- data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
- data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
- data/spec/reek/smells/long_yield_list_spec.rb +1 -1
- data/spec/reek/smells/module_initialize_spec.rb +1 -1
- data/spec/reek/smells/nested_iterators_spec.rb +2 -2
- data/spec/reek/smells/nil_check_spec.rb +1 -1
- data/spec/reek/smells/prima_donna_method_spec.rb +1 -1
- data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
- data/spec/reek/smells/smell_detector_shared.rb +2 -2
- data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -7
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +1 -1
- data/spec/reek/smells/too_many_statements_spec.rb +4 -4
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
- data/spec/reek/smells/unused_parameters_spec.rb +1 -1
- data/spec/reek/smells/utility_function_spec.rb +1 -1
- data/spec/reek/source/source_code_spec.rb +1 -1
- data/spec/reek/spec/should_reek_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_spec.rb +1 -1
- data/spec/samples/checkstyle.xml +2 -0
- data/spec/spec_helper.rb +15 -3
- metadata +68 -38
- data/.ruby-gemset +0 -1
- data/lib/reek/examiner.rb +0 -79
- data/lib/reek/smell_warning.rb +0 -87
- data/lib/reek/source/reference_collector.rb +0 -27
- data/lib/reek/source/sexp_formatter.rb +0 -22
- data/lib/reek/source/sexp_node.rb +0 -79
- data/spec/reek/source/tree_dresser_spec.rb +0 -16
@@ -0,0 +1,24 @@
|
|
1
|
+
# Uncommunicative Method Name
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
An `Uncommunicative Method Name` is a method name that doesn't communicate its intent well enough.
|
6
|
+
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
8
|
+
|
9
|
+
## Current Support in reek
|
10
|
+
|
11
|
+
`Uncommunicative Method Name` checks for:
|
12
|
+
|
13
|
+
* 1-character names
|
14
|
+
* any name ending with a number
|
15
|
+
* camelCaseVariableNames
|
16
|
+
|
17
|
+
## Configuration
|
18
|
+
|
19
|
+
`reek`'s Uncommunicative Method Name detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
|
+
|
21
|
+
| Option | Value | Effect |
|
22
|
+
| ---------------|-------------|---------|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^[a-z]$/, /[0-9]$/, /[A-Z]/]`. |
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. |
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Uncommunicative Module Name
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
An `Uncommunicative Module Name` is a module name that doesn't communicate its intent well enough.
|
6
|
+
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
8
|
+
|
9
|
+
## Current Support in reek
|
10
|
+
|
11
|
+
`Uncommunicative Module Name` checks for:
|
12
|
+
|
13
|
+
* 1-character names
|
14
|
+
* any name ending with a number
|
15
|
+
|
16
|
+
## Configuration
|
17
|
+
|
18
|
+
`reek`'s `Uncommunicative Module Name` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
19
|
+
|
20
|
+
| Option | Value | Effect |
|
21
|
+
| ---------------|-------------|---------|
|
22
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/]`. |
|
23
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to `['Inline::C']`.|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Uncommunicative Name
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
An `Uncommunicative Name` is a name that doesn't communicate its intent well enough.
|
6
|
+
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
8
|
+
|
9
|
+
## Current Support in Reek
|
10
|
+
|
11
|
+
`reek` offers four related checks:
|
12
|
+
|
13
|
+
* [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
|
14
|
+
* [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
|
15
|
+
* [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
|
16
|
+
* [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Uncommunicative Parameter Name
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
An `Uncommunicative Parameter Name` is a parameter name that doesn't communicate its intent well enough.
|
6
|
+
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
8
|
+
|
9
|
+
## Current Support in reek
|
10
|
+
|
11
|
+
`Uncommunicative Parameter Name` checks for:
|
12
|
+
|
13
|
+
* 1-character names
|
14
|
+
* any name ending with a number
|
15
|
+
* camelCaseVariableNames
|
16
|
+
|
17
|
+
## Configuration
|
18
|
+
|
19
|
+
`reek`'s Uncommunicative Parameter Name detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
|
+
|
21
|
+
| Option | Value | Effect |
|
22
|
+
| ---------------|-------------|---------|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/]@. |
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. |
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Uncommunicative Variable Name
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
An `Uncommunicative Variable Name` is a variable name that doesn't communicate its intent well enough.
|
6
|
+
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
8
|
+
|
9
|
+
## Current Support in Reek
|
10
|
+
|
11
|
+
`Uncommunicative Variable Name` checks for:
|
12
|
+
|
13
|
+
* 1-character names
|
14
|
+
* any name ending with a number
|
15
|
+
* camelCaseVariableNames
|
16
|
+
|
17
|
+
## Configuration
|
18
|
+
|
19
|
+
`reek`'s `Uncommunicative Variable Name` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
|
+
|
21
|
+
| Option | Value | Effect |
|
22
|
+
| ---------------|-------------|---------|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/]`. |
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to @['_']@.|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
## Introduction
|
2
|
+
|
3
|
+
`Unused Parameter` refers to methods with parameters that are unused in scope of the method.
|
4
|
+
|
5
|
+
Having unused parameters in a method is code smell because leaving dead code in a method can never improve the method and it makes the code confusing to read.
|
6
|
+
|
7
|
+
## Example
|
8
|
+
|
9
|
+
Given:
|
10
|
+
|
11
|
+
```Ruby
|
12
|
+
class Klass
|
13
|
+
def unused_parameters(x,y,z)
|
14
|
+
puts x,y # but not z
|
15
|
+
end
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
`reek` would emit the following warning:
|
20
|
+
|
21
|
+
```
|
22
|
+
[2]:Klass#unused_parameters has unused parameter 'z' (UnusedParameters)
|
23
|
+
```
|
24
|
+
|
25
|
+
## Configuration
|
26
|
+
|
27
|
+
`Unused Parameter` offers the [Basic Smell Options](Basic-Smell-Options.md).
|
@@ -0,0 +1,46 @@
|
|
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
|
+
A Utility Function reduces the code’s ability to communicate intent: code that “belongs” on one class but which is located in another can be hard to find, and may upset the “System of Names” in the host class. A Utility Function also affects the design’s flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application’s domain, and creates a loss of cohesion in the unwilling host class.
|
8
|
+
|
9
|
+
A Utility Function often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.
|
10
|
+
|
11
|
+
## Example
|
12
|
+
|
13
|
+
Given
|
14
|
+
|
15
|
+
```Ruby
|
16
|
+
class UtilityFunction
|
17
|
+
def showcase(argument)
|
18
|
+
argument.to_s + argument.to_i
|
19
|
+
end
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
`reek` would report:
|
24
|
+
|
25
|
+
```
|
26
|
+
test.rb -- 2 warnings:
|
27
|
+
[2]:UtilityFunction#showcase doesn't depend on instance state (UtilityFunction)
|
28
|
+
```
|
29
|
+
|
30
|
+
## Current Support in reek
|
31
|
+
|
32
|
+
`Utility Function` will warn about any method that:
|
33
|
+
|
34
|
+
* is non-empty
|
35
|
+
* does not override an inherited method
|
36
|
+
* calls at least one method on another object
|
37
|
+
* doesn't use any of self's instance variables
|
38
|
+
* doesn't use any of self's methods
|
39
|
+
|
40
|
+
## Configuration
|
41
|
+
|
42
|
+
`reek`'s `Utility Function` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
43
|
+
|
44
|
+
| Option | Value | Effect |
|
45
|
+
| ---------------|-------------|---------|
|
46
|
+
| `max_helper_calls` | integer | The maximum number of method calls to other objects allowed within a method. Defaults to 2. |
|
@@ -0,0 +1,7 @@
|
|
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.
|
@@ -0,0 +1,111 @@
|
|
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>
|
94
|
+
|
95
|
+
[Control Couple](Control-Couple.md):
|
96
|
+
|
97
|
+
<pre>
|
98
|
+
- !ruby/object:Reek::SmellWarning
|
99
|
+
location:
|
100
|
+
source: $stdin
|
101
|
+
lines:
|
102
|
+
- 2
|
103
|
+
context: Turn#fred
|
104
|
+
smell:
|
105
|
+
class: ControlCouple
|
106
|
+
subclass: BooleanParameter
|
107
|
+
parameter: arg
|
108
|
+
message: has boolean parameter 'arg'
|
109
|
+
status:
|
110
|
+
is_active: true
|
111
|
+
</pre>
|
data/docs/yard_plugin.rb
ADDED
@@ -0,0 +1,14 @@
|
|
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
|
@@ -8,7 +8,7 @@ Feature: Using reek programmatically
|
|
8
8
|
And a file named "examine.rb" with:
|
9
9
|
"""
|
10
10
|
require 'reek'
|
11
|
-
examiner = Reek::Examiner.new(['smelly.rb'])
|
11
|
+
examiner = Reek::Core::Examiner.new(['smelly.rb'])
|
12
12
|
examiner.smells.each do |smell|
|
13
13
|
puts smell.message
|
14
14
|
end
|
data/features/samples.feature
CHANGED
@@ -17,7 +17,7 @@ Feature: Basic smell detection
|
|
17
17
|
Inline declares the class variable @@rootdir (ClassVariable)
|
18
18
|
Inline#self.rootdir calls env.nil? 2 times (DuplicateMethodCall)
|
19
19
|
Inline#self.rootdir has approx 8 statements (TooManyStatements)
|
20
|
-
Inline#self.rootdir performs a nil-check
|
20
|
+
Inline#self.rootdir performs a nil-check (NilCheck)
|
21
21
|
Inline::C declares the class variable @@type_map (ClassVariable)
|
22
22
|
Inline::C has at least 13 instance variables (TooManyInstanceVariables)
|
23
23
|
Inline::C takes parameters [options, src] to 5 methods (DataClump)
|
@@ -101,7 +101,7 @@ Feature: Basic smell detection
|
|
101
101
|
OptionParser#make_switch has the variable name 'q' (UncommunicativeVariableName)
|
102
102
|
OptionParser#make_switch has the variable name 's' (UncommunicativeVariableName)
|
103
103
|
OptionParser#make_switch has the variable name 'v' (UncommunicativeVariableName)
|
104
|
-
OptionParser#make_switch performs a nil-check
|
104
|
+
OptionParser#make_switch performs a nil-check (NilCheck)
|
105
105
|
OptionParser#order calls argv[0] 2 times (DuplicateMethodCall)
|
106
106
|
OptionParser#order refers to argv more than self (FeatureEnvy)
|
107
107
|
OptionParser#parse calls argv[0] 2 times (DuplicateMethodCall)
|
@@ -119,7 +119,7 @@ Feature: Basic smell detection
|
|
119
119
|
OptionParser#permute refers to argv more than self (FeatureEnvy)
|
120
120
|
OptionParser#permute! has approx 6 statements (TooManyStatements)
|
121
121
|
OptionParser#search has the variable name 'k' (UncommunicativeVariableName)
|
122
|
-
OptionParser#self.inc performs a nil-check
|
122
|
+
OptionParser#self.inc performs a nil-check (NilCheck)
|
123
123
|
OptionParser#summarize has 4 parameters (LongParameterList)
|
124
124
|
OptionParser#summarize has the variable name 'l' (UncommunicativeVariableName)
|
125
125
|
OptionParser#summarize is controlled by argument blk (ControlParameter)
|
data/lib/reek.rb
CHANGED
data/lib/reek/cli/input.rb
CHANGED
@@ -29,11 +29,11 @@ module Reek
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def working_directory_as_source
|
32
|
-
Source::SourceLocator.new(['.']).
|
32
|
+
Source::SourceLocator.new(['.']).sources
|
33
33
|
end
|
34
34
|
|
35
35
|
def sources_from_argv
|
36
|
-
Source::SourceLocator.new(@argv).
|
36
|
+
Source::SourceLocator.new(@argv).sources
|
37
37
|
end
|
38
38
|
|
39
39
|
def source_from_pipe
|
data/lib/reek/cli/options.rb
CHANGED
@@ -9,11 +9,13 @@ module Reek
|
|
9
9
|
#
|
10
10
|
# Parses the command line
|
11
11
|
#
|
12
|
+
# See docs/Command-Line-Options for details.
|
12
13
|
class Options
|
13
|
-
def initialize(argv)
|
14
|
+
def initialize(argv = [])
|
14
15
|
@argv = argv
|
15
16
|
@parser = OptionParser.new
|
16
|
-
@options = OpenStruct.new(colored:
|
17
|
+
@options = OpenStruct.new(colored: color_support?,
|
18
|
+
smells_to_detect: [])
|
17
19
|
set_up_parser
|
18
20
|
end
|
19
21
|
|
@@ -26,6 +28,10 @@ module Reek
|
|
26
28
|
|
27
29
|
private
|
28
30
|
|
31
|
+
def color_support?
|
32
|
+
$stdout.tty?
|
33
|
+
end
|
34
|
+
|
29
35
|
def set_up_parser
|
30
36
|
set_banner
|
31
37
|
set_configuration_options
|
@@ -53,9 +59,9 @@ module Reek
|
|
53
59
|
def set_alternative_formatter_options
|
54
60
|
@parser.separator "\nReport format:"
|
55
61
|
@parser.on(
|
56
|
-
'-f', '--format FORMAT', [:html, :text, :yaml, :json],
|
62
|
+
'-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml],
|
57
63
|
'Report smells in the given format:',
|
58
|
-
' html', ' text (default)', ' yaml', ' json'
|
64
|
+
' html', ' text (default)', ' yaml', ' json', ' xml'
|
59
65
|
) do |opt|
|
60
66
|
@options.report_format = opt
|
61
67
|
end
|