reek 3.10.2 → 3.11
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 +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
|