reek 5.0.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -70
  3. data/.rubocop_todo.yml +63 -0
  4. data/.simplecov +4 -1
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +12 -17
  7. data/README.md +21 -29
  8. data/Rakefile +2 -2
  9. data/docs/templates/default/docstring/setup.rb +3 -0
  10. data/features/command_line_interface/options.feature +5 -3
  11. data/features/configuration_files/schema_validation.feature +3 -3
  12. data/features/configuration_files/show_configuration_file.feature +44 -0
  13. data/features/rake_task/rake_task.feature +1 -1
  14. data/features/reports/json.feature +3 -3
  15. data/features/reports/reports.feature +4 -4
  16. data/features/reports/yaml.feature +3 -3
  17. data/features/rspec_matcher.feature +1 -0
  18. data/features/step_definitions/sample_file_steps.rb +6 -8
  19. data/features/todo_list.feature +39 -26
  20. data/lib/reek.rb +7 -0
  21. data/lib/reek/ast/node.rb +4 -0
  22. data/lib/reek/ast/sexp_extensions/if.rb +20 -0
  23. data/lib/reek/ast/sexp_extensions/methods.rb +1 -0
  24. data/lib/reek/cli/application.rb +25 -0
  25. data/lib/reek/cli/command/todo_list_command.rb +17 -7
  26. data/lib/reek/cli/options.rb +21 -14
  27. data/lib/reek/code_comment.rb +2 -0
  28. data/lib/reek/configuration/app_configuration.rb +0 -3
  29. data/lib/reek/configuration/configuration_converter.rb +4 -4
  30. data/lib/reek/configuration/directory_directives.rb +1 -0
  31. data/lib/reek/configuration/schema_validator.rb +1 -0
  32. data/lib/reek/context/method_context.rb +1 -0
  33. data/lib/reek/context/module_context.rb +5 -4
  34. data/lib/reek/context/visibility_tracker.rb +7 -4
  35. data/lib/reek/context_builder.rb +1 -0
  36. data/lib/reek/detector_repository.rb +1 -0
  37. data/lib/reek/errors/incomprehensible_source_error.rb +2 -2
  38. data/lib/reek/errors/syntax_error.rb +4 -0
  39. data/lib/reek/examiner.rb +1 -0
  40. data/lib/reek/report/text_report.rb +1 -0
  41. data/lib/reek/smell_detectors/control_parameter.rb +13 -107
  42. data/lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb +91 -0
  43. data/lib/reek/smell_detectors/control_parameter_helpers/candidate.rb +38 -0
  44. data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +94 -0
  45. data/lib/reek/smell_detectors/duplicate_method_call.rb +1 -0
  46. data/lib/reek/smell_detectors/feature_envy.rb +2 -0
  47. data/lib/reek/smell_detectors/irresponsible_module.rb +1 -0
  48. data/lib/reek/smell_detectors/long_parameter_list.rb +1 -0
  49. data/lib/reek/smell_detectors/manual_dispatch.rb +1 -0
  50. data/lib/reek/smell_detectors/missing_safe_method.rb +1 -0
  51. data/lib/reek/smell_detectors/nested_iterators.rb +1 -0
  52. data/lib/reek/smell_detectors/repeated_conditional.rb +1 -0
  53. data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -0
  54. data/lib/reek/smell_detectors/too_many_methods.rb +1 -0
  55. data/lib/reek/smell_detectors/too_many_statements.rb +1 -0
  56. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +2 -0
  57. data/lib/reek/smell_detectors/unused_parameters.rb +1 -0
  58. data/lib/reek/source/source_locator.rb +1 -0
  59. data/lib/reek/spec/should_reek_of.rb +2 -2
  60. data/lib/reek/spec/should_reek_only_of.rb +1 -0
  61. data/lib/reek/spec/smell_matcher.rb +1 -0
  62. data/lib/reek/tree_dresser.rb +1 -0
  63. data/lib/reek/version.rb +1 -1
  64. data/samples/smelly_source/ruby.rb +368 -0
  65. data/spec/factories/factories.rb +10 -9
  66. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +17 -0
  67. data/spec/quality/documentation_spec.rb +40 -0
  68. data/spec/reek/ast/sexp_extensions_spec.rb +20 -20
  69. data/spec/reek/cli/application_spec.rb +29 -0
  70. data/spec/reek/cli/command/todo_list_command_spec.rb +64 -46
  71. data/spec/reek/configuration/app_configuration_spec.rb +8 -8
  72. data/spec/reek/configuration/configuration_file_finder_spec.rb +3 -3
  73. data/spec/reek/configuration/schema_validator_spec.rb +10 -10
  74. data/spec/reek/detector_repository_spec.rb +2 -2
  75. data/spec/reek/smell_detectors/control_parameter_spec.rb +17 -0
  76. data/spec/reek/source/source_locator_spec.rb +0 -2
  77. data/spec/spec_helper.rb +2 -0
  78. data/tasks/configuration.rake +2 -1
  79. data/tasks/test.rake +4 -0
  80. metadata +11 -5
  81. data/ataru_setup.rb +0 -13
  82. data/tasks/ataru.rake +0 -5
@@ -0,0 +1,44 @@
1
+ Feature: Show configuration file
2
+ With Reeks dynamic mechanism of finding a configuration file you might run into a situation where you are not
3
+ 100% sure what configuration file Reek is using. E.g. you have a project specific configuration file in your
4
+ project root and also another Reek configuration in your HOME directory that you use for all your other projects
5
+ and for whatever reasons Reek seems to be using another configuration file than the one you assumed it would.
6
+ In this case you can pass the flag `--show-configuration-path` to Reek which will cause Reek to output the path
7
+ to the configuration file it is using.
8
+
9
+ Scenario: Default configuration file present
10
+ Given the clean file "clean.rb"
11
+ And an empty file named ".reek.yml"
12
+ When I run reek --show-configuration-path clean.rb
13
+ Then it reports:
14
+ """
15
+ Using '.reek.yml' as configuration file.
16
+ """
17
+
18
+ Scenario: Non-default configuration file passed via CLI
19
+ Given the clean file "clean.rb"
20
+ And an empty file named "config.reek"
21
+ When I run reek --show-configuration-path -c config.reek clean.rb
22
+ Then it reports:
23
+ """
24
+ Using 'config.reek' as configuration file.
25
+ """
26
+
27
+ Scenario: Display the right configuration file even when there are multiple files present
28
+ Given the clean file "clean.rb"
29
+ And an empty file named ".reek.yml"
30
+ And an empty file named "config.reek"
31
+ When I run reek --show-configuration-path -c config.reek clean.rb
32
+ Then it reports:
33
+ """
34
+ Using 'config.reek' as configuration file.
35
+ """
36
+
37
+ Scenario: Use configuration file we find when traversing up the directory tree
38
+ Given the clean file "clean.rb"
39
+ And with a configuration file that is further up in the directory tree
40
+ When I run reek --show-configuration-path clean.rb
41
+ Then it reports:
42
+ """
43
+ Using '../../.reek.yml' as configuration file.
44
+ """
@@ -117,7 +117,7 @@ Feature: Reek can be driven through its Task
117
117
 
118
118
  Scenario: REEK_SRC overrides the files to check
119
119
  Given the smelly file 'smelly.rb'
120
- And the clean file 'clean.rb'
120
+ And the clean file "clean.rb"
121
121
  And a file "Rakefile" with:
122
122
  """
123
123
  require 'reek/rake/task'
@@ -24,7 +24,7 @@ Feature: Report smells using simple JSON layout
24
24
  "context": "Smelly#x",
25
25
  "lines": [ 4 ],
26
26
  "message": "has the name 'x'",
27
- "documentation_link": "https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Method-Name.md",
27
+ "documentation_link": "https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Method-Name.md",
28
28
  "name": "x"
29
29
  },
30
30
  {
@@ -33,7 +33,7 @@ Feature: Report smells using simple JSON layout
33
33
  "context": "Smelly#x",
34
34
  "lines": [ 5 ],
35
35
  "message": "has the variable name 'y'",
36
- "documentation_link": "https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Variable-Name.md",
36
+ "documentation_link": "https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Variable-Name.md",
37
37
  "name": "y"
38
38
  }
39
39
  ]
@@ -53,7 +53,7 @@ Feature: Report smells using simple JSON layout
53
53
  1
54
54
  ],
55
55
  "message": "has no descriptive comment",
56
- "documentation_link": "https://github.com/troessner/reek/blob/v5.0.2/docs/Irresponsible-Module.md"
56
+ "documentation_link": "https://github.com/troessner/reek/blob/v5.1.0/docs/Irresponsible-Module.md"
57
57
  }
58
58
  ]
59
59
  """
@@ -182,8 +182,8 @@ Feature: Correctly formatted reports
182
182
  And it reports:
183
183
  """
184
184
  smelly.rb -- 2 warnings:
185
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Method-Name.md]
186
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Variable-Name.md]
185
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Method-Name.md]
186
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Variable-Name.md]
187
187
  """
188
188
 
189
189
  Examples:
@@ -209,8 +209,8 @@ Feature: Correctly formatted reports
209
209
  And it reports:
210
210
  """
211
211
  smelly.rb -- 2 warnings:
212
- UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Method-Name.md]
213
- UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Variable-Name.md]
212
+ UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Method-Name.md]
213
+ UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Variable-Name.md]
214
214
  """
215
215
 
216
216
  Examples:
@@ -25,7 +25,7 @@ Feature: Report smells using simple YAML layout
25
25
  smell_type: UncommunicativeMethodName
26
26
  source: smelly.rb
27
27
  name: x
28
- documentation_link: https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Method-Name.md
28
+ documentation_link: https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Method-Name.md
29
29
  - context: Smelly#x
30
30
  lines:
31
31
  - 5
@@ -33,7 +33,7 @@ Feature: Report smells using simple YAML layout
33
33
  smell_type: UncommunicativeVariableName
34
34
  source: smelly.rb
35
35
  name: y
36
- documentation_link: https://github.com/troessner/reek/blob/v5.0.2/docs/Uncommunicative-Variable-Name.md
36
+ documentation_link: https://github.com/troessner/reek/blob/v5.1.0/docs/Uncommunicative-Variable-Name.md
37
37
  """
38
38
 
39
39
  Scenario: Indicate smells and print them as yaml when using STDIN
@@ -48,5 +48,5 @@ Feature: Report smells using simple YAML layout
48
48
  lines:
49
49
  - 1
50
50
  message: has no descriptive comment
51
- documentation_link: https://github.com/troessner/reek/blob/v5.0.2/docs/Irresponsible-Module.md
51
+ documentation_link: https://github.com/troessner/reek/blob/v5.1.0/docs/Irresponsible-Module.md
52
52
  """
@@ -7,6 +7,7 @@ Feature: Use reek_of matcher
7
7
  Given the smelly file 'smelly.rb'
8
8
  And a file "reek_spec.rb" with:
9
9
  """
10
+ require 'reek'
10
11
  require 'reek/spec'
11
12
 
12
13
  describe 'smelly.rb' do
@@ -4,8 +4,8 @@ Given(/^the smelly file '(.+)'$/) do |filename|
4
4
  write_file(filename, SAMPLES_DIR.join('smelly_source').join(filename).read)
5
5
  end
6
6
 
7
- Given(/^the clean file 'clean.rb'$/) do
8
- write_file('clean.rb', CLEAN_FILE.read)
7
+ Given(/^the clean file "(.*)"$/) do |filename|
8
+ write_file(filename, CLEAN_FILE.read)
9
9
  end
10
10
 
11
11
  Given(/^a directory called 'clean' containing two clean files$/) do
@@ -48,12 +48,10 @@ When(/^I run "reek (.*?)" in a subdirectory$/) do |args|
48
48
  reek(args)
49
49
  end
50
50
 
51
- Given(/^a configuration file '(.+)' in a subdirectory$/) do |filename|
52
- contents = CONFIGURATION_DIR.join(filename).read
53
-
54
- write_file("subdir/#{filename}", contents)
55
- end
56
-
57
51
  Then(/^it does not report private or protected methods$/) do
58
52
  # Pseudo step for feature clarity.
59
53
  end
54
+
55
+ Given('with a configuration file that is further up in the directory tree') do
56
+ # Pseudo step for feature clarity. We have an empty .reek.yml in our root directory already.
57
+ end
@@ -1,14 +1,11 @@
1
1
  Feature: Auto-generate a todo file
2
2
  Write a Reek configuration as a kind of todo list that will prevent Reek
3
- from reporting smells on the current code.
4
- This can then be worked on later on.
5
- The main goal here would be to ease the Reek adoption by allowing developers to:
6
- - introduce Reek right away (e.g. for CI)
7
- - exclude the "old" smells from getting reported
8
- - fix them step by step
9
- - get rid of the todo file
3
+ from reporting smells on the current code. This can then be worked on later on.
4
+ The main goal here would be to ease the Reek adoption by allowing developers to
5
+ introduce Reek right away (e.g. for CI), exclude the "old" smells from getting reported
6
+ and then fix them step by step.
10
7
 
11
- Scenario: Generate a proper todo file that disables all found smells
8
+ Scenario: Generate the default configuration file that disables all found smells
12
9
  Given the smelly file 'smelly.rb'
13
10
  When I run reek smelly.rb
14
11
  Then the exit status indicates smells
@@ -23,10 +20,10 @@ Feature: Auto-generate a todo file
23
20
  And it reports:
24
21
  """
25
22
 
26
- '.todo.reek' generated! You can now use this as a starting point for your configuration.
23
+ '.reek.yml' generated! You can now use this as a starting point.
27
24
  """
28
- And a file named ".todo.reek" should exist
29
- And the file ".todo.reek" should contain:
25
+ And a file named ".reek.yml" should exist
26
+ And the file ".reek.yml" should contain:
30
27
  """
31
28
  ---
32
29
  detectors:
@@ -37,48 +34,52 @@ Feature: Auto-generate a todo file
37
34
  exclude:
38
35
  - Smelly#x
39
36
  """
40
- When I run reek -c .todo.reek smelly.rb
37
+ When I run reek smelly.rb
41
38
  Then it succeeds
42
39
 
43
40
  Scenario: Reacts appropiately when there are no smells
44
- Given the clean file 'clean.rb'
41
+ Given the clean file "clean.rb"
45
42
  When I run reek --todo clean.rb
46
- Then a file named ".todo.reek" should not exist
43
+ Then a file named ".reek.yml" should not exist
47
44
  And it reports:
48
45
  """
49
46
 
50
- '.todo.reek' not generated because there were no smells found!
47
+ No smells found - nothing to do, exiting.
51
48
  """
52
49
 
53
- Scenario: Mercilessly overwrite existing .todo.reek files
50
+ Scenario: Don't overwrite existing .reek.yml files
54
51
  Given the smelly file 'smelly.rb'
55
- And a file named ".todo.reek" with:
52
+ And a file named ".reek.yml" with:
56
53
  """
57
54
  ---
58
55
  detectors:
59
- # smelly.rb reeks of UncommunicativeMethodName and UncommunicativeVariableName
60
- # so the configuration below will partially mask this
61
56
  UncommunicativeMethodName:
62
57
  enabled: false
63
58
  """
64
- When I run reek -c .todo.reek smelly.rb
59
+ When I run reek smelly.rb
65
60
  Then it reports:
66
61
  """
67
62
  smelly.rb -- 1 warning:
68
63
  [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
69
64
  """
70
65
  When I run reek --todo smelly.rb
71
- Then it succeeds
72
- When I run reek -c .todo.reek smelly.rb
73
- Then it reports nothing
66
+ Then it reports:
67
+ """
68
+
69
+ Existing '.reek.yml' detected - aborting.
70
+ """
71
+ When I run reek smelly.rb
72
+ Then it reports:
73
+ """
74
+ smelly.rb -- 1 warning:
75
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
76
+ """
74
77
 
75
78
  Scenario: Ignore existing other configuration files that are passed explicitly
76
79
  Given the smelly file 'smelly.rb'
77
80
  And a file named "config.reek" with:
78
81
  """
79
82
  ---
80
- # smelly.rb reeks of UncommunicativeMethodName and UncommunicativeVariableName
81
- # so the configuration below will partially mask this
82
83
  detectors:
83
84
  UncommunicativeMethodName:
84
85
  enabled: false
@@ -91,5 +92,17 @@ Feature: Auto-generate a todo file
91
92
  """
92
93
  When I run reek -c config.reek --todo smelly.rb
93
94
  Then it succeeds
94
- When I run reek -c .todo.reek smelly.rb
95
+ And a file named ".reek.yml" should exist
96
+ And the file ".reek.yml" should contain:
97
+ """
98
+ ---
99
+ detectors:
100
+ UncommunicativeMethodName:
101
+ exclude:
102
+ - Smelly#x
103
+ UncommunicativeVariableName:
104
+ exclude:
105
+ - Smelly#x
106
+ """
107
+ When I run reek smelly.rb
95
108
  Then it reports nothing
@@ -6,3 +6,10 @@
6
6
  require_relative 'reek/version'
7
7
  require_relative 'reek/examiner'
8
8
  require_relative 'reek/report'
9
+
10
+ module Reek
11
+ DEFAULT_CONFIGURATION_FILE_NAME = '.reek.yml'
12
+ DETECTORS_KEY = 'detectors'
13
+ EXCLUDE_PATHS_KEY = 'exclude_paths'
14
+ DIRECTORIES_KEY = 'directories'
15
+ end
@@ -102,6 +102,9 @@ module Reek
102
102
  loc.expression.source_buffer.name
103
103
  end
104
104
 
105
+ # Method will be overridden by the code in the IfNode, CaseNode, and LogicOperatorBase sexp extensions.
106
+ def condition; end
107
+
105
108
  protected
106
109
 
107
110
  # See ".each_node" for documentation.
@@ -119,6 +122,7 @@ module Reek
119
122
  def look_for_recurse(target_types, ignoring, &blk)
120
123
  yield self if target_types.include? type
121
124
  return if ignoring.include? type
125
+
122
126
  each_sexp do |elem|
123
127
  elem.look_for_recurse(target_types, ignoring, &blk)
124
128
  end
@@ -5,6 +5,26 @@ module Reek
5
5
  module SexpExtensions
6
6
  # Utility methods for :if nodes.
7
7
  module IfNode
8
+ #
9
+ # @return [Reek::AST::Node] the condition that is associated with a conditional node.
10
+ # For instance, this code
11
+ #
12
+ # if charlie(bravo) then delta end
13
+ #
14
+ # would be parsed into this AST:
15
+ #
16
+ # s(:if,
17
+ # s(:send, nil, :charlie,
18
+ # s(:lvar, :bravo)),
19
+ # s(:send, nil, :delta), nil)
20
+ #
21
+ # so in this case we would return this
22
+ #
23
+ # s(:send, nil, :charlie,
24
+ # s(:lvar, :bravo))
25
+ #
26
+ # as condition.
27
+ #
8
28
  def condition
9
29
  children.first
10
30
  end
@@ -32,6 +32,7 @@ module Reek
32
32
  def body_nodes(types, ignoring = [])
33
33
  return [] unless body
34
34
  return [] if ignoring.include?(body.type)
35
+
35
36
  body.each_node(types, ignoring | types)
36
37
  end
37
38
  end
@@ -3,6 +3,7 @@
3
3
  require_relative 'options'
4
4
  require_relative 'status'
5
5
  require_relative '../configuration/app_configuration'
6
+ require_relative '../configuration/configuration_file_finder'
6
7
  require_relative '../source/source_locator'
7
8
  require_relative 'command/report_command'
8
9
  require_relative 'command/todo_list_command'
@@ -27,6 +28,7 @@ module Reek
27
28
  end
28
29
 
29
30
  def execute
31
+ show_configuration_path
30
32
  command.execute
31
33
  end
32
34
 
@@ -48,6 +50,29 @@ module Reek
48
50
  exit Status::DEFAULT_ERROR_EXIT_CODE
49
51
  end
50
52
 
53
+ def show_configuration_path
54
+ return unless options.show_configuration_path
55
+
56
+ path = Configuration::ConfigurationFileFinder.find(path: options.config_file)
57
+ if path
58
+ puts "Using '#{path_relative_to_working_directory(path)}' as configuration file."
59
+ else
60
+ puts 'Not using any configuration file.'
61
+ end
62
+ end
63
+
64
+ # Returns the path that is relative to the current working directory given an absolute path.
65
+ # E.g. if the given absolute path is "/foo/bar/baz/.reek.yml" and your working directory is
66
+ # "/foo/bar" this method would return "baz/.reek.yml"
67
+ #
68
+ # @param path [String] Absolute path
69
+ # @return [Pathname], e.g. 'config/.reek.yml'
70
+ #
71
+ # :reek:UtilityFunction
72
+ def path_relative_to_working_directory(path)
73
+ Pathname(path).realpath.relative_path_from(Pathname.pwd)
74
+ end
75
+
51
76
  def command_class
52
77
  options.generate_todo_list ? Command::TodoListCommand : Command::ReportCommand
53
78
  end
@@ -12,17 +12,19 @@ module Reek
12
12
  # file that can serve as a todo list.
13
13
  #
14
14
  class TodoListCommand < BaseCommand
15
- FILE_NAME = '.todo.reek'
15
+ HEADER = "# Auto generated by Reeks --todo flag\n"
16
+ EXISTING_FILE_MESSAGE = "\nExisting '#{DEFAULT_CONFIGURATION_FILE_NAME}' detected - aborting.\n"
17
+ NO_SMELLS_FOUND_MESSAGE = "\nNo smells found - nothing to do, exiting.\n"
16
18
 
17
19
  def execute
18
20
  if smells.empty?
19
- puts "\n'.todo.reek' not generated because "\
20
- 'there were no smells found!'
21
+ puts NO_SMELLS_FOUND_MESSAGE
22
+ elsif File.exist?(DEFAULT_CONFIGURATION_FILE_NAME)
23
+ puts EXISTING_FILE_MESSAGE
21
24
  else
22
- File.write FILE_NAME,
23
- { Configuration::AppConfiguration::DETECTORS_KEY => groups }.to_yaml
24
- puts "\n'.todo.reek' generated! You can now use "\
25
- 'this as a starting point for your configuration.'
25
+ write_to_file
26
+ puts "\n'#{DEFAULT_CONFIGURATION_FILE_NAME}' generated! "\
27
+ 'You can now use this as a starting point.'
26
28
  end
27
29
  options.success_exit_code
28
30
  end
@@ -44,6 +46,14 @@ module Reek
44
46
  todos.inject(&:merge)
45
47
  end
46
48
  end
49
+
50
+ # :reek:FeatureEnvy
51
+ def write_to_file
52
+ File.open(DEFAULT_CONFIGURATION_FILE_NAME, 'w') do |configuration_file|
53
+ configuration_file.write HEADER
54
+ configuration_file.write({ DETECTORS_KEY => groups }.to_yaml)
55
+ end
56
+ end
47
57
  end
48
58
  end
49
59
  end
@@ -14,7 +14,7 @@ module Reek
14
14
  #
15
15
  # See {file:docs/Command-Line-Options.md} for details.
16
16
  #
17
- # @quality :reek:TooManyInstanceVariables { max_instance_variables: 12 }
17
+ # @quality :reek:TooManyInstanceVariables { max_instance_variables: 13 }
18
18
  # @quality :reek:TooManyMethods { max_methods: 18 }
19
19
  # @quality :reek:Attribute { enabled: false }
20
20
  #
@@ -32,21 +32,23 @@ module Reek
32
32
  :success_exit_code,
33
33
  :failure_exit_code,
34
34
  :generate_todo_list,
35
- :force_exclusion
35
+ :force_exclusion,
36
+ :show_configuration_path
36
37
 
37
38
  def initialize(argv = [])
38
- @argv = argv
39
- @parser = OptionParser.new
40
- @report_format = :text
41
- @location_format = :numbers
42
- @progress_format = tty_output? ? :dots : :quiet
43
- @show_links = true
44
- @smells_to_detect = []
45
- @colored = tty_output?
46
- @success_exit_code = Status::DEFAULT_SUCCESS_EXIT_CODE
47
- @failure_exit_code = Status::DEFAULT_FAILURE_EXIT_CODE
48
- @generate_todo_list = false
49
- @force_exclusion = false
39
+ @argv = argv
40
+ @parser = OptionParser.new
41
+ @report_format = :text
42
+ @location_format = :numbers
43
+ @progress_format = tty_output? ? :dots : :quiet
44
+ @show_links = true
45
+ @smells_to_detect = []
46
+ @colored = tty_output?
47
+ @success_exit_code = Status::DEFAULT_SUCCESS_EXIT_CODE
48
+ @failure_exit_code = Status::DEFAULT_FAILURE_EXIT_CODE
49
+ @generate_todo_list = false
50
+ @force_exclusion = false
51
+ @show_configuration_path = false
50
52
 
51
53
  set_up_parser
52
54
  end
@@ -153,6 +155,7 @@ module Reek
153
155
  end
154
156
  end
155
157
 
158
+ # @quality :reek:TooManyStatements { max_statements: 6 }
156
159
  def set_up_verbosity_options
157
160
  parser.on('-V', '--[no-]empty-headings',
158
161
  'Show headings for smell-free source files (default: false)') do |show_empty|
@@ -162,6 +165,10 @@ module Reek
162
165
  'Show link to related documentation page for each smell (default: true)') do |show_links|
163
166
  self.show_links = show_links
164
167
  end
168
+ parser.on(nil, '--[no-]show-configuration-path',
169
+ 'Show which configuration file Reek is using (default: false)') do |show_configuration_path|
170
+ self.show_configuration_path = show_configuration_path
171
+ end
165
172
  end
166
173
 
167
174
  def set_up_location_formatting_options