reek 3.10.2 → 3.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +46 -10
- data/docs/Command-Line-Options.md +1 -1
- data/docs/Unused-Private-Method.md +4 -4
- data/docs/YAML-Reports.md +1 -1
- data/features/command_line_interface/options.feature +3 -0
- data/features/step_definitions/todo_list_steps.rb +40 -0
- data/features/todo_list.feature +72 -0
- data/lib/reek/cli/application.rb +7 -2
- data/lib/reek/cli/command/base_command.rb +26 -0
- data/lib/reek/cli/command/report_command.rb +38 -0
- data/lib/reek/cli/command/todo_list_command.rb +49 -0
- data/lib/reek/cli/options.rb +33 -23
- data/lib/reek/version.rb +1 -1
- data/spec/factories/factories.rb +12 -0
- data/spec/reek/cli/application_spec.rb +11 -9
- data/spec/reek/cli/{reek_command_spec.rb → command/report_command_spec.rb} +3 -3
- data/spec/reek/cli/command/todo_list_command_spec.rb +64 -0
- metadata +9 -5
- data/lib/reek/cli/command.rb +0 -16
- data/lib/reek/cli/reek_command.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67870a4dc44b9996f80e3daddb3614cbc9a1ee6d
|
4
|
+
data.tar.gz: 8eedb66acfa7d1b874a2806ffd7b6aab69769794
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad6862ed6352640db4ff88fbe718c6116579d257a6c83337dd1603e1a8580686da6895be5b478db0d5ebd4fd3e288c3e29a9e56ae25cc5115053eef8a18540f9
|
7
|
+
data.tar.gz: 8e1cc3bd8e0d9f6c00dfa21e2cd2ba6c9706b817c0a6c895d75be07f58f28f2ce9159f20edbceb1d1e9d676869f65b7771119ac339af04cc2ade6c01854ae8b9
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Reek is a tool that examines Ruby classes, modules and methods and reports any
|
|
16
16
|
[Code Smells](docs/Code-Smells.md) it finds.
|
17
17
|
|
18
18
|
For an excellent introduction to
|
19
|
-
[Code Smells](docs/Code-Smells.md) and
|
19
|
+
[Code Smells](docs/Code-Smells.md) and Reek check out [this blog post](https://blog.codeship.com/how-to-find-ruby-code-smells-with-reek/)
|
20
20
|
or [that one](https://troessner.wordpress.com/2016/01/01/the-latest-and-greatest-additions-to-reek/). There is also [this talk](https://www.youtube.com/watch?v=ZzqOuHI5MkA) from the RUBYCONF Porto.
|
21
21
|
|
22
22
|
Install it via rubygems:
|
@@ -63,7 +63,7 @@ demo.rb -- 8 warnings:
|
|
63
63
|
|
64
64
|
## Supported rubies
|
65
65
|
|
66
|
-
|
66
|
+
Reek is officially running on the following MRI rubies:
|
67
67
|
|
68
68
|
- 2.0
|
69
69
|
- 2.1
|
@@ -95,7 +95,7 @@ class Item < ActiveRecord::Base
|
|
95
95
|
end
|
96
96
|
```
|
97
97
|
|
98
|
-
Running
|
98
|
+
Running Reek on this file like this:
|
99
99
|
|
100
100
|
```
|
101
101
|
reek app/models/shopping_cart.rb
|
@@ -133,13 +133,13 @@ those first when you have a warning that you don't know how to deal with.
|
|
133
133
|
|
134
134
|
## Sources
|
135
135
|
|
136
|
-
There are multiple ways you can have
|
136
|
+
There are multiple ways you can have Reek work on sources, the most common one just being
|
137
137
|
|
138
138
|
```Bash
|
139
139
|
reek lib/
|
140
140
|
```
|
141
141
|
|
142
|
-
If you don't pass any source arguments to
|
142
|
+
If you don't pass any source arguments to Reek it just takes the current working directory as source.
|
143
143
|
|
144
144
|
So
|
145
145
|
|
@@ -153,7 +153,7 @@ is the exact same thing as being explicit:
|
|
153
153
|
reek .
|
154
154
|
```
|
155
155
|
|
156
|
-
Additionally you can pipe code to
|
156
|
+
Additionally you can pipe code to Reek like this:
|
157
157
|
|
158
158
|
```Bash
|
159
159
|
echo "class C; def m; end; end" | reek
|
@@ -210,7 +210,7 @@ For a summary of those CLI options see [Command-Line Options](docs/Command-Line-
|
|
210
210
|
|
211
211
|
Configuring Reek via a configuration file is by far the most powerful way.
|
212
212
|
|
213
|
-
There are three ways of passing
|
213
|
+
There are three ways of passing Reek a configuration file:
|
214
214
|
|
215
215
|
1. Using the CLI `-c` switch (see [_Command-line interface_](#command-line-interface) above)
|
216
216
|
2. Having a file ending with `.reek` either in your current working directory or in a parent directory (more on that later)
|
@@ -337,6 +337,42 @@ end
|
|
337
337
|
|
338
338
|
This is an incredible powerful feature and further explained under [Smell Suppresion](docs/Smell-Suppression.md).
|
339
339
|
|
340
|
+
### Generating a 'todo' list
|
341
|
+
|
342
|
+
Integrating tools like Reek into an existing larger codebase can be daunting when you have to fix
|
343
|
+
possibly hundreds or thousands of smell warnings first.
|
344
|
+
Sure you could manually disable smell warnings like shown above but depending on the size of your
|
345
|
+
codebase this might not be an option.
|
346
|
+
Fortunately Reek provides a 'todo' flag which you can use to generate a configuration that will
|
347
|
+
suppress all smell warnings for the current codebase:
|
348
|
+
|
349
|
+
```Bash
|
350
|
+
reek --todo lib/
|
351
|
+
```
|
352
|
+
|
353
|
+
This will create the file '.todo.reek' in your current working directory.
|
354
|
+
|
355
|
+
You can then use this as your configuration - since your working directory
|
356
|
+
probably is your project root in most cases you don't have to tell Reek
|
357
|
+
explicitly to use '.todo.reek' because Reek will automatically pick it up
|
358
|
+
and use it as configuration file. See [Configuration Loading](#configuration-loading) above.
|
359
|
+
|
360
|
+
If for whatever reasons you decide to put '.todo.reek' somewhere else where
|
361
|
+
Reek won't pick it up automatically you need to tell Reek explicitly to do so
|
362
|
+
via:
|
363
|
+
|
364
|
+
```Bash
|
365
|
+
reek -c whatever/.todo.reek lib/
|
366
|
+
```
|
367
|
+
|
368
|
+
Note that if you re-run
|
369
|
+
|
370
|
+
```Bash
|
371
|
+
reek --todo lib/
|
372
|
+
```
|
373
|
+
|
374
|
+
'.todo.reek' will get overwritten with a possibly updated configuration.
|
375
|
+
|
340
376
|
## Usage
|
341
377
|
|
342
378
|
Besides the obvious
|
@@ -386,7 +422,7 @@ If you don't feel like getting your hands dirty with code there are still other
|
|
386
422
|
|
387
423
|
## Output formats
|
388
424
|
|
389
|
-
|
425
|
+
Reek supports 5 output formats:
|
390
426
|
|
391
427
|
* plain text (default)
|
392
428
|
* HTML (`--format html`)
|
@@ -429,12 +465,12 @@ Be careful though, Reek does not merge your configuration entries, so if you alr
|
|
429
465
|
|
430
466
|
* [overcommit](https://github.com/brigade/overcommit) - a Git commit hook manager with support for
|
431
467
|
Reek
|
432
|
-
* [ruby-critic](https://github.com/whitesmith/rubycritic) - gem that wraps around static analysis gems such as
|
468
|
+
* [ruby-critic](https://github.com/whitesmith/rubycritic) - gem that wraps around static analysis gems such as Reek, [flay](https://github.com/seattlerb/flay) and [flog](https://github.com/seattlerb/flog)
|
433
469
|
* [pronto-reek](https://github.com/mmozuras/pronto-reek) - Reek integration for [pronto](https://github.com/mmozuras/pronto)
|
434
470
|
|
435
471
|
### Misc
|
436
472
|
|
437
|
-
* [Colorful output for
|
473
|
+
* [Colorful output for Reek](https://github.com/joenas/preek)
|
438
474
|
(also with [Guard::Preek](https://github.com/joenas/guard-preek))
|
439
475
|
|
440
476
|
## Brothers and sisters
|
@@ -18,7 +18,7 @@ class Car
|
|
18
18
|
end
|
19
19
|
```
|
20
20
|
|
21
|
-
|
21
|
+
Reek would emit the following warning:
|
22
22
|
|
23
23
|
```
|
24
24
|
2 warnings:
|
@@ -32,7 +32,7 @@ end
|
|
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
|
-
scope for
|
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
37
|
for instance like this (an example from `Reek's` own codebase):
|
38
38
|
|
@@ -50,7 +50,7 @@ a method scope (like you can see above).
|
|
50
50
|
|
51
51
|
## Known limitations
|
52
52
|
|
53
|
-
* Method calls via dynamic dispatch (e.g. via `send`) is something
|
53
|
+
* Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
|
54
54
|
static tool for that matter) can not detect.
|
55
55
|
* Method calls via callback like [Rails filters](http://guides.rubyonrails.org/action_controller_overview.html#filters)
|
56
56
|
will trigger this as well, e.g.:
|
@@ -65,7 +65,7 @@ a method scope (like you can see above).
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
```
|
68
|
-
*
|
68
|
+
* Reek works on a per-file base. This means that using something like the [template pattern](https://en.wikipedia.org/wiki/Template_method_pattern)
|
69
69
|
with private methods will trigger this detector.
|
70
70
|
We do believe though that using private methods to fill out a template in a
|
71
71
|
superclass is not a good idea in general so this probably isn't really a problem
|
data/docs/YAML-Reports.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
|
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
6
|
|
7
7
|
| Field | Type | Value |
|
8
8
|
| ---------------|-------------|---------|
|
@@ -43,6 +43,9 @@ Feature: Reek can be controlled using command-line options
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
44
44
|
--smell SMELL Detect smell SMELL (default: all enabled smells)
|
45
45
|
|
46
|
+
Generate a todo list:
|
47
|
+
-t, --todo Generate a todo list
|
48
|
+
|
46
49
|
Report format:
|
47
50
|
-f, --format FORMAT Report smells in the given format:
|
48
51
|
html
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Given(/^a directory 'lib' with one clean file 'clean\.rb' and one dirty file 'dirty\.rb'$/) do
|
2
|
+
write_file('lib/clean.rb', <<-EOS.strip_heredoc)
|
3
|
+
# clean class for testing purposes
|
4
|
+
class Clean
|
5
|
+
def super_clean
|
6
|
+
puts @janitor.name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
EOS
|
10
|
+
|
11
|
+
write_file('lib/dirty.rb', <<-EOS.strip_heredoc)
|
12
|
+
class Dirty
|
13
|
+
def a; end
|
14
|
+
def b; end
|
15
|
+
end
|
16
|
+
EOS
|
17
|
+
end
|
18
|
+
|
19
|
+
Given(/^a configuration file 'config\.reek' that partially masks 'dirty\.rb'$/) do
|
20
|
+
write_file('config.reek', <<-EOS.strip_heredoc)
|
21
|
+
---
|
22
|
+
IrresponsibleModule:
|
23
|
+
exclude:
|
24
|
+
- Dirty
|
25
|
+
UncommunicativeMethodName:
|
26
|
+
exclude:
|
27
|
+
- Dirty#b
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
|
31
|
+
Given(/^a directory 'superclean' with one clean file 'clean\.rb'$/) do
|
32
|
+
write_file('superclean/clean.rb', <<-EOS.strip_heredoc)
|
33
|
+
# clean class for testing purposes
|
34
|
+
class Clean
|
35
|
+
def super_clean
|
36
|
+
puts @janitor.name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
EOS
|
40
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Feature:
|
2
|
+
|
3
|
+
Write a Reek configuration as a kind of todo list that will prevent Reek
|
4
|
+
from reporting smells on the current code.
|
5
|
+
This can then be worked on later on.
|
6
|
+
The main goal here would be to ease the Reek adoption by allowing developers to:
|
7
|
+
- introduce Reek right away (e.g. for CI)
|
8
|
+
- exclude the "old" smells from getting reported
|
9
|
+
- fix them step by step
|
10
|
+
- get rid of the todo file
|
11
|
+
|
12
|
+
Background:
|
13
|
+
Given a directory 'lib' with one clean file 'clean.rb' and one dirty file 'dirty.rb'
|
14
|
+
And a directory 'superclean' with one clean file 'clean.rb'
|
15
|
+
|
16
|
+
Scenario: Generate a proper todo file that disables all found smells
|
17
|
+
When I run reek lib
|
18
|
+
Then the exit status indicates smells
|
19
|
+
And it reports:
|
20
|
+
"""
|
21
|
+
lib/dirty.rb -- 3 warnings:
|
22
|
+
[1]:IrresponsibleModule: Dirty has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
|
23
|
+
[2]:UncommunicativeMethodName: Dirty#a has the name 'a' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
|
24
|
+
[3]:UncommunicativeMethodName: Dirty#b has the name 'b' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
|
25
|
+
3 total warnings
|
26
|
+
"""
|
27
|
+
When I run reek --todo lib
|
28
|
+
Then it succeeds
|
29
|
+
And a file named ".todo.reek" should exist
|
30
|
+
And the file ".todo.reek" should contain:
|
31
|
+
"""
|
32
|
+
---
|
33
|
+
IrresponsibleModule:
|
34
|
+
exclude:
|
35
|
+
- Dirty
|
36
|
+
UncommunicativeMethodName:
|
37
|
+
exclude:
|
38
|
+
- Dirty#a
|
39
|
+
- Dirty#b
|
40
|
+
"""
|
41
|
+
When I run reek -c .todo.reek lib
|
42
|
+
Then it succeeds
|
43
|
+
|
44
|
+
Scenario: Respects an configuration file
|
45
|
+
Given a configuration file 'config.reek' that partially masks 'dirty.rb'
|
46
|
+
When I run reek -c config.reek --todo lib
|
47
|
+
Then it succeeds
|
48
|
+
And a file named ".todo.reek" should exist
|
49
|
+
And the file ".todo.reek" should contain:
|
50
|
+
"""
|
51
|
+
---
|
52
|
+
UncommunicativeMethodName:
|
53
|
+
exclude:
|
54
|
+
- Dirty#a
|
55
|
+
"""
|
56
|
+
|
57
|
+
Scenario: Print out a helpful message that explains to the user what to do next
|
58
|
+
When I run reek --todo lib
|
59
|
+
Then it reports:
|
60
|
+
"""
|
61
|
+
|
62
|
+
'.todo.reek' generated! You can now use this as a starting point for your configuration.
|
63
|
+
"""
|
64
|
+
|
65
|
+
Scenario: Reacts appropiately when there are no smells
|
66
|
+
When I run reek --todo superclean/
|
67
|
+
Then a file named ".todo.reek" should not exist
|
68
|
+
And it reports:
|
69
|
+
"""
|
70
|
+
|
71
|
+
'.todo.reek' not generated because there were no smells found!
|
72
|
+
"""
|
data/lib/reek/cli/application.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require_relative 'options'
|
2
|
-
require_relative 'reek_command'
|
3
2
|
require_relative 'option_interpreter'
|
4
3
|
require_relative '../configuration/app_configuration'
|
4
|
+
require_relative 'command/report_command'
|
5
|
+
require_relative 'command/todo_list_command'
|
5
6
|
|
6
7
|
module Reek
|
7
8
|
module CLI
|
@@ -17,7 +18,7 @@ module Reek
|
|
17
18
|
@options = configure_options(argv)
|
18
19
|
@status = options.success_exit_code
|
19
20
|
@configuration = configure_app_configuration(options.config_file)
|
20
|
-
@command =
|
21
|
+
@command = command_class.new(OptionInterpreter.new(options))
|
21
22
|
end
|
22
23
|
|
23
24
|
def execute
|
@@ -42,6 +43,10 @@ module Reek
|
|
42
43
|
$stderr.puts "Error: #{error}"
|
43
44
|
exit Options::DEFAULT_ERROR_EXIT_CODE
|
44
45
|
end
|
46
|
+
|
47
|
+
def command_class
|
48
|
+
options.generate_todo_list ? Command::TodoListCommand : Command::ReportCommand
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Reek
|
2
|
+
module CLI
|
3
|
+
module Command
|
4
|
+
#
|
5
|
+
# Base class for all commands
|
6
|
+
#
|
7
|
+
class BaseCommand
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :options
|
15
|
+
|
16
|
+
def smell_names
|
17
|
+
@smell_names ||= options.smells_to_detect
|
18
|
+
end
|
19
|
+
|
20
|
+
def sources
|
21
|
+
@sources ||= options.sources
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'base_command'
|
2
|
+
require_relative '../../examiner'
|
3
|
+
|
4
|
+
module Reek
|
5
|
+
module CLI
|
6
|
+
module Command
|
7
|
+
#
|
8
|
+
# A command to collect smells from a set of sources and write them out in
|
9
|
+
# text report format.
|
10
|
+
#
|
11
|
+
class ReportCommand < BaseCommand
|
12
|
+
def execute(app)
|
13
|
+
populate_reporter_with_smells app
|
14
|
+
reporter.show
|
15
|
+
result_code
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def populate_reporter_with_smells(app)
|
21
|
+
sources.each do |source|
|
22
|
+
reporter.add_examiner Examiner.new(source,
|
23
|
+
smell_names,
|
24
|
+
configuration: app.configuration)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def result_code
|
29
|
+
reporter.smells? ? options.failure_exit_code : options.success_exit_code
|
30
|
+
end
|
31
|
+
|
32
|
+
def reporter
|
33
|
+
@reporter ||= options.reporter
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'base_command'
|
2
|
+
require_relative '../../examiner'
|
3
|
+
|
4
|
+
module Reek
|
5
|
+
module CLI
|
6
|
+
module Command
|
7
|
+
#
|
8
|
+
# A command to collect smells from a set of sources and writes a configuration
|
9
|
+
# file that can serve as a todo list.
|
10
|
+
#
|
11
|
+
class TodoListCommand < BaseCommand
|
12
|
+
FILE_NAME = '.todo.reek'.freeze
|
13
|
+
|
14
|
+
def execute(app)
|
15
|
+
smells = scan_for_smells(app)
|
16
|
+
if smells.empty?
|
17
|
+
puts "\n'.todo.reek' not generated because "\
|
18
|
+
'there were no smells found!'
|
19
|
+
else
|
20
|
+
File.write FILE_NAME, groups_for(smells).to_yaml
|
21
|
+
puts "\n'.todo.reek' generated! You can now use "\
|
22
|
+
'this as a starting point for your configuration.'
|
23
|
+
end
|
24
|
+
options.success_exit_code
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def scan_for_smells(app)
|
30
|
+
sources.map do |source|
|
31
|
+
Examiner.new(source,
|
32
|
+
smell_names,
|
33
|
+
configuration: app.configuration)
|
34
|
+
end.map(&:smells).flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
def groups_for(smells)
|
38
|
+
@groups ||= begin
|
39
|
+
Hash[
|
40
|
+
smells.group_by(&:smell_type).map do |smell_type, smells_for_type|
|
41
|
+
[smell_type, { 'exclude' => smells_for_type.map(&:context) }]
|
42
|
+
end
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/reek/cli/options.rb
CHANGED
@@ -9,7 +9,7 @@ module Reek
|
|
9
9
|
#
|
10
10
|
# See {file:docs/Command-Line-Options.md} for details.
|
11
11
|
#
|
12
|
-
# :reek:TooManyInstanceVariables: { max_instance_variables:
|
12
|
+
# :reek:TooManyInstanceVariables: { max_instance_variables: 10 }
|
13
13
|
# :reek:Attribute: { enabled: false }
|
14
14
|
#
|
15
15
|
class Options
|
@@ -26,18 +26,20 @@ module Reek
|
|
26
26
|
:show_links,
|
27
27
|
:sorting,
|
28
28
|
:success_exit_code,
|
29
|
-
:failure_exit_code
|
29
|
+
:failure_exit_code,
|
30
|
+
:generate_todo_list
|
30
31
|
|
31
32
|
def initialize(argv = [])
|
32
|
-
@argv
|
33
|
-
@parser
|
34
|
-
@report_format
|
35
|
-
@location_format
|
36
|
-
@show_links
|
37
|
-
@smells_to_detect
|
38
|
-
@colored
|
39
|
-
@success_exit_code
|
40
|
-
@failure_exit_code
|
33
|
+
@argv = argv
|
34
|
+
@parser = OptionParser.new
|
35
|
+
@report_format = :text
|
36
|
+
@location_format = :numbers
|
37
|
+
@show_links = true
|
38
|
+
@smells_to_detect = []
|
39
|
+
@colored = color_support?
|
40
|
+
@success_exit_code = DEFAULT_SUCCESS_EXIT_CODE
|
41
|
+
@failure_exit_code = DEFAULT_FAILURE_EXIT_CODE
|
42
|
+
@generate_todo_list = false
|
41
43
|
|
42
44
|
set_up_parser
|
43
45
|
end
|
@@ -55,10 +57,11 @@ module Reek
|
|
55
57
|
$stdout.tty?
|
56
58
|
end
|
57
59
|
|
58
|
-
# :reek:TooManyStatements: { max_statements:
|
60
|
+
# :reek:TooManyStatements: { max_statements: 7 }
|
59
61
|
def set_up_parser
|
60
62
|
set_banner
|
61
63
|
set_configuration_options
|
64
|
+
set_generate_todo_list_options
|
62
65
|
set_alternative_formatter_options
|
63
66
|
set_report_formatting_options
|
64
67
|
set_exit_codes
|
@@ -81,17 +84,6 @@ module Reek
|
|
81
84
|
EOB
|
82
85
|
end
|
83
86
|
|
84
|
-
def set_alternative_formatter_options
|
85
|
-
parser.separator "\nReport format:"
|
86
|
-
parser.on(
|
87
|
-
'-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml, :code_climate],
|
88
|
-
'Report smells in the given format:',
|
89
|
-
' html', ' text (default)', ' yaml', ' json', ' xml', ' code_climate'
|
90
|
-
) do |opt|
|
91
|
-
self.report_format = opt
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
87
|
# :reek:TooManyStatements: { max_statements: 6 }
|
96
88
|
def set_configuration_options
|
97
89
|
parser.separator 'Configuration:'
|
@@ -104,6 +96,24 @@ module Reek
|
|
104
96
|
end
|
105
97
|
end
|
106
98
|
|
99
|
+
def set_generate_todo_list_options
|
100
|
+
parser.separator '\nGenerate a todo list:'
|
101
|
+
parser.on('-t', '--todo', 'Generate a todo list') do
|
102
|
+
self.generate_todo_list = true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def set_alternative_formatter_options
|
107
|
+
parser.separator "\nReport format:"
|
108
|
+
parser.on(
|
109
|
+
'-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml, :code_climate],
|
110
|
+
'Report smells in the given format:',
|
111
|
+
' html', ' text (default)', ' yaml', ' json', ' xml', ' code_climate'
|
112
|
+
) do |opt|
|
113
|
+
self.report_format = opt
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
107
117
|
def set_report_formatting_options
|
108
118
|
parser.separator "\nText format options:"
|
109
119
|
set_up_color_option
|
data/lib/reek/version.rb
CHANGED
data/spec/factories/factories.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require_relative '../../lib/reek/smells'
|
2
2
|
require_relative '../../lib/reek/smells/smell_detector'
|
3
3
|
require_relative '../../lib/reek/smells/smell_warning'
|
4
|
+
require_relative '../../lib/reek/cli/option_interpreter'
|
5
|
+
require_relative '../../lib/reek/cli/options'
|
4
6
|
|
5
7
|
FactoryGirl.define do
|
6
8
|
factory :context, class: Reek::Context::CodeContext do
|
@@ -51,4 +53,14 @@ FactoryGirl.define do
|
|
51
53
|
parameters: parameters)
|
52
54
|
end
|
53
55
|
end
|
56
|
+
|
57
|
+
factory :options_interpreter_with_empty_sources, class: Reek::CLI::OptionInterpreter do
|
58
|
+
transient do
|
59
|
+
options { Reek::CLI::Options.new [] }
|
60
|
+
end
|
61
|
+
|
62
|
+
initialize_with do
|
63
|
+
Reek::CLI::OptionInterpreter.new(options)
|
64
|
+
end
|
65
|
+
end
|
54
66
|
end
|
@@ -15,17 +15,19 @@ RSpec.describe Reek::CLI::Application do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
context 'report_command' do
|
19
|
+
describe '#execute' do
|
20
|
+
let(:command) { double 'reek_command' }
|
21
|
+
let(:app) { Reek::CLI::Application.new [] }
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
before do
|
24
|
+
allow(Reek::CLI::Command::ReportCommand).to receive(:new).and_return command
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
it "returns the command's result code" do
|
28
|
+
allow(command).to receive(:execute).and_return 'foo'
|
29
|
+
expect(app.execute).to eq 'foo'
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_lib 'reek/cli/
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_lib 'reek/cli/command/report_command'
|
3
3
|
require_lib 'reek/cli/options'
|
4
4
|
require_lib 'reek/cli/option_interpreter'
|
5
5
|
|
6
|
-
RSpec.describe Reek::CLI::
|
6
|
+
RSpec.describe Reek::CLI::Command::ReportCommand do
|
7
7
|
describe '#execute' do
|
8
8
|
let(:options) { Reek::CLI::Options.new [] }
|
9
9
|
let(:option_interpreter) { Reek::CLI::OptionInterpreter.new(options) }
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_lib 'reek/cli/command/todo_list_command'
|
3
|
+
require_lib 'reek/cli/options'
|
4
|
+
require_lib 'reek/cli/option_interpreter'
|
5
|
+
|
6
|
+
RSpec.describe Reek::CLI::Command::TodoListCommand do
|
7
|
+
describe '#execute' do
|
8
|
+
let(:option_interpreter) { FactoryGirl.build(:options_interpreter_with_empty_sources) }
|
9
|
+
let(:app) { double 'app' }
|
10
|
+
let(:command) { described_class.new option_interpreter }
|
11
|
+
|
12
|
+
before do
|
13
|
+
$stdout = StringIO.new
|
14
|
+
allow(File).to receive(:write)
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:all) do
|
18
|
+
$stdout = STDOUT
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'smells found' do
|
22
|
+
before do
|
23
|
+
smells = [FactoryGirl.build(:smell_warning)]
|
24
|
+
allow(command).to receive(:scan_for_smells).and_return(smells)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'shows a proper message' do
|
28
|
+
expected = "\n'.todo.reek' generated! You can now use this as a starting point for your configuration.\n"
|
29
|
+
expect { command.execute app }.to output(expected).to_stdout
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns a success code' do
|
33
|
+
result = command.execute app
|
34
|
+
expect(result).to eq(Reek::CLI::Options::DEFAULT_SUCCESS_EXIT_CODE)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'no smells found' do
|
39
|
+
before do
|
40
|
+
allow(command).to receive(:scan_for_smells).and_return []
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'shows a proper message' do
|
44
|
+
expected = "\n'.todo.reek' not generated because there were no smells found!\n"
|
45
|
+
expect { command.execute app }.to output(expected).to_stdout
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns a success code' do
|
49
|
+
result = command.execute app
|
50
|
+
expect(result).to eq Reek::CLI::Options::DEFAULT_SUCCESS_EXIT_CODE
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'groups_for' do
|
55
|
+
let(:command) { described_class.new({}) }
|
56
|
+
|
57
|
+
it 'returns a proper hash representation of the smells found' do
|
58
|
+
smells = [FactoryGirl.build(:smell_warning)]
|
59
|
+
expected = { 'FeatureEnvy' => { 'exclude' => ['self'] } }
|
60
|
+
expect(command.send(:groups_for, smells)).to eq(expected)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: '3.11'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-02-
|
14
|
+
date: 2016-02-18 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: codeclimate-engine-rb
|
@@ -155,7 +155,9 @@ files:
|
|
155
155
|
- features/step_definitions/.rubocop.yml
|
156
156
|
- features/step_definitions/reek_steps.rb
|
157
157
|
- features/step_definitions/sample_file_steps.rb
|
158
|
+
- features/step_definitions/todo_list_steps.rb
|
158
159
|
- features/support/env.rb
|
160
|
+
- features/todo_list.feature
|
159
161
|
- lib/reek.rb
|
160
162
|
- lib/reek/ast/ast_node_class_map.rb
|
161
163
|
- lib/reek/ast/node.rb
|
@@ -181,11 +183,12 @@ files:
|
|
181
183
|
- lib/reek/ast/sexp_extensions/when.rb
|
182
184
|
- lib/reek/ast/sexp_extensions/yield.rb
|
183
185
|
- lib/reek/cli/application.rb
|
184
|
-
- lib/reek/cli/command.rb
|
186
|
+
- lib/reek/cli/command/base_command.rb
|
187
|
+
- lib/reek/cli/command/report_command.rb
|
188
|
+
- lib/reek/cli/command/todo_list_command.rb
|
185
189
|
- lib/reek/cli/input.rb
|
186
190
|
- lib/reek/cli/option_interpreter.rb
|
187
191
|
- lib/reek/cli/options.rb
|
188
|
-
- lib/reek/cli/reek_command.rb
|
189
192
|
- lib/reek/cli/silencer.rb
|
190
193
|
- lib/reek/cli/warning_collector.rb
|
191
194
|
- lib/reek/code_comment.rb
|
@@ -271,10 +274,11 @@ files:
|
|
271
274
|
- spec/reek/ast/reference_collector_spec.rb
|
272
275
|
- spec/reek/ast/sexp_extensions_spec.rb
|
273
276
|
- spec/reek/cli/application_spec.rb
|
277
|
+
- spec/reek/cli/command/report_command_spec.rb
|
278
|
+
- spec/reek/cli/command/todo_list_command_spec.rb
|
274
279
|
- spec/reek/cli/input_spec.rb
|
275
280
|
- spec/reek/cli/option_interpreter_spec.rb
|
276
281
|
- spec/reek/cli/options_spec.rb
|
277
|
-
- spec/reek/cli/reek_command_spec.rb
|
278
282
|
- spec/reek/cli/warning_collector_spec.rb
|
279
283
|
- spec/reek/code_comment_spec.rb
|
280
284
|
- spec/reek/configuration/app_configuration_spec.rb
|
data/lib/reek/cli/command.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require_relative 'command'
|
2
|
-
require_relative '../examiner'
|
3
|
-
|
4
|
-
module Reek
|
5
|
-
module CLI
|
6
|
-
#
|
7
|
-
# A command to collect smells from a set of sources and write them out in
|
8
|
-
# text report format.
|
9
|
-
#
|
10
|
-
class ReekCommand < Command
|
11
|
-
def execute(app)
|
12
|
-
options.sources.each do |source|
|
13
|
-
reporter.add_examiner Examiner.new(source, smell_names, configuration: app.configuration)
|
14
|
-
end
|
15
|
-
reporter.show
|
16
|
-
result_code
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def result_code
|
22
|
-
reporter.smells? ? options.failure_exit_code : options.success_exit_code
|
23
|
-
end
|
24
|
-
|
25
|
-
def reporter
|
26
|
-
@reporter ||= options.reporter
|
27
|
-
end
|
28
|
-
|
29
|
-
def smell_names
|
30
|
-
@smell_names ||= options.smells_to_detect
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|