reek 4.0.1 → 4.0.2
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/CHANGELOG.md +6 -0
- data/Gemfile +3 -3
- data/README.md +1 -1
- data/docs/Attribute.md +1 -1
- data/docs/Boolean-Parameter.md +8 -6
- data/docs/Class-Variable.md +1 -1
- data/docs/Command-Line-Options.md +26 -1
- data/docs/Control-Couple.md +13 -9
- data/docs/Control-Parameter.md +8 -5
- data/docs/Data-Clump.md +9 -7
- data/docs/Duplicate-Method-Call.md +1 -1
- data/docs/Irresponsible-Module.md +4 -3
- data/docs/Large-Class.md +7 -12
- data/docs/Long-Parameter-List.md +7 -6
- data/docs/Long-Yield-List.md +7 -6
- data/docs/Nested-Iterators.md +7 -7
- data/docs/Nil-Check.md +8 -4
- data/docs/Prima-Donna-Method.md +19 -9
- data/docs/Reek-Driven-Development.md +3 -1
- data/docs/Repeated-Conditional.md +5 -2
- data/docs/Too-Many-Instance-Variables.md +7 -7
- data/docs/Too-Many-Methods.md +10 -9
- data/docs/Too-Many-Statements.md +8 -4
- data/docs/Uncommunicative-Method-Name.md +8 -7
- data/docs/Uncommunicative-Module-Name.md +8 -8
- data/docs/Uncommunicative-Name.md +5 -3
- data/docs/Uncommunicative-Parameter-Name.md +9 -9
- data/docs/Uncommunicative-Variable-Name.md +8 -7
- data/docs/Unused-Parameters.md +5 -4
- data/docs/Unused-Private-Method.md +3 -3
- data/docs/Utility-Function.md +3 -3
- data/lib/reek/ast/object_refs.rb +4 -4
- data/lib/reek/cli/application.rb +40 -4
- data/lib/reek/cli/command/base_command.rb +3 -2
- data/lib/reek/cli/command/report_command.rb +35 -5
- data/lib/reek/cli/command/todo_list_command.rb +4 -4
- data/lib/reek/configuration/app_configuration.rb +15 -15
- data/lib/reek/configuration/default_directive.rb +2 -1
- data/lib/reek/context/code_context.rb +1 -1
- data/lib/reek/context/module_context.rb +5 -6
- data/lib/reek/spec.rb +6 -4
- data/lib/reek/spec/should_reek_of.rb +11 -3
- data/lib/reek/version.rb +1 -1
- data/spec/factories/factories.rb +0 -11
- data/spec/reek/cli/application_spec.rb +83 -9
- data/spec/reek/cli/command/report_command_spec.rb +17 -14
- data/spec/reek/cli/command/todo_list_command_spec.rb +12 -10
- data/spec/reek/smells/duplicate_method_call_spec.rb +8 -14
- data/spec/reek/smells/nested_iterators_spec.rb +12 -16
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +2 -4
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +2 -4
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +2 -4
- data/spec/reek/smells/unused_private_method_spec.rb +47 -48
- data/spec/reek/smells/utility_function_spec.rb +5 -10
- data/spec/reek/spec/should_reek_of_spec.rb +27 -0
- metadata +2 -6
- data/lib/reek/cli/input.rb +0 -49
- data/lib/reek/cli/option_interpreter.rb +0 -58
- data/spec/reek/cli/input_spec.rb +0 -71
- data/spec/reek/cli/option_interpreter_spec.rb +0 -20
@@ -22,7 +22,9 @@ But there's another way; a much more effective "Reek-driven" approach: add Reek
|
|
22
22
|
|
23
23
|
```Ruby
|
24
24
|
it 'contains no code smells' do
|
25
|
-
|
25
|
+
Pathname.glob('lib/**/*.rb').each do |file|
|
26
|
+
expect(file).not_to reek
|
27
|
+
end
|
26
28
|
end
|
27
29
|
```
|
28
30
|
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
|
5
|
+
_Repeated Conditional_ is a case of
|
6
|
+
[Simulated Polymorphism](Simulated-Polymorphism.md). Basically it means you are
|
7
|
+
checking the same value throughout a single class and take decisions based on
|
8
|
+
this.
|
6
9
|
|
7
10
|
## Example
|
8
11
|
|
@@ -37,7 +40,7 @@ If you get this warning then you are probably not using the right abstraction or
|
|
37
40
|
|
38
41
|
## Configuration
|
39
42
|
|
40
|
-
Reek's
|
43
|
+
Reek's _Repeated Conditional_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
41
44
|
|
42
45
|
| Option | Value | Effect |
|
43
46
|
| ---------------|-------------|---------|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
## Introduction
|
2
2
|
|
3
|
-
|
3
|
+
_Too Many Instance Variables_ is a case of [Large Class](Large-Class.md).
|
4
4
|
|
5
5
|
## Example
|
6
6
|
|
@@ -14,7 +14,7 @@ TooManyInstanceVariables:
|
|
14
14
|
and this code:
|
15
15
|
|
16
16
|
```Ruby
|
17
|
-
class
|
17
|
+
class Smelly
|
18
18
|
def initialize
|
19
19
|
@arg_1 = :dummy
|
20
20
|
@arg_2 = :dummy
|
@@ -28,7 +28,7 @@ Reek would emit the following warning:
|
|
28
28
|
|
29
29
|
```
|
30
30
|
test.rb -- 5 warnings:
|
31
|
-
[1]:TooManyInstanceVariables has at least 4 instance variables
|
31
|
+
[1]:TooManyInstanceVariables: Smelly has at least 4 instance variables
|
32
32
|
```
|
33
33
|
## Current Support in Reek
|
34
34
|
|
@@ -36,8 +36,8 @@ Reek only counts the instance variables you use explicitly like in the example a
|
|
36
36
|
|
37
37
|
## Configuration
|
38
38
|
|
39
|
-
Reek's
|
39
|
+
Reek's _Too Many Instance Variables_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
40
40
|
|
41
|
-
| Option
|
42
|
-
|
|
43
|
-
| max_instance_variables
|
41
|
+
| Option | Value | Effect |
|
42
|
+
| -------------------------|---------|---------|
|
43
|
+
| `max_instance_variables` | integer | The maximum number of instance variables that are permitted. Defaults to 4 |
|
data/docs/Too-Many-Methods.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## Introduction
|
2
2
|
|
3
|
-
|
3
|
+
_Too Many Methods_ is a case of [Large Class](Large-Class.md).
|
4
4
|
|
5
5
|
## Example
|
6
6
|
|
@@ -14,7 +14,7 @@ TooManyMethods:
|
|
14
14
|
and this code:
|
15
15
|
|
16
16
|
```Ruby
|
17
|
-
class
|
17
|
+
class Smelly
|
18
18
|
def one; end
|
19
19
|
def two; end
|
20
20
|
def three; end
|
@@ -26,14 +26,15 @@ Reek would emit the following warning:
|
|
26
26
|
|
27
27
|
```
|
28
28
|
test.rb -- 1 warning:
|
29
|
-
[1]:TooManyMethods has at least 4 methods
|
29
|
+
[1]:TooManyMethods: Smelly has at least 4 methods
|
30
30
|
```
|
31
31
|
## Current Support in Reek
|
32
32
|
|
33
|
-
Reek counts all the methods it can find in a
|
33
|
+
Reek counts all the methods it can find in a class — instance *and* class
|
34
|
+
methods. So given `max_methods` from above is 4, this:
|
34
35
|
|
35
36
|
```Ruby
|
36
|
-
class
|
37
|
+
class Smelly
|
37
38
|
class << self
|
38
39
|
def one; end
|
39
40
|
def two; end
|
@@ -48,8 +49,8 @@ would cause Reek to emit the same warning as in the example above.
|
|
48
49
|
|
49
50
|
## Configuration
|
50
51
|
|
51
|
-
Reek's
|
52
|
+
Reek's _Too Many Methods_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
52
53
|
|
53
|
-
| Option
|
54
|
-
|
|
55
|
-
| max_methods
|
54
|
+
| Option | Value | Effect |
|
55
|
+
| --------------|---------|---------|
|
56
|
+
| `max_methods` | integer | The maximum number of methods that are permitted. Defaults to 15 |
|
data/docs/Too-Many-Statements.md
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
A method with
|
5
|
+
A method with _Too Many Statements_ is any method that has a large number of lines.
|
6
6
|
|
7
7
|
## Current Support in Reek
|
8
8
|
|
9
|
-
|
9
|
+
_Too Many Statements_ warns about any method that has more than 5 statements.
|
10
|
+
Reek's smell detector for _Too Many Statements_ counts +1 for every simple
|
11
|
+
statement in a method and +1 for every statement within a control structure
|
12
|
+
(`if`, `else`, `case`, `when`, `for`, `while`, `until`, `begin`, `rescue`) but
|
13
|
+
it doesn't count the control structure itself.
|
10
14
|
|
11
15
|
So the following method would score +6 in Reek's statement-counting algorithm:
|
12
16
|
|
@@ -30,13 +34,13 @@ end
|
|
30
34
|
|
31
35
|
## Configuration
|
32
36
|
|
33
|
-
Reek's
|
37
|
+
Reek's _Too Many Statements_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
34
38
|
|
35
39
|
| Option | Value | Effect |
|
36
40
|
| ---------------|-------------|---------|
|
37
41
|
| `max_statements` | integer | The maximum number of statements allowed in a method before a warning is issued. Defaults to 5. |
|
38
42
|
|
39
|
-
|
43
|
+
_Too Many Statements_'s default configuration is:
|
40
44
|
|
41
45
|
```yaml
|
42
46
|
---
|
@@ -2,21 +2,22 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
An
|
6
|
-
|
7
|
-
|
5
|
+
An _Uncommunicative Method Name_ is a method name that doesn't communicate its
|
6
|
+
intent well enough. This code smell is a case of
|
7
|
+
[Uncommunicative Name](Uncommunicative-Name.md).
|
8
8
|
|
9
9
|
## Current Support in Reek
|
10
10
|
|
11
|
-
|
11
|
+
_Uncommunicative Method Name_ checks for:
|
12
12
|
|
13
|
-
*
|
13
|
+
* single-character names
|
14
14
|
* any name ending with a number
|
15
|
-
*
|
15
|
+
* camelCaseMethodNames
|
16
16
|
|
17
17
|
## Configuration
|
18
18
|
|
19
|
-
Reek's
|
19
|
+
Reek's _Uncommunicative Method Name_ detector supports the
|
20
|
+
[Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
21
|
|
21
22
|
| Option | Value | Effect |
|
22
23
|
| ---------------|-------------|---------|
|
@@ -2,25 +2,25 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
An
|
6
|
-
|
7
|
-
|
5
|
+
An _Uncommunicative Module Name_ is a module name that doesn't communicate its
|
6
|
+
intent well enough. This code smell is a case of
|
7
|
+
[Uncommunicative Name](Uncommunicative-Name.md).
|
8
8
|
|
9
9
|
## Current Support in Reek
|
10
10
|
|
11
|
-
|
11
|
+
_Uncommunicative Module Name_ checks for:
|
12
12
|
|
13
|
-
*
|
13
|
+
* single-character names
|
14
14
|
* any name ending with a number
|
15
15
|
|
16
16
|
## Configuration
|
17
17
|
|
18
|
-
Reek's
|
18
|
+
Reek's _Uncommunicative Module Name_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
19
19
|
|
20
20
|
| Option | Value | Effect |
|
21
21
|
| ---------------|-------------|---------|
|
22
|
-
| `reject` | array of regular expressions or strings | The set of patterns
|
23
|
-
| `accept` | array of regular expressions or strings | The set of patterns
|
22
|
+
| `reject` | array of regular expressions or strings | The set of patterns or names that Reek uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/]`. |
|
23
|
+
| `accept` | array of regular expressions or strings | The set of patterns or names that Reek will accept (and not report) even if they match one of the `reject` expressions. Empty by default.|
|
24
24
|
|
25
25
|
An example configuration could look like this:
|
26
26
|
|
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
An
|
5
|
+
An _Uncommunicative Name_ is a name that doesn't communicate its intent well enough.
|
6
6
|
|
7
|
-
Poor names make it hard for the reader to build a mental picture of what's
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's
|
8
|
+
going on in the code. They can also be mis-interpreted; and they hurt the flow
|
9
|
+
of reading, because the reader must slow down to interpret the names.
|
8
10
|
|
9
11
|
## Current Support in Reek
|
10
12
|
|
11
|
-
Reek offers four
|
13
|
+
Reek offers four checks in this category:
|
12
14
|
|
13
15
|
* [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
|
14
16
|
* [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
|
@@ -2,24 +2,24 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
An
|
6
|
-
|
7
|
-
|
5
|
+
An _Uncommunicative Parameter Name_ is a parameter name that doesn't
|
6
|
+
communicate its intent well enough. This code smell is a case of
|
7
|
+
[Uncommunicative Name](Uncommunicative-Name.md).
|
8
8
|
|
9
9
|
## Current Support in Reek
|
10
10
|
|
11
|
-
|
11
|
+
_Uncommunicative Parameter Name_ checks for:
|
12
12
|
|
13
|
-
*
|
13
|
+
* single-character names
|
14
14
|
* any name ending with a number
|
15
|
-
*
|
15
|
+
* camelCaseParameterNames
|
16
16
|
|
17
17
|
## Configuration
|
18
18
|
|
19
|
-
Reek's
|
19
|
+
Reek's _Uncommunicative Parameter Name_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
20
|
|
21
|
-
| Option
|
22
|
-
|
|
21
|
+
| Option | Value | Effect |
|
22
|
+
| ---------|-------------|---------|
|
23
23
|
| `reject` | array of regular expressions or strings | The set of patterns / names that Reek uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/, /^_/]. |
|
24
24
|
| `accept` | array of regular expressions or strings | The set of patterns / names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
|
25
25
|
|
@@ -2,23 +2,24 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
An
|
6
|
-
|
7
|
-
|
5
|
+
An _Uncommunicative Variable Name_ is a variable name that doesn't communicate
|
6
|
+
its intent well enough. This code smell is a case of
|
7
|
+
[Uncommunicative Name](Uncommunicative-Name.md).
|
8
8
|
|
9
9
|
## Current Support in Reek
|
10
10
|
|
11
|
-
|
11
|
+
_Uncommunicative Variable Name_ checks for:
|
12
12
|
|
13
|
-
*
|
13
|
+
* single-character names
|
14
14
|
* any name ending with a number
|
15
15
|
* camelCaseVariableNames
|
16
16
|
|
17
17
|
## Configuration
|
18
18
|
|
19
|
-
Reek's
|
19
|
+
Reek's _Uncommunicative Variable Name_ detector supports the
|
20
|
+
[Basic Smell Options](Basic-Smell-Options.md), plus:
|
20
21
|
|
21
22
|
| Option | Value | Effect |
|
22
23
|
| ---------------|-------------|---------|
|
23
24
|
| `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
|
25
|
+
| `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 `['_']`.|
|
data/docs/Unused-Parameters.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
## Introduction
|
2
2
|
|
3
|
-
|
3
|
+
_Unused Parameter_ refers to methods with parameters that are unused in scope of the method.
|
4
4
|
|
5
|
-
Having unused parameters in a method is code smell because leaving dead code in
|
5
|
+
Having unused parameters in a method is code smell because leaving dead code in
|
6
|
+
a method can never improve the method and it makes the code confusing to read.
|
6
7
|
|
7
8
|
## Example
|
8
9
|
|
@@ -19,9 +20,9 @@ end
|
|
19
20
|
Reek would emit the following warning:
|
20
21
|
|
21
22
|
```
|
22
|
-
[2]:Klass#unused_parameters has unused parameter 'z'
|
23
|
+
[2]:UnusedParameters: Klass#unused_parameters has unused parameter 'z'
|
23
24
|
```
|
24
25
|
|
25
26
|
## Configuration
|
26
27
|
|
27
|
-
|
28
|
+
_Unused Parameter_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Classes should use their private methods. Otherwise this is dead
|
4
4
|
code which is confusing and bad for maintenance.
|
5
5
|
|
6
|
-
The
|
6
|
+
The _Unused Private Method_ detector reports unused private instance
|
7
7
|
methods and instance methods only - class methods are ignored.
|
8
8
|
|
9
9
|
## Example
|
@@ -28,13 +28,13 @@ Reek would emit the following warning:
|
|
28
28
|
|
29
29
|
## Configuration
|
30
30
|
|
31
|
-
|
31
|
+
_Unused Private Method_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
32
32
|
|
33
33
|
Private methods that are called via dynamic dispatch
|
34
34
|
will trigger a false alarm since detecting something like this is far out of
|
35
35
|
scope for Reek. In this case you can disable this detector via the `exclude`
|
36
36
|
configuration option (which is part of the [Basic Smell Options](Basic-Smell-Options.md))
|
37
|
-
for instance like this (an example from
|
37
|
+
for instance like this (an example from Reek's own codebase):
|
38
38
|
|
39
39
|
```Ruby
|
40
40
|
# :reek:UnusedPrivateMethod: { exclude: [ !ruby/regexp /process_/ ] }
|
data/docs/Utility-Function.md
CHANGED
@@ -43,9 +43,9 @@ _[Feature Envy](Feature-Envy.md)_ is only triggered if there are some references
|
|
43
43
|
|
44
44
|
Reek's _Utility Function_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
45
45
|
|
46
|
-
| Option
|
47
|
-
|
|
48
|
-
| public_methods_only | Boolean | Disable this smell detector for non-public methods (which means "private" and "protected") |
|
46
|
+
| Option | Value | Effect |
|
47
|
+
| ----------------------|-------------|---------|
|
48
|
+
| `public_methods_only` | Boolean | Disable this smell detector for non-public methods (which means "private" and "protected") |
|
49
49
|
|
50
50
|
A sample configuration file would look like this:
|
51
51
|
|
data/lib/reek/ast/object_refs.rb
CHANGED
@@ -13,10 +13,10 @@ module Reek
|
|
13
13
|
# end
|
14
14
|
#
|
15
15
|
# would make "@refs" below look like this after the TreeWalker has done his job:
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
16
|
+
# {
|
17
|
+
# :self=>[2, 3], # `bar.call_me` and `bar.maybe` count as refs to `self` in line 2 and 3
|
18
|
+
# :thing=>[3] # `thing.wat` in `bar.maybe()` counts as one reference to `thing`
|
19
|
+
# }
|
20
20
|
#
|
21
21
|
class ObjectRefs
|
22
22
|
def initialize
|
data/lib/reek/cli/application.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative 'options'
|
3
|
-
require_relative 'option_interpreter'
|
4
3
|
require_relative '../configuration/app_configuration'
|
4
|
+
require_relative '../source/source_locator'
|
5
5
|
require_relative 'command/report_command'
|
6
6
|
require_relative 'command/todo_list_command'
|
7
7
|
|
@@ -13,18 +13,19 @@ module Reek
|
|
13
13
|
# command line.
|
14
14
|
#
|
15
15
|
class Application
|
16
|
-
include Input
|
17
16
|
attr_reader :configuration
|
18
17
|
|
19
18
|
def initialize(argv)
|
20
19
|
@options = configure_options(argv)
|
21
20
|
@status = options.success_exit_code
|
22
21
|
@configuration = configure_app_configuration(options.config_file)
|
23
|
-
@command = command_class.new(
|
22
|
+
@command = command_class.new(options: options,
|
23
|
+
sources: sources,
|
24
|
+
configuration: configuration)
|
24
25
|
end
|
25
26
|
|
26
27
|
def execute
|
27
|
-
command.execute
|
28
|
+
command.execute
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
@@ -50,9 +51,44 @@ module Reek
|
|
50
51
|
options.generate_todo_list ? Command::TodoListCommand : Command::ReportCommand
|
51
52
|
end
|
52
53
|
|
54
|
+
def sources
|
55
|
+
if no_source_files_given?
|
56
|
+
if input_was_piped?
|
57
|
+
source_from_pipe
|
58
|
+
else
|
59
|
+
working_directory_as_source
|
60
|
+
end
|
61
|
+
else
|
62
|
+
sources_from_argv
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
53
66
|
def argv
|
54
67
|
options.argv
|
55
68
|
end
|
69
|
+
|
70
|
+
# :reek:UtilityFunction
|
71
|
+
def input_was_piped?
|
72
|
+
!$stdin.tty?
|
73
|
+
end
|
74
|
+
|
75
|
+
def no_source_files_given?
|
76
|
+
# At this point we have deleted all options from argv. The only remaining entries
|
77
|
+
# are paths to the source files. If argv is empty, this means that no files were given.
|
78
|
+
argv.empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
def working_directory_as_source
|
82
|
+
Source::SourceLocator.new(['.'], configuration: configuration).sources
|
83
|
+
end
|
84
|
+
|
85
|
+
def sources_from_argv
|
86
|
+
Source::SourceLocator.new(argv).sources
|
87
|
+
end
|
88
|
+
|
89
|
+
def source_from_pipe
|
90
|
+
[$stdin]
|
91
|
+
end
|
56
92
|
end
|
57
93
|
end
|
58
94
|
end
|