reek 1.3.6 → 1.3.7

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +6 -0
  3. data/README.md +11 -1
  4. data/config/defaults.reek +1 -0
  5. data/features/command_line_interface/options.feature +1 -0
  6. data/features/rake_task/rake_task.feature +3 -0
  7. data/features/ruby_api/api.feature +1 -3
  8. data/features/samples.feature +27 -20
  9. data/features/support/env.rb +2 -2
  10. data/lib/reek/cli/application.rb +0 -4
  11. data/lib/reek/cli/command_line.rb +10 -12
  12. data/lib/reek/cli/reek_command.rb +1 -1
  13. data/lib/reek/cli/report.rb +36 -8
  14. data/lib/reek/config_file_exception.rb +3 -0
  15. data/lib/reek/core/code_context.rb +18 -8
  16. data/lib/reek/core/code_parser.rb +65 -61
  17. data/lib/reek/core/method_context.rb +4 -0
  18. data/lib/reek/core/module_context.rb +2 -2
  19. data/lib/reek/core/smell_repository.rb +3 -0
  20. data/lib/reek/core/sniffer.rb +0 -1
  21. data/lib/reek/core/stop_context.rb +1 -1
  22. data/lib/reek/smells/attribute.rb +1 -1
  23. data/lib/reek/smells/control_parameter.rb +79 -45
  24. data/lib/reek/smells/data_clump.rb +1 -1
  25. data/lib/reek/smells/duplicate_method_call.rb +1 -1
  26. data/lib/reek/smells/long_parameter_list.rb +1 -1
  27. data/lib/reek/smells/long_yield_list.rb +1 -1
  28. data/lib/reek/smells/nested_iterators.rb +1 -1
  29. data/lib/reek/smells/nil_check.rb +10 -5
  30. data/lib/reek/smells/repeated_conditional.rb +1 -1
  31. data/lib/reek/smells/smell_detector.rb +2 -3
  32. data/lib/reek/smells/too_many_instance_variables.rb +1 -1
  33. data/lib/reek/smells/too_many_methods.rb +1 -1
  34. data/lib/reek/smells/too_many_statements.rb +1 -1
  35. data/lib/reek/smells/uncommunicative_method_name.rb +4 -4
  36. data/lib/reek/smells/uncommunicative_module_name.rb +4 -4
  37. data/lib/reek/smells/uncommunicative_parameter_name.rb +9 -9
  38. data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
  39. data/lib/reek/smells/unused_parameters.rb +2 -6
  40. data/lib/reek/smells/utility_function.rb +1 -1
  41. data/lib/reek/source/code_comment.rb +1 -1
  42. data/lib/reek/source/config_file.rb +9 -8
  43. data/lib/reek/source/sexp_extensions.rb +2 -2
  44. data/lib/reek/source/sexp_node.rb +8 -5
  45. data/lib/reek/source/source_repository.rb +5 -0
  46. data/lib/reek/version.rb +1 -1
  47. data/reek.gemspec +3 -2
  48. data/spec/reek/cli/report_spec.rb +38 -8
  49. data/spec/reek/core/code_context_spec.rb +35 -3
  50. data/spec/reek/core/module_context_spec.rb +1 -1
  51. data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
  52. data/spec/reek/smells/smell_detector_shared.rb +1 -2
  53. data/spec/reek/smells/too_many_statements_spec.rb +39 -25
  54. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +44 -30
  55. data/spec/reek/smells/unused_parameters_spec.rb +15 -11
  56. data/spec/reek/source/sexp_extensions_spec.rb +2 -2
  57. data/spec/reek/source/sexp_node_spec.rb +0 -1
  58. data/spec/samples/ruby20_syntax.rb +1 -5
  59. metadata +172 -162
  60. data/lib/reek/cli/yaml_command.rb +0 -32
  61. data/lib/reek/core/hash_extensions.rb +0 -29
  62. data/spec/reek/cli/yaml_command_spec.rb +0 -47
  63. data/spec/reek/core/config_spec.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd6196b99429388642049ac970d159ca81066a08
4
- data.tar.gz: 45ec008b56f8a42ca8edeaa9951ecc8b03fd5d7c
3
+ metadata.gz: a655ae03def5604c059ac663e271eecc1a18d461
4
+ data.tar.gz: 6f6c21e7d712a339e649ad91eabefea90c5a6d13
5
5
  SHA512:
6
- metadata.gz: a09c19c44892cd6d2b8cc82b0fa82c8563fbed0c8734b8f12dfbb5906c223b664ab15e95cdeea8d2270004e06a182968d161bd644a044b157236e69141b8be80
7
- data.tar.gz: a6ff074ebe7abd1a2029ffd6a3f04571ee75beb5709cef297a221bc37b3427fa84c5d53de767ccecf2f248e70a0cdf75fb8e363eb776ddec0b0aa9f1d2018c93
6
+ metadata.gz: 637e3a7af79aee3dd3d7e107d9de35ab2bac39b90f015b58ae8b21cd852a12613a7085d5217eb701ef0b78baa2f517566d21906006eba841dcc77e722ff6d171
7
+ data.tar.gz: 1f6f1923e86614fcb73d77e6a36e3c4f977db3bba059b785904042f27fa8fe7fecc5f568128597c432ee5ca42ea7b9c3ce5039b256f13bd87f46228136438d3d
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ == 1.3.7
2
+
3
+ * (gilles-leblanc) Add color to reek's output
4
+ * (mvz) Ignore unused parameters if method calls super in nested context
5
+ * (mvz) Only mark parameters uncommunicative if used
6
+
1
7
  == 1.3.6
2
8
 
3
9
  * (troessner) Add `Prima Donna Method` smell
data/README.md CHANGED
@@ -1,9 +1,16 @@
1
1
  # Reek -- code smell detection for Ruby
2
2
 
3
- ##Overview
3
+
4
+ ### Overview
5
+
4
6
 
5
7
  [![Build Status](https://secure.travis-ci.org/troessner/reek.png?branch=master)](http://travis-ci.org/troessner/reek?branch=master)
6
8
  [![Gem Version](https://badge.fury.io/rb/reek.png)](http://badge.fury.io/rb/reek)
9
+ [![Dependency Status](https://gemnasium.com/troessner/reek.png)](https://gemnasium.com/troessner/reek)
10
+ [![Inline docs](http://inch-pages.github.io/github/troessner/reek.png)](http://inch-pages.github.io/github/troessner/reek)
11
+
12
+
13
+ ### Synopsis
7
14
 
8
15
 
9
16
  Reek is a tool that examines Ruby classes, modules and methods and
@@ -131,6 +138,8 @@ There's a vim plugin for `reek`: [https://github.com/rainerborene/vim-reek](http
131
138
 
132
139
  TextMate Bundle for `reek`: [https://github.com/peeyush1234/reek.tmbundle](https://github.com/peeyush1234/reek.tmbundle)
133
140
 
141
+ Colorful output for `reek`: [Preek](https://github.com/joenas/preek) (also with [Guard::Preek](https://github.com/joenas/guard-preek))
142
+
134
143
  ### Dependencies
135
144
 
136
145
  Reek makes use of the following other gems:
@@ -138,6 +147,7 @@ Reek makes use of the following other gems:
138
147
  * ruby_parser
139
148
  * sexp_processor
140
149
  * ruby2ruby
150
+ * rainbow
141
151
 
142
152
  ### Learn More
143
153
 
data/config/defaults.reek CHANGED
@@ -89,6 +89,7 @@ UncommunicativeParameterName:
89
89
  - !ruby/regexp /^.$/
90
90
  - !ruby/regexp /[0-9]$/
91
91
  - !ruby/regexp /[A-Z]/
92
+ - !ruby/regexp /^_/
92
93
  accept: []
93
94
  UncommunicativeVariableName:
94
95
  enabled: true
@@ -38,6 +38,7 @@ Feature: Reek can be controlled using command-line options
38
38
  -c, --config FILE Read configuration options from FILE
39
39
 
40
40
  Report formatting:
41
+ -o, --[no-]color Use colors for the output (this is the default)
41
42
  -q, --quiet Suppress headings for smell-free source files (this is the default)
42
43
  -V, --no-quiet, --verbose Show headings for smell-free source files
43
44
  -n, --no-line-numbers Suppress line numbers from the output
@@ -8,6 +8,7 @@ Feature: Reek can be driven through its Task
8
8
  """
9
9
  Reek::Rake::Task.new do |t|
10
10
  t.source_files = 'spec/samples/masked/dirty.rb'
11
+ t.reek_opts = '--no-color'
11
12
  end
12
13
  """
13
14
  Then the exit status indicates an error
@@ -24,6 +25,7 @@ Feature: Reek can be driven through its Task
24
25
  """
25
26
  Reek::Rake::Task.new('silky') do |t|
26
27
  t.source_files = 'spec/samples/masked/dirty.rb'
28
+ t.reek_opts = '--no-color'
27
29
  end
28
30
  """
29
31
  Then the exit status indicates an error
@@ -52,6 +54,7 @@ Feature: Reek can be driven through its Task
52
54
  Reek::Rake::Task.new do |t|
53
55
  t.fail_on_error = false
54
56
  t.source_files = 'spec/samples/no_config_file/dirty.rb'
57
+ t.reek_opts = '--no-color'
55
58
  end
56
59
  """
57
60
  Then it reports no errors
@@ -9,12 +9,10 @@ Feature: The Reek API maintains backwards compatibility
9
9
  Then the exit status indicates smells
10
10
  And it reports:
11
11
  """
12
- spec/samples/demo/demo.rb -- 10 warnings:
12
+ spec/samples/demo/demo.rb -- 8 warnings:
13
13
  [1]:Dirty has no descriptive comment (IrresponsibleModule)
14
14
  [3]:Dirty#awful has 4 parameters (LongParameterList)
15
15
  [3]:Dirty#awful has boolean parameter 'log' (BooleanParameter)
16
- [3]:Dirty#awful has the parameter name 'x' (UncommunicativeParameterName)
17
- [3]:Dirty#awful has the parameter name 'y' (UncommunicativeParameterName)
18
16
  [5]:Dirty#awful has the variable name 'w' (UncommunicativeVariableName)
19
17
  [3]:Dirty#awful has unused parameter 'log' (UnusedParameters)
20
18
  [3]:Dirty#awful has unused parameter 'offset' (UnusedParameters)
@@ -10,8 +10,9 @@ Feature: Basic smell detection
10
10
  Then the exit status indicates smells
11
11
  And it reports:
12
12
  """
13
- spec/samples/inline.rb -- 39 warnings:
13
+ spec/samples/inline.rb -- 41 warnings:
14
14
  File has no descriptive comment (IrresponsibleModule)
15
+ File#self.write_with_backup has approx 6 statements (TooManyStatements)
15
16
  Inline declares the class variable @@directory (ClassVariable)
16
17
  Inline declares the class variable @@rootdir (ClassVariable)
17
18
  Inline#self.rootdir calls env.nil? twice (DuplicateMethodCall)
@@ -30,7 +31,7 @@ Feature: Basic smell detection
30
31
  Inline::C#build calls io.puts("#ifdef __cplusplus") twice (DuplicateMethodCall)
31
32
  Inline::C#build calls warn("Output:\n#{result}") twice (DuplicateMethodCall)
32
33
  Inline::C#build contains iterators nested 2 deep (NestedIterators)
33
- Inline::C#build has approx 60 statements (TooManyStatements)
34
+ Inline::C#build has approx 63 statements (TooManyStatements)
34
35
  Inline::C#build has the variable name 'n' (UncommunicativeVariableName)
35
36
  Inline::C#build has the variable name 't' (UncommunicativeVariableName)
36
37
  Inline::C#c has the name 'c' (UncommunicativeMethodName)
@@ -38,18 +39,19 @@ Feature: Basic smell detection
38
39
  Inline::C#generate calls result.sub!(/\A\n/, "") twice (DuplicateMethodCall)
39
40
  Inline::C#generate calls signature["args"] twice (DuplicateMethodCall)
40
41
  Inline::C#generate calls signature["args"].map twice (DuplicateMethodCall)
41
- Inline::C#generate has approx 32 statements (TooManyStatements)
42
+ Inline::C#generate has approx 35 statements (TooManyStatements)
42
43
  Inline::C#initialize calls stack.empty? twice (DuplicateMethodCall)
44
+ Inline::C#module_name has approx 7 statements (TooManyStatements)
43
45
  Inline::C#module_name has the variable name 'm' (UncommunicativeVariableName)
44
46
  Inline::C#module_name has the variable name 'x' (UncommunicativeVariableName)
45
- Inline::C#parse_signature has approx 15 statements (TooManyStatements)
47
+ Inline::C#parse_signature has approx 16 statements (TooManyStatements)
46
48
  Inline::C#parse_signature has boolean parameter 'raw' (BooleanParameter)
47
49
  Inline::C#parse_signature has the variable name 'x' (UncommunicativeVariableName)
48
50
  Inline::C#parse_signature is controlled by argument raw (ControlParameter)
49
51
  Inline::C#strip_comments doesn't depend on instance state (UtilityFunction)
50
52
  Inline::C#strip_comments refers to src more than self (FeatureEnvy)
51
53
  Module#inline calls Inline.const_get(lang) twice (DuplicateMethodCall)
52
- Module#inline has approx 11 statements (TooManyStatements)
54
+ Module#inline has approx 12 statements (TooManyStatements)
53
55
  """
54
56
 
55
57
  Scenario: Correct smells from optparse.rb
@@ -57,7 +59,7 @@ Feature: Basic smell detection
57
59
  Then the exit status indicates smells
58
60
  And it reports:
59
61
  """
60
- spec/samples/optparse.rb -- 103 warnings:
62
+ spec/samples/optparse.rb -- 108 warnings:
61
63
  OptionParser has at least 42 methods (TooManyMethods)
62
64
  OptionParser has the variable name 'f' (UncommunicativeVariableName)
63
65
  OptionParser has the variable name 'k' (UncommunicativeVariableName)
@@ -71,9 +73,11 @@ Feature: Basic smell detection
71
73
  OptionParser tests s at least 7 times (RepeatedConditional)
72
74
  OptionParser#complete contains iterators nested 2 deep (NestedIterators)
73
75
  OptionParser#complete has 4 parameters (LongParameterList)
76
+ OptionParser#complete has approx 6 statements (TooManyStatements)
74
77
  OptionParser#complete has boolean parameter 'icase' (BooleanParameter)
75
78
  OptionParser#getopts calls result[opt] = false twice (DuplicateMethodCall)
76
- OptionParser#getopts has approx 17 statements (TooManyStatements)
79
+ OptionParser#getopts has approx 18 statements (TooManyStatements)
80
+ OptionParser#load has approx 6 statements (TooManyStatements)
77
81
  OptionParser#load has the variable name 's' (UncommunicativeVariableName)
78
82
  OptionParser#make_switch calls (long << (o = q.downcase)) twice (DuplicateMethodCall)
79
83
  OptionParser#make_switch calls (sdesc << "-#{q}") twice (DuplicateMethodCall)
@@ -87,7 +91,7 @@ Feature: Basic smell detection
87
91
  OptionParser#make_switch calls search(:atype, FalseClass) twice (DuplicateMethodCall)
88
92
  OptionParser#make_switch calls search(:atype, o) 6 times (DuplicateMethodCall)
89
93
  OptionParser#make_switch contains iterators nested 3 deep (NestedIterators)
90
- OptionParser#make_switch has approx 68 statements (TooManyStatements)
94
+ OptionParser#make_switch has approx 72 statements (TooManyStatements)
91
95
  OptionParser#make_switch has the variable name 'a' (UncommunicativeVariableName)
92
96
  OptionParser#make_switch has the variable name 'c' (UncommunicativeVariableName)
93
97
  OptionParser#make_switch has the variable name 'n' (UncommunicativeVariableName)
@@ -108,19 +112,21 @@ Feature: Basic smell detection
108
112
  OptionParser#parse_in_order calls sw.block twice (DuplicateMethodCall)
109
113
  OptionParser#parse_in_order calls sw.switch_name twice (DuplicateMethodCall)
110
114
  OptionParser#parse_in_order contains iterators nested 3 deep (NestedIterators)
111
- OptionParser#parse_in_order has approx 28 statements (TooManyStatements)
115
+ OptionParser#parse_in_order has approx 35 statements (TooManyStatements)
112
116
  OptionParser#permute calls argv[0] twice (DuplicateMethodCall)
113
117
  OptionParser#permute refers to argv more than self (FeatureEnvy)
118
+ OptionParser#permute! has approx 6 statements (TooManyStatements)
114
119
  OptionParser#search has the variable name 'k' (UncommunicativeVariableName)
115
120
  OptionParser#self.inc performs a nil-check. (NilCheck)
116
121
  OptionParser#summarize has 4 parameters (LongParameterList)
117
122
  OptionParser#summarize has the variable name 'l' (UncommunicativeVariableName)
118
123
  OptionParser#ver has the variable name 'v' (UncommunicativeVariableName)
124
+ OptionParser::Arguable#options has approx 6 statements (TooManyStatements)
119
125
  OptionParser::Arguable#options= is controlled by argument opt (ControlParameter)
120
126
  OptionParser::CompletingHash#match contains iterators nested 2 deep (NestedIterators)
121
127
  OptionParser::Completion#complete calls candidates.size twice (DuplicateMethodCall)
122
128
  OptionParser::Completion#complete calls k.id2name twice (DuplicateMethodCall)
123
- OptionParser::Completion#complete has approx 22 statements (TooManyStatements)
129
+ OptionParser::Completion#complete has approx 23 statements (TooManyStatements)
124
130
  OptionParser::Completion#complete has boolean parameter 'icase' (BooleanParameter)
125
131
  OptionParser::Completion#complete has the variable name 'k' (UncommunicativeVariableName)
126
132
  OptionParser::Completion#complete has the variable name 'v' (UncommunicativeVariableName)
@@ -134,7 +140,7 @@ Feature: Basic smell detection
134
140
  OptionParser::List#reject has the parameter name 't' (UncommunicativeParameterName)
135
141
  OptionParser::List#summarize refers to opt more than self (FeatureEnvy)
136
142
  OptionParser::List#update has 5 parameters (LongParameterList)
137
- OptionParser::List#update has approx 6 statements (TooManyStatements)
143
+ OptionParser::List#update has approx 10 statements (TooManyStatements)
138
144
  OptionParser::List#update has the variable name 'o' (UncommunicativeVariableName)
139
145
  OptionParser::ParseError#set_option is controlled by argument eq (ControlParameter)
140
146
  OptionParser::Switch#add_banner has the variable name 's' (UncommunicativeVariableName)
@@ -143,6 +149,7 @@ Feature: Basic smell detection
143
149
  OptionParser::Switch#parse_arg has approx 11 statements (TooManyStatements)
144
150
  OptionParser::Switch#parse_arg has the variable name 'm' (UncommunicativeVariableName)
145
151
  OptionParser::Switch#parse_arg has the variable name 's' (UncommunicativeVariableName)
152
+ OptionParser::Switch#self.guess has approx 6 statements (TooManyStatements)
146
153
  OptionParser::Switch#self.guess has the variable name 't' (UncommunicativeVariableName)
147
154
  OptionParser::Switch#self.incompatible_argument_styles has the parameter name 't' (UncommunicativeParameterName)
148
155
  OptionParser::Switch#summarize calls (indent + l) twice (DuplicateMethodCall)
@@ -154,7 +161,7 @@ Feature: Basic smell detection
154
161
  OptionParser::Switch#summarize calls s.length 3 times (DuplicateMethodCall)
155
162
  OptionParser::Switch#summarize contains iterators nested 2 deep (NestedIterators)
156
163
  OptionParser::Switch#summarize has 5 parameters (LongParameterList)
157
- OptionParser::Switch#summarize has approx 25 statements (TooManyStatements)
164
+ OptionParser::Switch#summarize has approx 28 statements (TooManyStatements)
158
165
  OptionParser::Switch#summarize has the variable name 'l' (UncommunicativeVariableName)
159
166
  OptionParser::Switch#summarize has the variable name 'r' (UncommunicativeVariableName)
160
167
  OptionParser::Switch#summarize has the variable name 's' (UncommunicativeVariableName)
@@ -189,21 +196,21 @@ Feature: Basic smell detection
189
196
  RedCloth#block_textile_lists calls lines[(line_id - 1)] twice (DuplicateMethodCall)
190
197
  RedCloth#block_textile_lists calls tl.length 3 times (DuplicateMethodCall)
191
198
  RedCloth#block_textile_lists contains iterators nested 3 deep (NestedIterators)
192
- RedCloth#block_textile_lists has approx 20 statements (TooManyStatements)
199
+ RedCloth#block_textile_lists has approx 21 statements (TooManyStatements)
193
200
  RedCloth#block_textile_lists has the variable name 'i' (UncommunicativeVariableName)
194
201
  RedCloth#block_textile_lists has the variable name 'v' (UncommunicativeVariableName)
195
202
  RedCloth#block_textile_lists refers to depth more than self (FeatureEnvy)
196
203
  RedCloth#block_textile_table contains iterators nested 3 deep (NestedIterators)
197
- RedCloth#block_textile_table has approx 18 statements (TooManyStatements)
204
+ RedCloth#block_textile_table has approx 19 statements (TooManyStatements)
198
205
  RedCloth#block_textile_table has the variable name 'x' (UncommunicativeVariableName)
199
206
  RedCloth#blocks contains iterators nested 2 deep (NestedIterators)
200
- RedCloth#blocks has approx 18 statements (TooManyStatements)
207
+ RedCloth#blocks has approx 19 statements (TooManyStatements)
201
208
  RedCloth#blocks has boolean parameter 'deep_code' (BooleanParameter)
202
209
  RedCloth#blocks is controlled by argument deep_code (ControlParameter)
203
210
  RedCloth#clean_html calls tags[tag] twice (DuplicateMethodCall)
204
211
  RedCloth#clean_html contains iterators nested 3 deep (NestedIterators)
205
212
  RedCloth#clean_html doesn't depend on instance state (UtilityFunction)
206
- RedCloth#clean_html has approx 14 statements (TooManyStatements)
213
+ RedCloth#clean_html has approx 15 statements (TooManyStatements)
207
214
  RedCloth#clean_html has the variable name 'q' (UncommunicativeVariableName)
208
215
  RedCloth#clean_html has the variable name 'q2' (UncommunicativeVariableName)
209
216
  RedCloth#clean_html refers to raw more than self (FeatureEnvy)
@@ -233,7 +240,7 @@ Feature: Basic smell detection
233
240
  RedCloth#inline_textile_link has approx 9 statements (TooManyStatements)
234
241
  RedCloth#inline_textile_link has the variable name 'm' (UncommunicativeVariableName)
235
242
  RedCloth#inline_textile_span contains iterators nested 2 deep (NestedIterators)
236
- RedCloth#inline_textile_span has approx 8 statements (TooManyStatements)
243
+ RedCloth#inline_textile_span has approx 9 statements (TooManyStatements)
237
244
  RedCloth#inline_textile_span has the variable name 'm' (UncommunicativeVariableName)
238
245
  RedCloth#lT has the name 'lT' (UncommunicativeMethodName)
239
246
  RedCloth#lT is controlled by argument text (ControlParameter)
@@ -266,15 +273,15 @@ Feature: Basic smell detection
266
273
  RedCloth#textile_p has unused parameter 'cite' (UnusedParameters)
267
274
  RedCloth#textile_popup_help has the parameter name 'windowH' (UncommunicativeParameterName)
268
275
  RedCloth#textile_popup_help has the parameter name 'windowW' (UncommunicativeParameterName)
269
- RedCloth#to_html has approx 24 statements (TooManyStatements)
276
+ RedCloth#to_html has approx 26 statements (TooManyStatements)
270
277
  """
271
278
 
279
+ @ruby20
272
280
  Scenario: Correct smells from a source file with Ruby 2.0 specific syntax
273
281
  When I run reek spec/samples/ruby20_syntax.rb
274
282
  Then the exit status indicates smells
275
283
  And it reports:
276
284
  """
277
- spec/samples/ruby20_syntax.rb -- 2 warnings:
285
+ spec/samples/ruby20_syntax.rb -- 1 warning:
278
286
  [1]:SomeClass has no descriptive comment (IrresponsibleModule)
279
- [2]:SomeClass#method_with_keyword_arguments has unused parameter 'foo' (UnusedParameters)
280
287
  """
@@ -15,11 +15,11 @@ class ReekWorld
15
15
  end
16
16
 
17
17
  def reek(args)
18
- run("ruby -Ilib -rubygems bin/reek #{args}")
18
+ run("ruby -Ilib -rubygems bin/reek --no-color #{args}")
19
19
  end
20
20
 
21
21
  def reek_with_pipe(stdin, args)
22
- run("echo \"#{stdin}\" | ruby -Ilib -rubygems bin/reek #{args}")
22
+ run("echo \"#{stdin}\" | ruby -Ilib -rubygems bin/reek --no-color #{args}")
23
23
  end
24
24
 
25
25
  def rake(name, task_def)
@@ -41,10 +41,6 @@ module Reek
41
41
  def report_smells
42
42
  @status = STATUS_SMELLS
43
43
  end
44
-
45
- def update_status(reporter)
46
- reporter.has_smells? ? report_smells : report_success
47
- end
48
44
  end
49
45
  end
50
46
  end
@@ -1,9 +1,9 @@
1
1
  require 'optparse'
2
+ require 'rainbow'
2
3
  require 'reek/cli/report'
3
4
  require 'reek/cli/reek_command'
4
5
  require 'reek/cli/help_command'
5
6
  require 'reek/cli/version_command'
6
- require 'reek/cli/yaml_command'
7
7
  require 'reek/source'
8
8
 
9
9
  module Reek
@@ -17,9 +17,11 @@ module Reek
17
17
  def initialize(argv)
18
18
  @argv = argv
19
19
  @parser = OptionParser.new
20
+ @colored = true
20
21
  @report_class = QuietReport
21
22
  @warning_formatter = WarningFormatterWithLineNumbers
22
23
  @command_class = ReekCommand
24
+ @format = Report::DefaultFormat
23
25
  @config_files = []
24
26
  @sort_by_issue_count = false
25
27
  set_options
@@ -73,6 +75,9 @@ EOB
73
75
  end
74
76
 
75
77
  @parser.separator "\nReport formatting:"
78
+ @parser.on("-o", "--[no-]color", "Use colors for the output (this is the default)") do |opt|
79
+ @colored = opt
80
+ end
76
81
  @parser.on("-q", "--quiet", "Suppress headings for smell-free source files (this is the default)") do |opt|
77
82
  @report_class = QuietReport
78
83
  end
@@ -92,10 +97,7 @@ EOB
92
97
  @sort_by_issue_count = true
93
98
  end
94
99
  @parser.on("-y", "--yaml", "Report smells in YAML format") do
95
- @command_class = YamlCommand
96
- # SMELL: the args passed to the command should be tested, because it may
97
- # turn out that they are passed too soon, ie. before the files have been
98
- # separated out from the options
100
+ @format = :yaml
99
101
  end
100
102
  end
101
103
 
@@ -106,13 +108,9 @@ EOB
106
108
  elsif @command_class == VersionCommand
107
109
  VersionCommand.new(@parser.program_name)
108
110
  else
109
- sources = get_sources
110
- if @command_class == YamlCommand
111
- YamlCommand.create(sources, @config_files)
112
- else
113
- reporter = @report_class.new(@warning_formatter, ReportFormatter, @sort_by_issue_count)
114
- ReekCommand.create(sources, reporter, @config_files)
115
- end
111
+ Rainbow.enabled = @colored
112
+ reporter = @report_class.new(@warning_formatter, ReportFormatter, @sort_by_issue_count, @format)
113
+ ReekCommand.create(get_sources, reporter, @config_files)
116
114
  end
117
115
  end
118
116
 
@@ -22,7 +22,7 @@ module Reek
22
22
  @sources.each do |source|
23
23
  @reporter.add_examiner(Examiner.new(source, @config_files))
24
24
  end
25
- app.update_status(@reporter)
25
+ @reporter.has_smells? ? app.report_smells : app.report_success
26
26
  @reporter.show
27
27
  end
28
28
  end
@@ -1,3 +1,5 @@
1
+ require 'rainbow'
2
+
1
3
  module Reek
2
4
  module Cli
3
5
  module ReportFormatter
@@ -9,8 +11,8 @@ module Reek
9
11
 
10
12
  def self.header(examiner)
11
13
  count = examiner.smells_count
12
- result = "#{examiner.description} -- #{count} warning"
13
- result += 's' unless count == 1
14
+ result = Rainbow("#{examiner.description} -- ").cyan + Rainbow("#{count} warning").yellow
15
+ result += Rainbow('s').yellow unless count == 1
14
16
  result
15
17
  end
16
18
  end
@@ -33,13 +35,19 @@ module Reek
33
35
  end
34
36
  end
35
37
 
38
+ #
39
+ # A report that contains the smells and smell counts following source code analysis.
40
+ #
36
41
  class Report
37
- def initialize(warning_formatter = SimpleWarningFormatter, report_formatter = ReportFormatter, sort_by_issue_count = false)
42
+ DefaultFormat = :text
43
+
44
+ def initialize(warning_formatter = SimpleWarningFormatter, report_formatter = ReportFormatter, sort_by_issue_count = false, format = DefaultFormat)
38
45
  @warning_formatter = warning_formatter
39
46
  @report_formatter = report_formatter
40
47
  @examiners = []
41
48
  @total_smell_count = 0
42
49
  @sort_by_issue_count = sort_by_issue_count
50
+ @format = format
43
51
  end
44
52
 
45
53
  def add_examiner(examiner)
@@ -49,9 +57,18 @@ module Reek
49
57
  end
50
58
 
51
59
  def show
52
- sort_examiners
53
- display_summary
54
- display_total_smell_count
60
+ case @format
61
+ when DefaultFormat
62
+ sort_examiners
63
+ display_summary
64
+ display_total_smell_count
65
+ when :yaml
66
+ if all_smells.size > 0
67
+ print(all_smells.to_yaml)
68
+ else
69
+ print ''
70
+ end
71
+ end
55
72
  end
56
73
 
57
74
  def has_smells?
@@ -60,8 +77,13 @@ module Reek
60
77
 
61
78
  private
62
79
 
80
+ def all_smells
81
+ @all_smells ||= @examiners.each_with_object([]) { |examiner, smells| smells << examiner.smells }
82
+ .flatten
83
+ end
84
+
63
85
  def sort_examiners
64
- @examiners.sort! {|a, b| b.smells_count <=> a.smells_count } if @sort_by_issue_count
86
+ @examiners.sort! {|first, second| second.smells_count <=> first.smells_count } if @sort_by_issue_count
65
87
  end
66
88
 
67
89
  def display_summary
@@ -76,7 +98,7 @@ module Reek
76
98
  end
77
99
 
78
100
  def total_smell_count_message
79
- "#{@total_smell_count} total warning#{'s' unless @total_smell_count == 1 }\n"
101
+ Rainbow("#{@total_smell_count} total warning#{'s' unless @total_smell_count == 1 }\n").red
80
102
  end
81
103
 
82
104
  def summarize_single_examiner(examiner)
@@ -89,6 +111,9 @@ module Reek
89
111
  end
90
112
  end
91
113
 
114
+ #
115
+ # A report that lists smell-free source files.
116
+ #
92
117
  class VerboseReport < Report
93
118
  def gather_results
94
119
  @examiners.each_with_object([]) do |examiner, result|
@@ -97,6 +122,9 @@ module Reek
97
122
  end
98
123
  end
99
124
 
125
+ #
126
+ # A report that does not list smell-free source files.
127
+ #
100
128
  class QuietReport < Report
101
129
  def gather_results
102
130
  @examiners.each_with_object([]) do |examiner, result|