reek 5.0.2 → 5.1.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 (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