reek 4.7.1 → 5.0.0

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 (260) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -12
  3. data/.rubocop.yml +36 -7
  4. data/.simplecov +1 -0
  5. data/.travis.yml +3 -9
  6. data/.yardopts +1 -1
  7. data/CHANGELOG.md +59 -0
  8. data/CONTRIBUTING.md +1 -1
  9. data/Gemfile +5 -5
  10. data/README.md +134 -104
  11. data/Rakefile +16 -3
  12. data/bin/reek +1 -3
  13. data/docs/API.md +2 -9
  14. data/docs/Basic-Smell-Options.md +51 -11
  15. data/docs/Code-Smells.md +1 -1
  16. data/docs/Command-Line-Options.md +14 -4
  17. data/docs/Duplicate-Method-Call.md +49 -1
  18. data/docs/Feature-Envy.md +44 -0
  19. data/docs/How-To-Write-New-Detectors.md +7 -7
  20. data/docs/Instance-Variable-Assumption.md +1 -1
  21. data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
  22. data/docs/Rake-Task.md +1 -1
  23. data/docs/Reek-4-to-Reek-5-migration.md +193 -0
  24. data/docs/Reek-Driven-Development.md +1 -1
  25. data/docs/Uncommunicative-Method-Name.md +45 -6
  26. data/docs/Uncommunicative-Module-Name.md +49 -7
  27. data/docs/Uncommunicative-Parameter-Name.md +43 -5
  28. data/docs/Uncommunicative-Variable-Name.md +73 -2
  29. data/docs/Unused-Private-Method.md +3 -3
  30. data/docs/defaults.reek.yml +129 -0
  31. data/docs/yard_plugin.rb +1 -0
  32. data/features/command_line_interface/basic_usage.feature +2 -2
  33. data/features/command_line_interface/options.feature +46 -4
  34. data/features/command_line_interface/show_progress.feature +4 -4
  35. data/features/command_line_interface/smell_selection.feature +1 -1
  36. data/features/command_line_interface/smells_count.feature +6 -6
  37. data/features/command_line_interface/stdin.feature +30 -8
  38. data/features/configuration_files/accept_setting.feature +45 -28
  39. data/features/configuration_files/directory_specific_directives.feature +80 -75
  40. data/features/configuration_files/exclude_directives.feature +11 -10
  41. data/features/configuration_files/exclude_paths_directives.feature +4 -4
  42. data/features/configuration_files/masking_smells.feature +38 -9
  43. data/features/configuration_files/mix_accept_reject_setting.feature +31 -28
  44. data/features/configuration_files/reject_setting.feature +52 -41
  45. data/features/configuration_files/schema_validation.feature +59 -0
  46. data/features/configuration_files/unused_private_method.feature +18 -16
  47. data/features/configuration_loading.feature +53 -10
  48. data/features/configuration_via_source_comments/erroneous_source_comments.feature +3 -3
  49. data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
  50. data/features/locales.feature +32 -0
  51. data/features/rake_task/rake_task.feature +58 -18
  52. data/features/reports/json.feature +3 -3
  53. data/features/reports/reports.feature +34 -34
  54. data/features/reports/yaml.feature +3 -3
  55. data/features/rspec_matcher.feature +40 -0
  56. data/features/samples.feature +287 -287
  57. data/features/step_definitions/reek_steps.rb +2 -2
  58. data/features/step_definitions/sample_file_steps.rb +9 -4
  59. data/features/support/env.rb +2 -11
  60. data/features/todo_list.feature +26 -23
  61. data/lib/reek/ast/builder.rb +1 -1
  62. data/lib/reek/ast/node.rb +40 -58
  63. data/lib/reek/ast/object_refs.rb +1 -1
  64. data/lib/reek/ast/reference_collector.rb +2 -4
  65. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  66. data/lib/reek/ast/sexp_extensions/if.rb +8 -1
  67. data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
  68. data/lib/reek/ast/sexp_extensions/methods.rb +4 -6
  69. data/lib/reek/ast/sexp_extensions/send.rb +0 -4
  70. data/lib/reek/cli/application.rb +4 -3
  71. data/lib/reek/cli/command/report_command.rb +1 -2
  72. data/lib/reek/cli/command/todo_list_command.rb +8 -8
  73. data/lib/reek/cli/options.rb +31 -16
  74. data/lib/reek/cli/silencer.rb +14 -3
  75. data/lib/reek/code_comment.rb +14 -16
  76. data/lib/reek/configuration/app_configuration.rb +32 -27
  77. data/lib/reek/configuration/configuration_converter.rb +110 -0
  78. data/lib/reek/configuration/configuration_file_finder.rb +16 -41
  79. data/lib/reek/configuration/configuration_validator.rb +12 -23
  80. data/lib/reek/configuration/default_directive.rb +17 -3
  81. data/lib/reek/configuration/directory_directives.rb +17 -11
  82. data/lib/reek/configuration/excluded_paths.rb +1 -1
  83. data/lib/reek/configuration/rake_task_converter.rb +29 -0
  84. data/lib/reek/configuration/schema.yml +210 -0
  85. data/lib/reek/configuration/schema_validator.rb +38 -0
  86. data/lib/reek/context/attribute_context.rb +3 -3
  87. data/lib/reek/context/code_context.rb +47 -43
  88. data/lib/reek/context/ghost_context.rb +0 -2
  89. data/lib/reek/context/method_context.rb +22 -15
  90. data/lib/reek/context/module_context.rb +5 -9
  91. data/lib/reek/context/root_context.rb +0 -4
  92. data/lib/reek/context/send_context.rb +2 -2
  93. data/lib/reek/context_builder.rb +43 -44
  94. data/lib/reek/detector_repository.rb +11 -11
  95. data/lib/reek/documentation_link.rb +28 -0
  96. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +14 -13
  97. data/lib/reek/errors/bad_detector_in_comment_error.rb +12 -11
  98. data/lib/reek/errors/base_error.rb +3 -0
  99. data/lib/reek/errors/config_file_error.rb +11 -0
  100. data/lib/reek/errors/encoding_error.rb +43 -0
  101. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +13 -12
  102. data/lib/reek/errors/incomprehensible_source_error.rb +22 -24
  103. data/lib/reek/errors/syntax_error.rb +41 -0
  104. data/lib/reek/examiner.rb +24 -26
  105. data/lib/reek/logging_error_handler.rb +7 -5
  106. data/lib/reek/rake/task.rb +8 -4
  107. data/lib/reek/report/base_report.rb +8 -12
  108. data/lib/reek/report/code_climate/code_climate_configuration.rb +1 -1
  109. data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -10
  110. data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
  111. data/lib/reek/report/heading_formatter.rb +54 -0
  112. data/lib/reek/report/json_report.rb +1 -1
  113. data/lib/reek/report/location_formatter.rb +40 -0
  114. data/lib/reek/report/progress_formatter.rb +79 -0
  115. data/lib/reek/report/simple_warning_formatter.rb +34 -0
  116. data/lib/reek/report/text_report.rb +1 -2
  117. data/lib/reek/report/xml_report.rb +3 -3
  118. data/lib/reek/report/yaml_report.rb +1 -1
  119. data/lib/reek/report.rb +15 -10
  120. data/lib/reek/smell_configuration.rb +2 -2
  121. data/lib/reek/smell_detectors/attribute.rb +5 -11
  122. data/lib/reek/smell_detectors/base_detector.rb +30 -26
  123. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -5
  124. data/lib/reek/smell_detectors/class_variable.rb +5 -14
  125. data/lib/reek/smell_detectors/control_parameter.rb +18 -33
  126. data/lib/reek/smell_detectors/data_clump.rb +15 -9
  127. data/lib/reek/smell_detectors/duplicate_method_call.rb +23 -17
  128. data/lib/reek/smell_detectors/feature_envy.rb +9 -7
  129. data/lib/reek/smell_detectors/instance_variable_assumption.rb +14 -23
  130. data/lib/reek/smell_detectors/irresponsible_module.rb +5 -12
  131. data/lib/reek/smell_detectors/long_parameter_list.rb +10 -7
  132. data/lib/reek/smell_detectors/long_yield_list.rb +10 -7
  133. data/lib/reek/smell_detectors/manual_dispatch.rb +4 -5
  134. data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +20 -20
  135. data/lib/reek/smell_detectors/module_initialize.rb +3 -5
  136. data/lib/reek/smell_detectors/nested_iterators.rb +16 -24
  137. data/lib/reek/smell_detectors/nil_check.rb +8 -15
  138. data/lib/reek/smell_detectors/repeated_conditional.rb +13 -11
  139. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +7 -8
  140. data/lib/reek/smell_detectors/too_many_constants.rb +10 -9
  141. data/lib/reek/smell_detectors/too_many_instance_variables.rb +10 -6
  142. data/lib/reek/smell_detectors/too_many_methods.rb +11 -7
  143. data/lib/reek/smell_detectors/too_many_statements.rb +10 -6
  144. data/lib/reek/smell_detectors/uncommunicative_method_name.rb +10 -11
  145. data/lib/reek/smell_detectors/uncommunicative_module_name.rb +14 -18
  146. data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +17 -22
  147. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +26 -27
  148. data/lib/reek/smell_detectors/unused_parameters.rb +4 -6
  149. data/lib/reek/smell_detectors/unused_private_method.rb +11 -18
  150. data/lib/reek/smell_detectors/utility_function.rb +12 -16
  151. data/lib/reek/smell_detectors.rb +1 -2
  152. data/lib/reek/smell_warning.rb +15 -8
  153. data/lib/reek/source/source_code.rb +57 -58
  154. data/lib/reek/source/source_locator.rb +8 -8
  155. data/lib/reek/spec/should_reek.rb +2 -2
  156. data/lib/reek/spec/should_reek_of.rb +9 -16
  157. data/lib/reek/spec/should_reek_only_of.rb +4 -4
  158. data/lib/reek/spec.rb +6 -6
  159. data/lib/reek/tree_dresser.rb +8 -8
  160. data/lib/reek/version.rb +1 -1
  161. data/reek.gemspec +5 -7
  162. data/samples/checkstyle.xml +1 -1
  163. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
  164. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
  165. data/samples/configuration/full_configuration.reek +8 -4
  166. data/samples/configuration/full_mask.reek +5 -4
  167. data/samples/configuration/partial_mask.reek +3 -2
  168. data/samples/configuration/regular_configuration/.reek.yml +4 -0
  169. data/samples/paths.rb +5 -4
  170. data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
  171. data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
  172. data/spec/factories/factories.rb +2 -13
  173. data/spec/reek/ast/node_spec.rb +103 -10
  174. data/spec/reek/ast/reference_collector_spec.rb +1 -1
  175. data/spec/reek/ast/sexp_extensions_spec.rb +14 -34
  176. data/spec/reek/cli/application_spec.rb +52 -42
  177. data/spec/reek/cli/command/todo_list_command_spec.rb +6 -4
  178. data/spec/reek/cli/silencer_spec.rb +28 -0
  179. data/spec/reek/code_comment_spec.rb +31 -38
  180. data/spec/reek/configuration/app_configuration_spec.rb +46 -33
  181. data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -51
  182. data/spec/reek/configuration/default_directive_spec.rb +1 -1
  183. data/spec/reek/configuration/directory_directives_spec.rb +6 -7
  184. data/spec/reek/configuration/excluded_paths_spec.rb +6 -6
  185. data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
  186. data/spec/reek/configuration/schema_validator_spec.rb +165 -0
  187. data/spec/reek/context/code_context_spec.rb +70 -106
  188. data/spec/reek/context/ghost_context_spec.rb +9 -9
  189. data/spec/reek/context/method_context_spec.rb +2 -2
  190. data/spec/reek/context/module_context_spec.rb +3 -3
  191. data/spec/reek/context/root_context_spec.rb +1 -1
  192. data/spec/reek/context_builder_spec.rb +20 -0
  193. data/spec/reek/documentation_link_spec.rb +20 -0
  194. data/spec/reek/errors/base_error_spec.rb +13 -0
  195. data/spec/reek/examiner_spec.rb +136 -29
  196. data/spec/reek/rake/task_spec.rb +25 -2
  197. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
  198. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  199. data/spec/reek/report/json_report_spec.rb +13 -46
  200. data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
  201. data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
  202. data/spec/reek/report/text_report_spec.rb +4 -4
  203. data/spec/reek/report/xml_report_spec.rb +3 -3
  204. data/spec/reek/report/yaml_report_spec.rb +9 -38
  205. data/spec/reek/report_spec.rb +3 -3
  206. data/spec/reek/smell_detectors/base_detector_spec.rb +4 -5
  207. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
  208. data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
  209. data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
  210. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +3 -3
  211. data/spec/reek/smell_detectors/feature_envy_spec.rb +47 -2
  212. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -11
  213. data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +10 -10
  214. data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
  215. data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
  216. data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
  217. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
  218. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
  219. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
  220. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +36 -15
  221. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +9 -9
  222. data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
  223. data/spec/reek/smell_detectors/unused_private_method_spec.rb +21 -10
  224. data/spec/reek/smell_detectors/utility_function_spec.rb +57 -5
  225. data/spec/reek/smell_warning_spec.rb +12 -8
  226. data/spec/reek/source/source_code_spec.rb +22 -21
  227. data/spec/reek/source/source_locator_spec.rb +17 -17
  228. data/spec/reek/spec/should_reek_of_spec.rb +25 -29
  229. data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
  230. data/spec/reek/spec/should_reek_spec.rb +8 -8
  231. data/spec/reek/spec/smell_matcher_spec.rb +23 -23
  232. data/spec/reek/tree_dresser_spec.rb +12 -17
  233. data/spec/spec_helper.rb +6 -17
  234. data/tasks/configuration.rake +8 -5
  235. metadata +74 -41
  236. data/defaults.reek +0 -131
  237. data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
  238. data/lib/reek/report/formatter/heading_formatter.rb +0 -52
  239. data/lib/reek/report/formatter/location_formatter.rb +0 -42
  240. data/lib/reek/report/formatter/progress_formatter.rb +0 -81
  241. data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
  242. data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -36
  243. data/lib/reek/report/formatter.rb +0 -33
  244. data/lib/reek/smell_detectors/syntax.rb +0 -37
  245. data/samples/configuration/non_public_modifiers_mask.reek +0 -3
  246. data/samples/smelly_with_inline_mask.rb +0 -8
  247. data/samples/smelly_with_modifiers.rb +0 -12
  248. data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
  249. data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
  250. data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
  251. /data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
  252. /data/samples/{clean.rb → clean_source/clean.rb} +0 -0
  253. /data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
  254. /data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
  255. /data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
  256. /data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
  257. /data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
  258. /data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
  259. /data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
  260. /data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
@@ -21,8 +21,8 @@ Reek's _Uncommunicative Method Name_ detector supports the
21
21
 
22
22
  | Option | Value | Effect |
23
23
  | ---------------|-------------|---------|
24
- | `reject` | array of regular expressions or strings | The set of patterns / names that Reek uses to check for bad names. Defaults to `[/^[a-z]$/, /[0-9]$/, /[A-Z]/]`. |
25
- | `accept` | array of regular expressions or strings | The set of patterns / names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
24
+ | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names, names ending with a number or names containing upper case letters. |
25
+ | `accept` | array of strings | The set of names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
26
26
 
27
27
  An example configuration could look like this:
28
28
 
@@ -30,13 +30,15 @@ An example configuration could look like this:
30
30
  ---
31
31
  UncommunicativeMethodName:
32
32
  accept:
33
- - !ruby/regexp /x/
33
+ - x
34
34
  - meth1
35
35
  reject:
36
- - !ruby/regexp /helper/
36
+ - helper
37
37
  - foobar
38
38
  ```
39
39
 
40
+ Reek will convert whatever you give it as a string to the corresponding regex, so "foobar" from above will be converted to /foobar/ internally.
41
+
40
42
  Applying a configuration to a source file like this:
41
43
 
42
44
  ```Ruby
@@ -50,6 +52,43 @@ Reek would report:
50
52
 
51
53
  ```
52
54
  smelly.rb -- 2 warnings:
53
- [4]:UncommunicativeMethodName: awesome_helper has the name 'awesome_helper' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
54
- [3]:UncommunicativeMethodName: foobar has the name 'foobar' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
55
+ [4]:UncommunicativeMethodName: awesome_helper has the name 'awesome_helper'
56
+ [3]:UncommunicativeMethodName: foobar has the name 'foobar'
57
+ ```
58
+
59
+ ## Advanced configuration
60
+
61
+ Sometimes just strings are not enough for configuration. E.g. consider this code sample:
62
+
63
+ ```Ruby
64
+ class Klass
65
+ def foo; end
66
+ def foobar; end;
67
+ end
55
68
  ```
69
+
70
+ and now imagine that you want to reject the name "foo" but not "foobar". This wouldn't be possible with just using strings.
71
+ For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
72
+ Everything within the forward slashes will be loaded as a regex.
73
+
74
+ A possible configuration that allows "foobar" but rejects "foo" could look like this:
75
+
76
+ ```Yaml
77
+ ---
78
+ UncommunicativeMethodName:
79
+ reject:
80
+ - "/^foo$/"
81
+ ```
82
+
83
+ ## Reek 4
84
+
85
+ In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
86
+
87
+ ```yaml
88
+ UncommunicativeMethodName:
89
+ accept:
90
+ - !ruby/regexp /foobar/
91
+ ```
92
+
93
+ Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
94
+ You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -19,8 +19,8 @@ Reek's _Uncommunicative Module Name_ detector supports the [Basic Smell Options]
19
19
 
20
20
  | Option | Value | Effect |
21
21
  | ---------------|-------------|---------|
22
- | `reject` | array of regular expressions or strings | The set of patterns or names that Reek uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/]`. |
23
- | `accept` | array of regular expressions or strings | The set of patterns or names that Reek will accept (and not report) even if they match one of the `reject` expressions. Empty by default.|
22
+ | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names and names ending with a number. |
23
+ | `accept` | array or strings | The set of names that Reek will accept (and not report) even if they match one of the `reject` expressions. Empty by default.|
24
24
 
25
25
  An example configuration could look like this:
26
26
 
@@ -28,17 +28,19 @@ An example configuration could look like this:
28
28
  ---
29
29
  UncommunicativeModuleName:
30
30
  accept:
31
- - !ruby/regexp /lassy/
32
- - M
31
+ - lassy
32
+ - Util
33
33
  reject:
34
- - !ruby/regexp /Helper/
34
+ - Helper
35
35
  ```
36
36
 
37
+ Reek will convert whatever you give it as a string to the corresponding regex, so "Helper" from above will be converted to /Helper/ internally.
38
+
37
39
  Applying a configuration to a source file like this:
38
40
 
39
41
  ```Ruby
40
42
  class Classy1; end # Should not be reported
41
- class M; end # Should not be reported
43
+ class Util; end # Should not be reported
42
44
  class BaseHelper; end # Should be reported
43
45
  ```
44
46
 
@@ -46,5 +48,45 @@ Reek would report:
46
48
 
47
49
  ```
48
50
  smelly.rb -- 1 warning:
49
- [3]:UncommunicativeModuleName: BaseHelper has the name 'BaseHelper' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Module-Name.md]
51
+ [3]:UncommunicativeModuleName: BaseHelper has the name 'BaseHelper'
52
+ ```
53
+
54
+ ## Advanced configuration
55
+
56
+ Sometimes just strings are not enough for configuration. E.g. consider this code sample:
57
+
58
+ ```Ruby
59
+ class Klassy
60
+ # ...
61
+ end
62
+
63
+ class KlassyModule
64
+ # ...
65
+ end
66
+ ```
67
+
68
+ and now imagine that you want to reject the name "Klassy" but not "KlassyModule". This wouldn't be possible with just using strings.
69
+ For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
70
+ Everything within the forward slashes will be loaded as a regex.
71
+
72
+ A possible configuration that allows "KlassyModule" but rejects "Klassy" could look like this:
73
+
74
+ ```Yaml
75
+ ---
76
+ UncommunicativeModuleName:
77
+ reject:
78
+ - "/^Klassy$/"
50
79
  ```
80
+
81
+ ## Reek 4
82
+
83
+ In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
84
+
85
+ ```yaml
86
+ UncommunicativeModuleName:
87
+ accept:
88
+ - !ruby/regexp /foobar/
89
+ ```
90
+
91
+ Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
92
+ You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -20,8 +20,8 @@ Reek's _Uncommunicative Parameter Name_ detector supports the [Basic Smell Optio
20
20
 
21
21
  | Option | Value | Effect |
22
22
  | ---------|-------------|---------|
23
- | `reject` | array of regular expressions or strings | The set of patterns / names that Reek uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/, /^_/]. |
24
- | `accept` | array of regular expressions or strings | The set of patterns / names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
23
+ | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names, names containing an uppercase letter, names with a number at the end and '_'. |
24
+ | `accept` | array of strings | The set of names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
25
25
 
26
26
 
27
27
  An example configuration could look like this:
@@ -30,12 +30,14 @@ An example configuration could look like this:
30
30
  ---
31
31
  UncommunicativeParameterName:
32
32
  accept:
33
- - !ruby/regexp /x/
33
+ - x
34
34
  - arg1
35
35
  reject:
36
- - !ruby/regexp /foobar/
36
+ - foobar
37
37
  ```
38
38
 
39
+ Reek will convert whatever you give it as a string to the corresponding regex, so "foobar" from above will be converted to /foobar/ internally.
40
+
39
41
  Applying a configuration to a source file like this:
40
42
 
41
43
  ```Ruby
@@ -48,5 +50,41 @@ Reek would report:
48
50
 
49
51
  ```
50
52
  smelly.rb -- 1 warning:
51
- [3]:UncommunicativeParameterName: omg has the parameter name 'foobar' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md]
53
+ [3]:UncommunicativeParameterName: omg has the parameter name 'foobar'
54
+ ```
55
+
56
+ ## Advanced configuration
57
+
58
+ Sometimes just strings are not enough for configuration. E.g. consider this code sample:
59
+
60
+ ```Ruby
61
+ class Klass
62
+ def my_method(foo, foobar); end
63
+ end
52
64
  ```
65
+
66
+ and now imagine that you want to reject the name "foo" but not "foobar". This wouldn't be possible with just using strings.
67
+ For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
68
+ Everything within the forward slashes will be loaded as a regex.
69
+
70
+ A possible configuration that allows "foobar" but rejects "foo" could look like this:
71
+
72
+ ```Yaml
73
+ ---
74
+ UncommunicativeParameterName:
75
+ reject:
76
+ - "/^foo$/"
77
+ ```
78
+
79
+ ## Reek 4
80
+
81
+ In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
82
+
83
+ ```yaml
84
+ UncommunicativeParameterName:
85
+ accept:
86
+ - !ruby/regexp /foobar/
87
+ ```
88
+
89
+ Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
90
+ You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -21,5 +21,76 @@ Reek's _Uncommunicative Variable Name_ detector supports the
21
21
 
22
22
  | Option | Value | Effect |
23
23
  | ---------------|-------------|---------|
24
- | `reject` | array of regular expressions | The set of regular expressions that Reek uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/]`. |
25
- | `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to `['_']`.|
24
+ | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names, names ending with a number or names containing upper case letters. |
25
+ | `accept` | array of strings | Names that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to `_`.|
26
+
27
+ An example configuration could look like this:
28
+
29
+ ```Yaml
30
+ ---
31
+ UncommunicativeVariableName:
32
+ accept:
33
+ - x
34
+ - var1
35
+ reject:
36
+ - helper
37
+ - foobar
38
+ ```
39
+
40
+ Reek will convert whatever you give it as a string to the corresponding regex, so "foobar" from above will be converted to /foobar/ internally.
41
+
42
+ Applying a configuration to a source file like this:
43
+
44
+ ```Ruby
45
+ def omg
46
+ x = 5 # Should not be reported
47
+ var1 = true # Should not be reported
48
+ helper = 42 # Should be reported
49
+ foobar = false # Should be reported
50
+ end
51
+ ```
52
+
53
+ Reek would report:
54
+
55
+ ```
56
+ smelly.rb -- 2 warnings:
57
+ [5]:UncommunicativeVariableName: omg has the variable name 'foobar' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
58
+ [4]:UncommunicativeVariableName: omg has the variable name 'helper' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
59
+ ```
60
+
61
+ ## Advanced configuration
62
+
63
+ Sometimes just strings are not enough for configuration. E.g. consider this code sample:
64
+
65
+ ```Ruby
66
+ def omg
67
+ foo = 42
68
+ foobar = 4242
69
+ end
70
+ ```
71
+
72
+ and now imagine that you want to reject the name "foo" but not "foobar". This wouldn't be possible with just using strings.
73
+ For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
74
+ Everything within the forward slashes will be loaded as a regex.
75
+
76
+ A possible configuration that allows "foobar" but rejects "foo" could look like this:
77
+
78
+ ```Yaml
79
+ ---
80
+ UncommunicativeVariableName:
81
+ reject:
82
+ - "/^foo$/"
83
+ ```
84
+
85
+ ## Reek 4
86
+
87
+ In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
88
+
89
+ ```yaml
90
+ UncommunicativeVariableName:
91
+ accept:
92
+ - !ruby/regexp /write/
93
+ ```
94
+
95
+ Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
96
+ You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -37,7 +37,7 @@ configuration option (which is part of the [Basic Smell Options](Basic-Smell-Opt
37
37
  for instance like this (an example from Reek's own codebase):
38
38
 
39
39
  ```Ruby
40
- # :reek:UnusedPrivateMethod { exclude: [ !ruby/regexp /process_/ ] }
40
+ # :reek:UnusedPrivateMethod { exclude: [ process_ ] }
41
41
  class ContextBuilder
42
42
  def process_begin
43
43
  # ....
@@ -78,13 +78,13 @@ end
78
78
  ## Known limitations
79
79
 
80
80
  * Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
81
- static tool for that matter) can not detect.
81
+ static tool for that matter) cannot detect.
82
82
  * Method calls via callback like [Rails filters](http://guides.rubyonrails.org/action_controller_overview.html#filters)
83
83
  will trigger this as well, e.g.:
84
84
 
85
85
  ```Ruby
86
86
  class BankController < ActionController::Base
87
- before_filter :audit
87
+ before_action :audit
88
88
 
89
89
  private
90
90
  def audit
@@ -0,0 +1,129 @@
1
+ ---
2
+ detectors:
3
+ Attribute:
4
+ enabled: true
5
+ exclude: []
6
+ BooleanParameter:
7
+ enabled: true
8
+ exclude: []
9
+ ClassVariable:
10
+ enabled: true
11
+ exclude: []
12
+ ControlParameter:
13
+ enabled: true
14
+ exclude: []
15
+ DataClump:
16
+ enabled: true
17
+ exclude: []
18
+ max_copies: 2
19
+ min_clump_size: 2
20
+ DuplicateMethodCall:
21
+ enabled: true
22
+ exclude: []
23
+ max_calls: 1
24
+ allow_calls: []
25
+ FeatureEnvy:
26
+ enabled: true
27
+ exclude: []
28
+ InstanceVariableAssumption:
29
+ enabled: true
30
+ exclude: []
31
+ IrresponsibleModule:
32
+ enabled: true
33
+ exclude: []
34
+ LongParameterList:
35
+ enabled: true
36
+ exclude: []
37
+ max_params: 3
38
+ overrides:
39
+ initialize:
40
+ max_params: 5
41
+ LongYieldList:
42
+ enabled: true
43
+ exclude: []
44
+ max_params: 3
45
+ ManualDispatch:
46
+ enabled: true
47
+ exclude: []
48
+ MissingSafeMethod:
49
+ enabled: true
50
+ exclude: []
51
+ ModuleInitialize:
52
+ enabled: true
53
+ exclude: []
54
+ NestedIterators:
55
+ enabled: true
56
+ exclude: []
57
+ max_allowed_nesting: 1
58
+ ignore_iterators:
59
+ - tap
60
+ NilCheck:
61
+ enabled: true
62
+ exclude: []
63
+ RepeatedConditional:
64
+ enabled: true
65
+ exclude: []
66
+ max_ifs: 2
67
+ SubclassedFromCoreClass:
68
+ enabled: true
69
+ exclude: []
70
+ TooManyConstants:
71
+ enabled: true
72
+ exclude: []
73
+ max_constants: 5
74
+ TooManyInstanceVariables:
75
+ enabled: true
76
+ exclude: []
77
+ max_instance_variables: 4
78
+ TooManyMethods:
79
+ enabled: true
80
+ exclude: []
81
+ max_methods: 15
82
+ TooManyStatements:
83
+ enabled: true
84
+ exclude:
85
+ - initialize
86
+ max_statements: 5
87
+ UncommunicativeMethodName:
88
+ enabled: true
89
+ exclude: []
90
+ reject:
91
+ - "/^[a-z]$/"
92
+ - "/[0-9]$/"
93
+ - "/[A-Z]/"
94
+ accept: []
95
+ UncommunicativeModuleName:
96
+ enabled: true
97
+ exclude: []
98
+ reject:
99
+ - "/^.$/"
100
+ - "/[0-9]$/"
101
+ accept: []
102
+ UncommunicativeParameterName:
103
+ enabled: true
104
+ exclude: []
105
+ reject:
106
+ - "/^.$/"
107
+ - "/[0-9]$/"
108
+ - "/[A-Z]/"
109
+ - "/^_/"
110
+ accept: []
111
+ UncommunicativeVariableName:
112
+ enabled: true
113
+ exclude: []
114
+ reject:
115
+ - "/^.$/"
116
+ - "/[0-9]$/"
117
+ - "/[A-Z]/"
118
+ accept:
119
+ - "/^_$/"
120
+ UnusedParameters:
121
+ enabled: true
122
+ exclude: []
123
+ UnusedPrivateMethod:
124
+ enabled: false
125
+ exclude: []
126
+ UtilityFunction:
127
+ enabled: true
128
+ exclude: []
129
+ public_methods_only: false
data/docs/yard_plugin.rb CHANGED
@@ -13,4 +13,5 @@ end
13
13
 
14
14
  YARD::Templates::Template.extra_includes << LocalLinkHelper
15
15
  YARD::Tags::Library.define_tag('Guaranteed public API', :public)
16
+ YARD::Tags::Library.define_tag('Code quality configuration', :quality)
16
17
  YARD::Templates::Engine.register_template_path File.join(File.dirname(__FILE__), 'templates')
@@ -10,6 +10,6 @@ Feature: The Reek CLI maintains backwards compatibility
10
10
  And it reports:
11
11
  """
12
12
  smelly.rb -- 2 warnings:
13
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
14
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
13
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
14
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
15
15
  """
@@ -37,13 +37,14 @@ Feature: Reek can be controlled using command-line options
37
37
  reek -s lib
38
38
  cat my_class.rb | reek
39
39
 
40
- See https://wiki.github.com/troessner/reek for detailed help.
40
+ See https://github.com/troessner/reek for detailed help.
41
41
 
42
42
  Configuration:
43
43
  -c, --config FILE Read configuration options from FILE
44
44
  --smell SMELL Only look for a specific smell.
45
- Call it like this: reek --smell PrimaDonnaMethod source.rb
46
- Check out https://github.com/troessner/reek/blob/master/docs/Code-Smells.md for a list of smells
45
+ Call it like this: reek --smell MissingSafeMethod source.rb
46
+ Check out https://github.com/troessner/reek/blob/v5.0.0/docs/Code-Smells.md for a list of smells
47
+ --stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
47
48
 
48
49
  Generate a todo list:
49
50
  -t, --todo Generate a todo list
@@ -60,7 +61,7 @@ Feature: Reek can be controlled using command-line options
60
61
  Text format options:
61
62
  --[no-]color Use colors for the output (default: true)
62
63
  -V, --[no-]empty-headings Show headings for smell-free source files (default: false)
63
- -U, --[no-]wiki-links Show link to related wiki page for each smell (default: true)
64
+ -U, --[no-]documentation Show link to related documentation page for each smell (default: true)
64
65
  -n, --[no-]line-numbers Show line numbers in the output (default: true)
65
66
  -s, --single-line Show location in editor-compatible single-line-per-smell format
66
67
  -P, --[no-]progress Show progress of each source as it is examined (default: true)
@@ -76,5 +77,46 @@ Feature: Reek can be controlled using command-line options
76
77
 
77
78
  Utility options:
78
79
  -h, --help Show this message
80
+ -l, --list List all available smell detectors
79
81
  -v, --version Show version
80
82
  """
83
+
84
+ Scenario: List all available smell detectors
85
+ When I run reek --list
86
+ Then it succeeds
87
+ And it reports:
88
+ """
89
+ All available smell detectors:
90
+
91
+ Attribute
92
+ BooleanParameter
93
+ ClassVariable
94
+ ControlParameter
95
+ DataClump
96
+ DuplicateMethodCall
97
+ FeatureEnvy
98
+ InstanceVariableAssumption
99
+ IrresponsibleModule
100
+ LongParameterList
101
+ LongYieldList
102
+ ManualDispatch
103
+ MissingSafeMethod
104
+ ModuleInitialize
105
+ NestedIterators
106
+ NilCheck
107
+ RepeatedConditional
108
+ SubclassedFromCoreClass
109
+ TooManyConstants
110
+ TooManyInstanceVariables
111
+ TooManyMethods
112
+ TooManyStatements
113
+ UncommunicativeMethodName
114
+ UncommunicativeModuleName
115
+ UncommunicativeParameterName
116
+ UncommunicativeVariableName
117
+ UnusedParameters
118
+ UnusedPrivateMethod
119
+ UtilityFunction
120
+
121
+ Check out https://github.com/troessner/reek/blob/v5.0.0/docs/Code-Smells.md for a details on each detector
122
+ """
@@ -15,8 +15,8 @@ Feature: Show progress
15
15
  .S
16
16
 
17
17
  mixed_files/dirty.rb -- 2 warnings:
18
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
19
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
18
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
19
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
20
20
  2 total warnings
21
21
  """
22
22
 
@@ -27,7 +27,7 @@ Feature: Show progress
27
27
  And it reports:
28
28
  """
29
29
  mixed_files/dirty.rb -- 2 warnings:
30
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
31
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
30
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
31
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
32
32
  2 total warnings
33
33
  """
@@ -11,5 +11,5 @@ Feature: Smell selection
11
11
  And it reports:
12
12
  """
13
13
  smelly.rb -- 1 warning:
14
- UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
14
+ UncommunicativeVariableName: Smelly#x has the variable name 'y'
15
15
  """
@@ -9,8 +9,8 @@ Feature: Reports total number of code smells
9
9
  And it reports:
10
10
  """
11
11
  smelly.rb -- 2 warnings:
12
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
13
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
12
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
13
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
14
14
  """
15
15
 
16
16
  Scenario: Output total number of smells when inspecting multiple files
@@ -20,11 +20,11 @@ Feature: Reports total number of code smells
20
20
  And it reports:
21
21
  """
22
22
  smelly/dirty_one.rb -- 2 warnings:
23
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
24
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
23
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
24
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
25
25
  smelly/dirty_two.rb -- 2 warnings:
26
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
27
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
26
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
27
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
28
28
  4 total warnings
29
29
  """
30
30
 
@@ -27,17 +27,39 @@ Feature: Reek reads from $stdin when no files are given
27
27
  And it reports:
28
28
  """
29
29
  STDIN -- 3 warnings:
30
- [1]:IrresponsibleModule: Turn has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
31
- [1]:UncommunicativeMethodName: Turn#y has the name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
32
- [1]:UncommunicativeVariableName: Turn has the variable name '@x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
30
+ [1]:IrresponsibleModule: Turn has no descriptive comment
31
+ [1]:UncommunicativeMethodName: Turn#y has the name 'y'
32
+ [1]:UncommunicativeVariableName: Turn has the variable name '@x'
33
33
  """
34
34
 
35
35
  Scenario: syntax error causes the source to be ignored
36
36
  When I pass "= invalid syntax =" to reek
37
- Then the exit status indicates smells
38
- And it reports:
37
+ Then it succeeds
38
+ And it reports the error "Parser::SyntaxError: unexpected token tEQL"
39
+
40
+ Scenario: providing a filename to use for the config to match against
41
+ Given a file named "web_app/config.reek" with:
39
42
  """
40
- STDIN -- 2 warnings:
41
- [2]:Syntax: This file has unexpected token $end [https://github.com/troessner/reek/blob/master/docs/Syntax.md]
42
- [1]:Syntax: This file has unexpected token tEQL [https://github.com/troessner/reek/blob/master/docs/Syntax.md]
43
+ ---
44
+ directories:
45
+ "web_app/app/controllers":
46
+ IrresponsibleModule:
47
+ enabled: false
48
+ NestedIterators:
49
+ enabled: false
50
+ InstanceVariableAssumption:
51
+ enabled: false
43
52
  """
53
+ When I pass a stdin to reek --config web_app/config.reek --stdin-filename web_app/app/controllers/users_controller with:
54
+ """
55
+ class UsersController < ApplicationController
56
+ def show
57
+ respond_with do |format|
58
+ format.json { |json| @user.to_custom_json }
59
+ format.xml { |xml| @user.to_fancy_xml }
60
+ end
61
+ end
62
+ end
63
+ """
64
+ Then it succeeds
65
+ And it reports nothing