kevinrutherford-reek 1.1.3.10 → 1.1.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.
- data/History.txt +5 -1
- data/bin/reek +2 -17
- data/features/masking_smells.feature +22 -8
- data/features/options.feature +12 -5
- data/features/reports.feature +22 -12
- data/features/samples.feature +66 -66
- data/lib/reek/adapters/application.rb +47 -0
- data/lib/reek/{config_file.rb → adapters/config_file.rb} +0 -0
- data/lib/reek/adapters/core_extras.rb +72 -0
- data/lib/reek/{object_source.rb → adapters/object_source.rb} +7 -6
- data/lib/reek/{rake_task.rb → adapters/rake_task.rb} +2 -2
- data/lib/reek/adapters/report.rb +91 -0
- data/lib/reek/adapters/source.rb +49 -0
- data/lib/reek/{spec.rb → adapters/spec.rb} +20 -9
- data/lib/reek/block_context.rb +1 -1
- data/lib/reek/class_context.rb +3 -2
- data/lib/reek/code_parser.rb +4 -0
- data/lib/reek/command_line.rb +85 -0
- data/lib/reek/detector_stack.rb +23 -6
- data/lib/reek/exceptions.reek +5 -1
- data/lib/reek/smell_warning.rb +5 -1
- data/lib/reek/smells/duplication.rb +5 -3
- data/lib/reek/smells/smell_detector.rb +15 -1
- data/lib/reek/smells/uncommunicative_name.rb +1 -1
- data/lib/reek/sniffer.rb +34 -66
- data/lib/reek.rb +1 -1
- data/reek.gemspec +3 -3
- data/spec/quality/reek_source_spec.rb +15 -0
- data/spec/reek/adapters/report_spec.rb +48 -0
- data/spec/reek/{should_reek_of_spec.rb → adapters/should_reek_of_spec.rb} +14 -11
- data/spec/reek/{should_reek_only_of_spec.rb → adapters/should_reek_only_of_spec.rb} +6 -4
- data/spec/reek/{should_reek_spec.rb → adapters/should_reek_spec.rb} +13 -10
- data/spec/reek/block_context_spec.rb +6 -0
- data/spec/reek/code_parser_spec.rb +6 -1
- data/spec/reek/config_spec.rb +3 -3
- data/spec/reek/smell_warning_spec.rb +2 -1
- data/spec/reek/smells/duplication_spec.rb +1 -1
- data/spec/reek/smells/large_class_spec.rb +3 -2
- data/spec/reek/smells/long_method_spec.rb +4 -3
- data/spec/reek/smells/long_parameter_list_spec.rb +0 -2
- data/spec/reek/smells/smell_detector_spec.rb +2 -16
- data/spec/reek/smells/uncommunicative_name_spec.rb +1 -2
- data/spec/reek/smells/utility_function_spec.rb +4 -0
- data/spec/samples/not_quite_masked/dirty.rb +8 -0
- data/spec/samples/not_quite_masked/masked.reek +5 -0
- data/spec/spec_helper.rb +1 -1
- data/tasks/reek.rake +2 -2
- data/tasks/test.rake +8 -8
- metadata +18 -20
- data/features/rake_task.feature +0 -9
- data/lib/reek/core_extras.rb +0 -50
- data/lib/reek/options.rb +0 -103
- data/lib/reek/report.rb +0 -115
- data/lib/reek/source.rb +0 -36
- data/spec/reek/options_spec.rb +0 -13
- data/spec/reek/report_spec.rb +0 -49
- data/spec/slow/inline_spec.rb +0 -44
- data/spec/slow/optparse_spec.rb +0 -112
- data/spec/slow/redcloth_spec.rb +0 -105
- data/spec/slow/reek_source_spec.rb +0 -13
data/History.txt
CHANGED
@@ -6,18 +6,22 @@
|
|
6
6
|
** Output now reports on all files examined, even if they have no smells
|
7
7
|
** Smell warnings are indented in the report; file summary headers are not
|
8
8
|
** Reports for multiple sources are run together; no more blank lines
|
9
|
-
** Reports in spec matcher failures are quiet
|
9
|
+
** Reports in spec matcher failures are quiet (fixed #38)
|
10
10
|
* The smells masked by *.reek config files can now be seen:
|
11
11
|
** The header for each source file now counts masked smells
|
12
12
|
** The --show-all (-a) option shows masked warnings in the report
|
13
|
+
* The spec matchers are now accessed by requiring 'reek/adapters/spec'
|
13
14
|
|
14
15
|
=== Minor Changes
|
15
16
|
* Reek's RDoc is now hosted at http://rdoc.info/projects/kevinrutherford/reek
|
17
|
+
* If a dir is passed on the command-line all **/*.rb files below it are examined (fixed #41)
|
16
18
|
* Several changes to the LongMethod counting algorithm:
|
17
19
|
** LongMethod now counts statements deeper into each method (fixed #25)
|
18
20
|
** LongMethod no longer counts control structures, only their contained stmts
|
19
21
|
** See http://wiki.github.com/kevinrutherford/reek/long-method for details
|
20
22
|
* LargeClass is disabled when checking in-memory classes (fixed #28)
|
23
|
+
* UtilityFunction no longer reports methods that call 'super' (fixed #39)
|
24
|
+
* Duplication warnings now report the number of identical calls
|
21
25
|
* Now reports an error for corrupt config files
|
22
26
|
* Empty config files are ignored
|
23
27
|
|
data/bin/reek
CHANGED
@@ -6,21 +6,6 @@
|
|
6
6
|
# Author: Kevin Rutherford
|
7
7
|
#
|
8
8
|
|
9
|
-
require 'reek/
|
9
|
+
require 'reek/adapters/application'
|
10
10
|
|
11
|
-
|
12
|
-
begin
|
13
|
-
sniffer = Reek::Options.parse(args)
|
14
|
-
# SMELL:
|
15
|
-
# This should use the actual type of report selected by the user's options
|
16
|
-
puts sniffer.full_report
|
17
|
-
return sniffer.smelly? ? 2 : 0
|
18
|
-
rescue SystemExit => ex
|
19
|
-
return ex.status
|
20
|
-
rescue Exception => error
|
21
|
-
$stderr.puts "Error: #{error}"
|
22
|
-
return 1
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
exit reek(ARGV)
|
11
|
+
exit Reek::Application.new(ARGV).execute
|
@@ -11,8 +11,8 @@ Feature: Masking smells using config files
|
|
11
11
|
"""
|
12
12
|
spec/samples/empty_config_file/dirty.rb -- 6 warnings:
|
13
13
|
Dirty has the variable name '@s' (Uncommunicative Name)
|
14
|
-
Dirty#a calls @s.title
|
15
|
-
Dirty#a calls puts(@s.title)
|
14
|
+
Dirty#a calls @s.title twice (Duplication)
|
15
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
16
16
|
Dirty#a has the name 'a' (Uncommunicative Name)
|
17
17
|
Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
18
18
|
Dirty#a/block/block is nested (Nested Iterators)
|
@@ -35,8 +35,8 @@ Feature: Masking smells using config files
|
|
35
35
|
And it reports:
|
36
36
|
"""
|
37
37
|
spec/samples/masked/dirty.rb -- 3 warnings (+3 masked):
|
38
|
-
Dirty#a calls @s.title
|
39
|
-
Dirty#a calls puts(@s.title)
|
38
|
+
Dirty#a calls @s.title twice (Duplication)
|
39
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
40
40
|
Dirty#a/block/block is nested (Nested Iterators)
|
41
41
|
|
42
42
|
"""
|
@@ -48,8 +48,8 @@ Feature: Masking smells using config files
|
|
48
48
|
"""
|
49
49
|
spec/samples/masked/dirty.rb -- 3 warnings (+3 masked):
|
50
50
|
(masked) Dirty has the variable name '@s' (Uncommunicative Name)
|
51
|
-
Dirty#a calls @s.title
|
52
|
-
Dirty#a calls puts(@s.title)
|
51
|
+
Dirty#a calls @s.title twice (Duplication)
|
52
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
53
53
|
(masked) Dirty#a has the name 'a' (Uncommunicative Name)
|
54
54
|
(masked) Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
55
55
|
Dirty#a/block/block is nested (Nested Iterators)
|
@@ -62,8 +62,22 @@ Feature: Masking smells using config files
|
|
62
62
|
And it reports:
|
63
63
|
"""
|
64
64
|
spec/samples/masked/dirty.rb -- 3 warnings (+3 masked):
|
65
|
-
Dirty#a calls @s.title
|
66
|
-
Dirty#a calls puts(@s.title)
|
65
|
+
Dirty#a calls @s.title twice (Duplication)
|
66
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
67
|
+
Dirty#a/block/block is nested (Nested Iterators)
|
68
|
+
|
69
|
+
"""
|
70
|
+
|
71
|
+
Scenario: non-masked smells are only counted once
|
72
|
+
When I run reek spec/samples/not_quite_masked/dirty.rb
|
73
|
+
Then it fails with exit status 2
|
74
|
+
And it reports:
|
75
|
+
"""
|
76
|
+
spec/samples/not_quite_masked/dirty.rb -- 5 warnings (+1 masked):
|
77
|
+
Dirty has the variable name '@s' (Uncommunicative Name)
|
78
|
+
Dirty#a calls @s.title twice (Duplication)
|
79
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
80
|
+
Dirty#a has the name 'a' (Uncommunicative Name)
|
67
81
|
Dirty#a/block/block is nested (Nested Iterators)
|
68
82
|
|
69
83
|
"""
|
data/features/options.feature
CHANGED
@@ -24,19 +24,26 @@ Feature: Reek can be controlled using command-line options
|
|
24
24
|
Then it succeeds
|
25
25
|
And it reports:
|
26
26
|
"""
|
27
|
-
Usage: reek [options] files
|
27
|
+
Usage: reek [options] [files]
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
|
31
|
+
reek lib/*.rb
|
32
|
+
reek -q -a lib
|
33
|
+
cat my_class.rb | reek
|
28
34
|
|
29
|
-
If no files are given, Reek reads source code from standard input.
|
30
35
|
See http://wiki.github.com/kevinrutherford/reek for detailed help.
|
31
36
|
|
37
|
+
Common options:
|
38
|
+
-h, --help Show this message
|
39
|
+
-v, --version Show version
|
32
40
|
|
33
|
-
|
41
|
+
|
42
|
+
Report formatting:
|
34
43
|
-a, --[no-]show-all Show all smells, including those masked by config settings
|
35
44
|
-q, --quiet Suppress headings for smell-free source files
|
36
|
-
-h, --help Show this message
|
37
45
|
-f, --format FORMAT Specify the format of smell warnings
|
38
46
|
-c, --context-first Sort by context; sets the format string to "%m%c %w (%s)"
|
39
47
|
-s, --smell-first Sort by smell; sets the format string to "%m[%s] %c %w"
|
40
|
-
-v, --version Show version
|
41
48
|
|
42
49
|
"""
|
data/features/reports.feature
CHANGED
@@ -4,30 +4,35 @@ Feature: Correctly formatted reports
|
|
4
4
|
As a developer
|
5
5
|
I want to be able to parse reek's output simply and consistently
|
6
6
|
|
7
|
-
Scenario: two reports run together with indented smells
|
8
|
-
When I run reek
|
7
|
+
Scenario Outline: two reports run together with indented smells
|
8
|
+
When I run reek <args>
|
9
9
|
Then it fails with exit status 2
|
10
10
|
And it reports:
|
11
11
|
"""
|
12
12
|
spec/samples/two_smelly_files/dirty_one.rb -- 6 warnings:
|
13
13
|
Dirty has the variable name '@s' (Uncommunicative Name)
|
14
|
-
Dirty#a calls @s.title
|
15
|
-
Dirty#a calls puts(@s.title)
|
14
|
+
Dirty#a calls @s.title twice (Duplication)
|
15
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
16
16
|
Dirty#a has the name 'a' (Uncommunicative Name)
|
17
17
|
Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
18
18
|
Dirty#a/block/block is nested (Nested Iterators)
|
19
19
|
spec/samples/two_smelly_files/dirty_two.rb -- 6 warnings:
|
20
20
|
Dirty has the variable name '@s' (Uncommunicative Name)
|
21
|
-
Dirty#a calls @s.title
|
22
|
-
Dirty#a calls puts(@s.title)
|
21
|
+
Dirty#a calls @s.title twice (Duplication)
|
22
|
+
Dirty#a calls puts(@s.title) twice (Duplication)
|
23
23
|
Dirty#a has the name 'a' (Uncommunicative Name)
|
24
24
|
Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
25
25
|
Dirty#a/block/block is nested (Nested Iterators)
|
26
26
|
|
27
27
|
"""
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
Examples:
|
30
|
+
| args |
|
31
|
+
| spec/samples/two_smelly_files/*.rb |
|
32
|
+
| spec/samples/two_smelly_files |
|
33
|
+
|
34
|
+
Scenario Outline: good files show headers consecutively
|
35
|
+
When I run reek <args>
|
31
36
|
Then it succeeds
|
32
37
|
And it reports:
|
33
38
|
"""
|
@@ -37,6 +42,11 @@ Feature: Correctly formatted reports
|
|
37
42
|
|
38
43
|
"""
|
39
44
|
|
45
|
+
Examples:
|
46
|
+
| args |
|
47
|
+
| spec/samples/three_clean_files/*.rb |
|
48
|
+
| spec/samples/three_clean_files |
|
49
|
+
|
40
50
|
Scenario Outline: --quiet turns off headers for fragrant files
|
41
51
|
When I run reek <option> spec/samples/three_clean_files/*.rb
|
42
52
|
Then it succeeds
|
@@ -59,15 +69,15 @@ Feature: Correctly formatted reports
|
|
59
69
|
"""
|
60
70
|
spec/samples/clean_due_to_masking/dirty_one.rb -- 0 warnings (+6 masked):
|
61
71
|
(masked) Dirty has the variable name '@s' (Uncommunicative Name)
|
62
|
-
(masked) Dirty#a calls @s.title
|
63
|
-
(masked) Dirty#a calls puts(@s.title)
|
72
|
+
(masked) Dirty#a calls @s.title twice (Duplication)
|
73
|
+
(masked) Dirty#a calls puts(@s.title) twice (Duplication)
|
64
74
|
(masked) Dirty#a has the name 'a' (Uncommunicative Name)
|
65
75
|
(masked) Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
66
76
|
(masked) Dirty#a/block/block is nested (Nested Iterators)
|
67
77
|
spec/samples/clean_due_to_masking/dirty_two.rb -- 0 warnings (+6 masked):
|
68
78
|
(masked) Dirty has the variable name '@s' (Uncommunicative Name)
|
69
|
-
(masked) Dirty#a calls @s.title
|
70
|
-
(masked) Dirty#a calls puts(@s.title)
|
79
|
+
(masked) Dirty#a calls @s.title twice (Duplication)
|
80
|
+
(masked) Dirty#a calls puts(@s.title) twice (Duplication)
|
71
81
|
(masked) Dirty#a has the name 'a' (Uncommunicative Name)
|
72
82
|
(masked) Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
73
83
|
(masked) Dirty#a/block/block is nested (Nested Iterators)
|
data/features/samples.feature
CHANGED
@@ -11,25 +11,25 @@ Feature: Basic smell detection
|
|
11
11
|
"""
|
12
12
|
spec/samples/inline.rb -- 32 warnings:
|
13
13
|
Inline::C has at least 13 instance variables (Large Class)
|
14
|
-
Inline::C#build calls ($? == 0)
|
15
|
-
Inline::C#build calls Inline.directory
|
16
|
-
Inline::C#build calls io.puts
|
17
|
-
Inline::C#build calls io.puts("#endif")
|
18
|
-
Inline::C#build calls io.puts("#ifdef __cplusplus")
|
19
|
-
Inline::C#build calls module_name
|
20
|
-
Inline::C#build calls warn("Output:\n#{result}")
|
14
|
+
Inline::C#build calls ($? == 0) twice (Duplication)
|
15
|
+
Inline::C#build calls Inline.directory 5 times (Duplication)
|
16
|
+
Inline::C#build calls io.puts 6 times (Duplication)
|
17
|
+
Inline::C#build calls io.puts("#endif") twice (Duplication)
|
18
|
+
Inline::C#build calls io.puts("#ifdef __cplusplus") twice (Duplication)
|
19
|
+
Inline::C#build calls module_name twice (Duplication)
|
20
|
+
Inline::C#build calls warn("Output:\n#{result}") twice (Duplication)
|
21
21
|
Inline::C#build has approx 60 statements (Long Method)
|
22
22
|
Inline::C#build has the variable name 't' (Uncommunicative Name)
|
23
23
|
Inline::C#build/block/block has the variable name 'n' (Uncommunicative Name)
|
24
24
|
Inline::C#build/block/block is nested (Nested Iterators)
|
25
25
|
Inline::C#c has the name 'c' (Uncommunicative Name)
|
26
|
-
Inline::C#crap_for_windoze calls Config::CONFIG["libdir"]
|
27
|
-
Inline::C#generate calls result.sub!(/\A\n/, "")
|
28
|
-
Inline::C#generate calls signature["args"]
|
29
|
-
Inline::C#generate calls signature["args"].map
|
26
|
+
Inline::C#crap_for_windoze calls Config::CONFIG["libdir"] twice (Duplication)
|
27
|
+
Inline::C#generate calls result.sub!(/\A\n/, "") twice (Duplication)
|
28
|
+
Inline::C#generate calls signature["args"] twice (Duplication)
|
29
|
+
Inline::C#generate calls signature["args"].map twice (Duplication)
|
30
30
|
Inline::C#generate has approx 32 statements (Long Method)
|
31
|
-
Inline::C#initialize calls stack.empty?
|
32
|
-
Inline::C#load calls so_name
|
31
|
+
Inline::C#initialize calls stack.empty? twice (Duplication)
|
32
|
+
Inline::C#load calls so_name twice (Duplication)
|
33
33
|
Inline::C#module_name/block has the variable name 'm' (Uncommunicative Name)
|
34
34
|
Inline::C#module_name/block has the variable name 'x' (Uncommunicative Name)
|
35
35
|
Inline::C#parse_signature has approx 15 statements (Long Method)
|
@@ -37,9 +37,9 @@ Feature: Basic smell detection
|
|
37
37
|
Inline::C#parse_signature/block has the variable name 'x' (Uncommunicative Name)
|
38
38
|
Inline::C#strip_comments doesn't depend on instance state (Utility Function)
|
39
39
|
Inline::C#strip_comments refers to src more than self (Feature Envy)
|
40
|
-
Inline::self.rootdir calls env.nil?
|
40
|
+
Inline::self.rootdir calls env.nil? twice (Duplication)
|
41
41
|
Inline::self.rootdir has approx 8 statements (Long Method)
|
42
|
-
Module#inline calls Inline.const_get(lang)
|
42
|
+
Module#inline calls Inline.const_get(lang) twice (Duplication)
|
43
43
|
Module#inline has approx 11 statements (Long Method)
|
44
44
|
Module#inline is controlled by argument options (Control Couple)
|
45
45
|
|
@@ -53,8 +53,8 @@ Feature: Basic smell detection
|
|
53
53
|
spec/samples/optparse.rb -- 117 warnings:
|
54
54
|
OptionParser has at least 59 methods (Large Class)
|
55
55
|
OptionParser#CompletingHash#match/block/block is nested (Nested Iterators)
|
56
|
-
OptionParser#Completion::complete calls candidates.size
|
57
|
-
OptionParser#Completion::complete calls k.id2name
|
56
|
+
OptionParser#Completion::complete calls candidates.size twice (Duplication)
|
57
|
+
OptionParser#Completion::complete calls k.id2name twice (Duplication)
|
58
58
|
OptionParser#Completion::complete has approx 22 statements (Long Method)
|
59
59
|
OptionParser#Completion::complete has the variable name 'k' (Uncommunicative Name)
|
60
60
|
OptionParser#Completion::complete has the variable name 'v' (Uncommunicative Name)
|
@@ -80,23 +80,23 @@ Feature: Basic smell detection
|
|
80
80
|
OptionParser#Switch#PlacedArgument#parse has approx 6 statements (Long Method)
|
81
81
|
OptionParser#Switch#RequiredArgument#parse is controlled by argument arg (Control Couple)
|
82
82
|
OptionParser#Switch#add_banner has the variable name 's' (Uncommunicative Name)
|
83
|
-
OptionParser#Switch#conv_arg calls conv
|
83
|
+
OptionParser#Switch#conv_arg calls conv twice (Duplication)
|
84
84
|
OptionParser#Switch#initialize has 7 parameters (Long Parameter List)
|
85
|
-
OptionParser#Switch#parse_arg calls pattern
|
86
|
-
OptionParser#Switch#parse_arg calls s.length
|
85
|
+
OptionParser#Switch#parse_arg calls pattern twice (Duplication)
|
86
|
+
OptionParser#Switch#parse_arg calls s.length twice (Duplication)
|
87
87
|
OptionParser#Switch#parse_arg has approx 11 statements (Long Method)
|
88
88
|
OptionParser#Switch#parse_arg has the variable name 'm' (Uncommunicative Name)
|
89
89
|
OptionParser#Switch#parse_arg has the variable name 's' (Uncommunicative Name)
|
90
90
|
OptionParser#Switch#self.guess has the variable name 't' (Uncommunicative Name)
|
91
91
|
OptionParser#Switch#self.incompatible_argument_styles has the variable name 't' (Uncommunicative Name)
|
92
|
-
OptionParser#Switch#summarize calls (indent + l)
|
93
|
-
OptionParser#Switch#summarize calls arg
|
94
|
-
OptionParser#Switch#summarize calls left.collect
|
95
|
-
OptionParser#Switch#summarize calls left.collect { |s| s.length }.max
|
96
|
-
OptionParser#Switch#summarize calls left.collect { |s| s.length }.max.to_i
|
97
|
-
OptionParser#Switch#summarize calls left.shift
|
98
|
-
OptionParser#Switch#summarize calls left[-1]
|
99
|
-
OptionParser#Switch#summarize calls s.length
|
92
|
+
OptionParser#Switch#summarize calls (indent + l) twice (Duplication)
|
93
|
+
OptionParser#Switch#summarize calls arg 4 times (Duplication)
|
94
|
+
OptionParser#Switch#summarize calls left.collect twice (Duplication)
|
95
|
+
OptionParser#Switch#summarize calls left.collect { |s| s.length }.max twice (Duplication)
|
96
|
+
OptionParser#Switch#summarize calls left.collect { |s| s.length }.max.to_i twice (Duplication)
|
97
|
+
OptionParser#Switch#summarize calls left.shift twice (Duplication)
|
98
|
+
OptionParser#Switch#summarize calls left[-1] 3 times (Duplication)
|
99
|
+
OptionParser#Switch#summarize calls s.length 3 times (Duplication)
|
100
100
|
OptionParser#Switch#summarize has 5 parameters (Long Parameter List)
|
101
101
|
OptionParser#Switch#summarize has approx 25 statements (Long Method)
|
102
102
|
OptionParser#Switch#summarize has the variable name 'l' (Uncommunicative Name)
|
@@ -117,21 +117,21 @@ Feature: Basic smell detection
|
|
117
117
|
OptionParser#block/block is nested (Nested Iterators)
|
118
118
|
OptionParser#complete has 4 parameters (Long Parameter List)
|
119
119
|
OptionParser#complete/block/block is nested (Nested Iterators)
|
120
|
-
OptionParser#getopts calls result[opt] = false
|
120
|
+
OptionParser#getopts calls result[opt] = false twice (Duplication)
|
121
121
|
OptionParser#getopts has approx 17 statements (Long Method)
|
122
122
|
OptionParser#getopts/block is controlled by argument val (Control Couple)
|
123
123
|
OptionParser#load/block has the variable name 's' (Uncommunicative Name)
|
124
|
-
OptionParser#make_switch calls (long << o = q.downcase)
|
125
|
-
OptionParser#make_switch calls (sdesc << "-#{q}")
|
126
|
-
OptionParser#make_switch calls default_style.guess(arg = a)
|
127
|
-
OptionParser#make_switch calls notwice(NilClass, klass, "type")
|
128
|
-
OptionParser#make_switch calls notwice(a ? (Object) : (TrueClass), klass, "type")
|
129
|
-
OptionParser#make_switch calls pattern.method(:convert)
|
130
|
-
OptionParser#make_switch calls pattern.method(:convert).to_proc
|
131
|
-
OptionParser#make_switch calls pattern.respond_to?(:convert)
|
132
|
-
OptionParser#make_switch calls q.downcase
|
133
|
-
OptionParser#make_switch calls search(:atype, FalseClass)
|
134
|
-
OptionParser#make_switch calls search(:atype, o)
|
124
|
+
OptionParser#make_switch calls (long << o = q.downcase) twice (Duplication)
|
125
|
+
OptionParser#make_switch calls (sdesc << "-#{q}") twice (Duplication)
|
126
|
+
OptionParser#make_switch calls default_style.guess(arg = a) 4 times (Duplication)
|
127
|
+
OptionParser#make_switch calls notwice(NilClass, klass, "type") twice (Duplication)
|
128
|
+
OptionParser#make_switch calls notwice(a ? (Object) : (TrueClass), klass, "type") twice (Duplication)
|
129
|
+
OptionParser#make_switch calls pattern.method(:convert) twice (Duplication)
|
130
|
+
OptionParser#make_switch calls pattern.method(:convert).to_proc twice (Duplication)
|
131
|
+
OptionParser#make_switch calls pattern.respond_to?(:convert) twice (Duplication)
|
132
|
+
OptionParser#make_switch calls q.downcase 3 times (Duplication)
|
133
|
+
OptionParser#make_switch calls search(:atype, FalseClass) twice (Duplication)
|
134
|
+
OptionParser#make_switch calls search(:atype, o) 6 times (Duplication)
|
135
135
|
OptionParser#make_switch has approx 68 statements (Long Method)
|
136
136
|
OptionParser#make_switch has the variable name 'a' (Uncommunicative Name)
|
137
137
|
OptionParser#make_switch has the variable name 'n' (Uncommunicative Name)
|
@@ -146,22 +146,22 @@ Feature: Basic smell detection
|
|
146
146
|
OptionParser#make_switch/block/block has the variable name 'v' (Uncommunicative Name)
|
147
147
|
OptionParser#make_switch/block/block is nested (Nested Iterators)
|
148
148
|
OptionParser#make_switch/block/block/block is nested (Nested Iterators)
|
149
|
-
OptionParser#order calls argv[0]
|
149
|
+
OptionParser#order calls argv[0] twice (Duplication)
|
150
150
|
OptionParser#order refers to argv more than self (Feature Envy)
|
151
|
-
OptionParser#parse calls argv[0]
|
151
|
+
OptionParser#parse calls argv[0] twice (Duplication)
|
152
152
|
OptionParser#parse refers to argv more than self (Feature Envy)
|
153
|
-
OptionParser#parse_in_order calls $!.set_option(arg, true)
|
154
|
-
OptionParser#parse_in_order calls cb.call(val)
|
155
|
-
OptionParser#parse_in_order calls raise($!.set_option(arg, true))
|
156
|
-
OptionParser#parse_in_order calls raise(*exc)
|
157
|
-
OptionParser#parse_in_order calls setter.call(sw.switch_name, val)
|
158
|
-
OptionParser#parse_in_order calls sw.block
|
159
|
-
OptionParser#parse_in_order calls sw.switch_name
|
153
|
+
OptionParser#parse_in_order calls $!.set_option(arg, true) twice (Duplication)
|
154
|
+
OptionParser#parse_in_order calls cb.call(val) twice (Duplication)
|
155
|
+
OptionParser#parse_in_order calls raise($!.set_option(arg, true)) twice (Duplication)
|
156
|
+
OptionParser#parse_in_order calls raise(*exc) twice (Duplication)
|
157
|
+
OptionParser#parse_in_order calls setter.call(sw.switch_name, val) twice (Duplication)
|
158
|
+
OptionParser#parse_in_order calls sw.block twice (Duplication)
|
159
|
+
OptionParser#parse_in_order calls sw.switch_name twice (Duplication)
|
160
160
|
OptionParser#parse_in_order has approx 28 statements (Long Method)
|
161
161
|
OptionParser#parse_in_order/block is controlled by argument setter (Control Couple)
|
162
162
|
OptionParser#parse_in_order/block/block is nested (Nested Iterators)
|
163
163
|
OptionParser#parse_in_order/block/block/block is nested (Nested Iterators)
|
164
|
-
OptionParser#permute calls argv[0]
|
164
|
+
OptionParser#permute calls argv[0] twice (Duplication)
|
165
165
|
OptionParser#permute refers to argv more than self (Feature Envy)
|
166
166
|
OptionParser#search/block has the variable name 'k' (Uncommunicative Name)
|
167
167
|
OptionParser#summarize has 4 parameters (Long Parameter List)
|
@@ -185,12 +185,12 @@ Feature: Basic smell detection
|
|
185
185
|
RedCloth#block_markdown_rule doesn't depend on instance state (Utility Function)
|
186
186
|
RedCloth#block_markdown_rule refers to text more than self (Feature Envy)
|
187
187
|
RedCloth#block_markdown_setext refers to text more than self (Feature Envy)
|
188
|
-
RedCloth#block_textile_lists calls (line_id - 1)
|
189
|
-
RedCloth#block_textile_lists calls depth.last
|
190
|
-
RedCloth#block_textile_lists calls depth.last.length
|
191
|
-
RedCloth#block_textile_lists calls depth[i]
|
192
|
-
RedCloth#block_textile_lists calls lines[(line_id - 1)]
|
193
|
-
RedCloth#block_textile_lists calls tl.length
|
188
|
+
RedCloth#block_textile_lists calls (line_id - 1) twice (Duplication)
|
189
|
+
RedCloth#block_textile_lists calls depth.last 5 times (Duplication)
|
190
|
+
RedCloth#block_textile_lists calls depth.last.length twice (Duplication)
|
191
|
+
RedCloth#block_textile_lists calls depth[i] twice (Duplication)
|
192
|
+
RedCloth#block_textile_lists calls lines[(line_id - 1)] twice (Duplication)
|
193
|
+
RedCloth#block_textile_lists calls tl.length 3 times (Duplication)
|
194
194
|
RedCloth#block_textile_lists has approx 20 statements (Long Method)
|
195
195
|
RedCloth#block_textile_lists refers to depth more than self (Feature Envy)
|
196
196
|
RedCloth#block_textile_lists/block/block is nested (Nested Iterators)
|
@@ -205,7 +205,7 @@ Feature: Basic smell detection
|
|
205
205
|
RedCloth#blocks/block is controlled by argument deep_code (Control Couple)
|
206
206
|
RedCloth#blocks/block/block is nested (Nested Iterators)
|
207
207
|
RedCloth#check_refs is controlled by argument text (Control Couple)
|
208
|
-
RedCloth#clean_html calls tags[tag]
|
208
|
+
RedCloth#clean_html calls tags[tag] twice (Duplication)
|
209
209
|
RedCloth#clean_html doesn't depend on instance state (Utility Function)
|
210
210
|
RedCloth#clean_html has approx 14 statements (Long Method)
|
211
211
|
RedCloth#clean_html refers to raw more than self (Feature Envy)
|
@@ -243,7 +243,7 @@ Feature: Basic smell detection
|
|
243
243
|
RedCloth#inline_textile_span/block/block is nested (Nested Iterators)
|
244
244
|
RedCloth#no_textile doesn't depend on instance state (Utility Function)
|
245
245
|
RedCloth#no_textile refers to text more than self (Feature Envy)
|
246
|
-
RedCloth#pba calls $1.length
|
246
|
+
RedCloth#pba calls $1.length twice (Duplication)
|
247
247
|
RedCloth#pba has approx 21 statements (Long Method)
|
248
248
|
RedCloth#pba is controlled by argument text_in (Control Couple)
|
249
249
|
RedCloth#pba refers to style more than self (Feature Envy)
|
@@ -252,14 +252,14 @@ Feature: Basic smell detection
|
|
252
252
|
RedCloth#refs_textile/block has the variable name 'm' (Uncommunicative Name)
|
253
253
|
RedCloth#retrieve/block has the variable name 'i' (Uncommunicative Name)
|
254
254
|
RedCloth#retrieve/block has the variable name 'r' (Uncommunicative Name)
|
255
|
-
RedCloth#rip_offtags calls ((codepre - used_offtags.length) > 0)
|
256
|
-
RedCloth#rip_offtags calls (@pre_list.last << line)
|
257
|
-
RedCloth#rip_offtags calls (codepre - used_offtags.length)
|
258
|
-
RedCloth#rip_offtags calls @pre_list.last
|
259
|
-
RedCloth#rip_offtags calls codepre.zero?
|
260
|
-
RedCloth#rip_offtags calls htmlesc(line, :NoQuotes)
|
261
|
-
RedCloth#rip_offtags calls used_offtags.length
|
262
|
-
RedCloth#rip_offtags calls used_offtags["notextile"]
|
255
|
+
RedCloth#rip_offtags calls ((codepre - used_offtags.length) > 0) twice (Duplication)
|
256
|
+
RedCloth#rip_offtags calls (@pre_list.last << line) twice (Duplication)
|
257
|
+
RedCloth#rip_offtags calls (codepre - used_offtags.length) twice (Duplication)
|
258
|
+
RedCloth#rip_offtags calls @pre_list.last twice (Duplication)
|
259
|
+
RedCloth#rip_offtags calls codepre.zero? twice (Duplication)
|
260
|
+
RedCloth#rip_offtags calls htmlesc(line, :NoQuotes) twice (Duplication)
|
261
|
+
RedCloth#rip_offtags calls used_offtags.length twice (Duplication)
|
262
|
+
RedCloth#rip_offtags calls used_offtags["notextile"] 3 times (Duplication)
|
263
263
|
RedCloth#rip_offtags has approx 18 statements (Long Method)
|
264
264
|
RedCloth#textile_bq has 4 parameters (Long Parameter List)
|
265
265
|
RedCloth#textile_bq is controlled by argument atts (Control Couple)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'reek/command_line'
|
2
|
+
require 'reek/adapters/source'
|
3
|
+
require 'reek/adapters/core_extras'
|
4
|
+
require 'reek/adapters/report'
|
5
|
+
|
6
|
+
module Reek
|
7
|
+
#
|
8
|
+
# Represents an instance of a Reek application.
|
9
|
+
# This is the entry point for all invocations of Reek from the
|
10
|
+
# command line.
|
11
|
+
#
|
12
|
+
class Application
|
13
|
+
def initialize(argv)
|
14
|
+
@argv = argv
|
15
|
+
end
|
16
|
+
|
17
|
+
def examine_sources
|
18
|
+
# SMELL: Greedy Method
|
19
|
+
# Options.parse executes the -v and -h commands and throws a SystemExit
|
20
|
+
args = Options.new(@argv).parse
|
21
|
+
if args.length > 0
|
22
|
+
@sniffer = args.sniff
|
23
|
+
else
|
24
|
+
@sniffer = Reek::Sniffer.new($stdin.to_reek_source('$stdin'))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def reek
|
29
|
+
examine_sources
|
30
|
+
# SMELL:
|
31
|
+
# This should use the actual type of report selected by the user's options
|
32
|
+
puts Report.new(@sniffer.sniffers).full_report
|
33
|
+
return @sniffer.smelly? ? 2 : 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def execute
|
37
|
+
begin
|
38
|
+
return reek
|
39
|
+
rescue SystemExit => ex
|
40
|
+
return ex.status
|
41
|
+
rescue Exception => error
|
42
|
+
$stderr.puts "Error: #{error}"
|
43
|
+
return 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
File without changes
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'reek/adapters/source'
|
2
|
+
require 'reek/sniffer'
|
3
|
+
|
4
|
+
class Object
|
5
|
+
#
|
6
|
+
# Creates a new +Sniffer+ that assumes this object contains Ruby source
|
7
|
+
# code and examines that code for smells. Calls +to_reek_source+ on self
|
8
|
+
# to obtain the +Source+ object wrapper.
|
9
|
+
#
|
10
|
+
def sniff
|
11
|
+
Reek::Sniffer.new(self.to_reek_source)
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Constructs a Sniffer which examines this object for code smells.
|
16
|
+
# (This feature is only enabled if you have the ParseTree gem installed.)
|
17
|
+
#
|
18
|
+
def to_reek_source
|
19
|
+
ObjectSource.new(self, self.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class File
|
24
|
+
#
|
25
|
+
# Creates a new +Source+ that assumes this File contains Ruby source
|
26
|
+
# code and prepares it to be examined for code smells.
|
27
|
+
#
|
28
|
+
def to_reek_source
|
29
|
+
Reek::SourceFile.new(self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class IO
|
34
|
+
#
|
35
|
+
# Creates a new +Source+ that assumes this IO stream contains Ruby source
|
36
|
+
# code and prepares it to be examined for code smells.
|
37
|
+
#
|
38
|
+
def to_reek_source(description = 'io')
|
39
|
+
Reek::Source.new(self.readlines.join, description)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class String
|
44
|
+
#
|
45
|
+
# Creates a new +Source+ that assumes this string contains Ruby source
|
46
|
+
# code and prepares it to be examined for code smells.
|
47
|
+
#
|
48
|
+
def to_reek_source
|
49
|
+
Reek::Source.new(self, 'string')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Array
|
54
|
+
def paths
|
55
|
+
self.map do |path|
|
56
|
+
if test 'd', path
|
57
|
+
Dir["#{path}/**/*.rb"].paths
|
58
|
+
else
|
59
|
+
path
|
60
|
+
end
|
61
|
+
end.flatten.sort
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Creates a new +Sniffer+ that assumes this Array contains the names
|
66
|
+
# of Ruby source files and examines those files for smells.
|
67
|
+
#
|
68
|
+
def sniff
|
69
|
+
sniffers = paths.map {|path| File.new(path).sniff}
|
70
|
+
Reek::SnifferSet.new(sniffers, 'dir')
|
71
|
+
end
|
72
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'reek/adapters/source'
|
2
|
+
|
1
3
|
module Reek
|
2
4
|
class ObjectSource < Source # :nodoc:
|
3
5
|
|
@@ -9,9 +11,10 @@ module Reek
|
|
9
11
|
return unifier.process(sexp[0])
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
14
|
+
def configure(sniffer)
|
13
15
|
super
|
14
|
-
|
16
|
+
disabled_config = {Reek::Smells::SmellDetector::ENABLED_KEY => false}
|
17
|
+
sniffer.configure(LargeClass, disabled_config)
|
15
18
|
end
|
16
19
|
|
17
20
|
def can_parse_objects?
|
@@ -39,9 +42,7 @@ class Object
|
|
39
42
|
# Constructs a Sniffer which examines this object for code smells.
|
40
43
|
# (This feature is only enabled if you have the ParseTree gem installed.)
|
41
44
|
#
|
42
|
-
def
|
43
|
-
|
44
|
-
ObjectSource.new(self, self.to_s, result)
|
45
|
-
result
|
45
|
+
def to_reek_source
|
46
|
+
ObjectSource.new(self, self.to_s)
|
46
47
|
end
|
47
48
|
end
|
@@ -59,7 +59,7 @@ module Reek
|
|
59
59
|
# Defines a new task, using the name +name+.
|
60
60
|
def initialize(name = :reek)
|
61
61
|
@name = name
|
62
|
-
@libs = [File.expand_path(File.dirname(__FILE__) + '
|
62
|
+
@libs = [File.expand_path(File.dirname(__FILE__) + '/../../../lib')]
|
63
63
|
@source_files = nil
|
64
64
|
@ruby_opts = []
|
65
65
|
@reek_opts = ''
|
@@ -87,7 +87,7 @@ private
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def self.reek_script
|
90
|
-
File.expand_path(File.dirname(__FILE__) + '
|
90
|
+
File.expand_path(File.dirname(__FILE__) + '/../../../bin/reek')
|
91
91
|
end
|
92
92
|
|
93
93
|
def self.ruby_exe
|