reek 6.1.3 → 6.2.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +4 -4
  3. data/.rubocop.yml +1 -9
  4. data/CHANGELOG.md +57 -0
  5. data/CONTRIBUTING.md +6 -9
  6. data/Gemfile +5 -4
  7. data/README.md +27 -27
  8. data/bin/code_climate_reek +54 -5
  9. data/lib/reek/ast/sexp_extensions/send.rb +21 -6
  10. data/lib/reek/cli/command/todo_list_command.rb +1 -1
  11. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.rb +1 -1
  12. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.yml +38 -38
  13. data/lib/reek/{report/code_climate → code_climate}/code_climate_fingerprint.rb +2 -2
  14. data/lib/reek/{report/code_climate → code_climate}/code_climate_formatter.rb +1 -1
  15. data/lib/reek/{report/code_climate → code_climate}/code_climate_report.rb +3 -3
  16. data/lib/reek/code_comment.rb +3 -3
  17. data/lib/reek/configuration/app_configuration.rb +5 -5
  18. data/lib/reek/configuration/configuration_converter.rb +1 -1
  19. data/lib/reek/configuration/configuration_file_finder.rb +3 -3
  20. data/lib/reek/configuration/default_directive.rb +1 -1
  21. data/lib/reek/configuration/directory_directives.rb +1 -1
  22. data/lib/reek/configuration/excluded_paths.rb +1 -1
  23. data/lib/reek/configuration/schema.rb +177 -0
  24. data/lib/reek/configuration/schema_validator.rb +12 -13
  25. data/lib/reek/context/attribute_context.rb +1 -1
  26. data/lib/reek/context/method_context.rb +1 -1
  27. data/lib/reek/context/send_context.rb +1 -1
  28. data/lib/reek/documentation_link.rb +3 -5
  29. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +2 -2
  30. data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -2
  31. data/lib/reek/errors/encoding_error.rb +1 -1
  32. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -2
  33. data/lib/reek/errors/incomprehensible_source_error.rb +1 -1
  34. data/lib/reek/errors/legacy_comment_separator_error.rb +2 -2
  35. data/lib/reek/errors/syntax_error.rb +1 -1
  36. data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +1 -1
  37. data/lib/reek/smell_detectors/instance_variable_assumption.rb +8 -8
  38. data/lib/reek/smell_detectors/nested_iterators.rb +4 -3
  39. data/lib/reek/smell_detectors/unused_private_method.rb +2 -2
  40. data/lib/reek/version.rb +1 -1
  41. data/reek.gemspec +4 -3
  42. metadata +30 -16
  43. data/lib/reek/configuration/schema.yml +0 -210
  44. /data/lib/reek/{report/code_climate.rb → code_climate.rb} +0 -0
@@ -10,7 +10,7 @@ Attribute:
10
10
 
11
11
  Given:
12
12
 
13
- ```Ruby
13
+ ```ruby
14
14
  class Klass
15
15
  attr_accessor :dummy
16
16
  end
@@ -33,7 +33,7 @@ BooleanParameter:
33
33
 
34
34
  Given
35
35
 
36
- ```Ruby
36
+ ```ruby
37
37
  class Dummy
38
38
  def hit_the_switch(switch = true)
39
39
  if switch
@@ -76,7 +76,7 @@ ClassVariable:
76
76
 
77
77
  Given
78
78
 
79
- ```Ruby
79
+ ```ruby
80
80
  class Dummy
81
81
  @@class_variable = :whatever
82
82
  end
@@ -95,7 +95,7 @@ ClassVariable:
95
95
 
96
96
  You can use class-instance variable to mitigate the problem (as also suggested in the linked article above):
97
97
 
98
- ```Ruby
98
+ ```ruby
99
99
  class Dummy
100
100
  @class_variable = :whatever
101
101
  end
@@ -109,7 +109,7 @@ ControlParameter:
109
109
 
110
110
  A simple example would be the "quoted" parameter in the following method:
111
111
 
112
- ```Ruby
112
+ ```ruby
113
113
  def write(quoted)
114
114
  if quoted
115
115
  write_quoted @value
@@ -131,7 +131,7 @@ DataClump:
131
131
 
132
132
  Given
133
133
 
134
- ```Ruby
134
+ ```ruby
135
135
  class Dummy
136
136
  def x(y1,y2); end
137
137
  def y(y1,y2); end
@@ -160,7 +160,7 @@ DuplicateMethodCall:
160
160
 
161
161
  Here's a very much simplified and contrived example. The following method will report a warning:
162
162
 
163
- ```Ruby
163
+ ```ruby
164
164
  def double_thing()
165
165
  @other.thing + @other.thing
166
166
  end
@@ -168,7 +168,7 @@ DuplicateMethodCall:
168
168
 
169
169
  One quick approach to silence Reek would be to refactor the code thus:
170
170
 
171
- ```Ruby
171
+ ```ruby
172
172
  def double_thing()
173
173
  thing = @other.thing
174
174
  thing + thing
@@ -177,7 +177,7 @@ DuplicateMethodCall:
177
177
 
178
178
  A slightly different approach would be to replace all calls of `double_thing` by calls to `@other.double_thing`:
179
179
 
180
- ```Ruby
180
+ ```ruby
181
181
  class Other
182
182
  def double_thing()
183
183
  thing + thing
@@ -201,7 +201,7 @@ FeatureEnvy:
201
201
 
202
202
  Running Reek on:
203
203
 
204
- ```Ruby
204
+ ```ruby
205
205
  class Warehouse
206
206
  def sale_price(item)
207
207
  (item.price - item.rebate) * @vat
@@ -211,13 +211,13 @@ FeatureEnvy:
211
211
 
212
212
  would report:
213
213
 
214
- ```Bash
214
+ ```bash
215
215
  Warehouse#total_price refers to item more than self (FeatureEnvy)
216
216
  ```
217
217
 
218
218
  since this:
219
219
 
220
- ```Ruby
220
+ ```ruby
221
221
  (item.price - item.rebate)
222
222
  ```
223
223
 
@@ -229,7 +229,7 @@ InstanceVariableAssumption:
229
229
 
230
230
  Good:
231
231
 
232
- ```Ruby
232
+ ```ruby
233
233
  class Foo
234
234
  def initialize
235
235
  @bar = :foo
@@ -243,7 +243,7 @@ InstanceVariableAssumption:
243
243
 
244
244
  Good as well:
245
245
 
246
- ```Ruby
246
+ ```ruby
247
247
  class Foo
248
248
  def foo?
249
249
  bar == :foo
@@ -257,7 +257,7 @@ InstanceVariableAssumption:
257
257
 
258
258
  Bad:
259
259
 
260
- ```Ruby
260
+ ```ruby
261
261
  class Foo
262
262
  def go_foo!
263
263
  @bar = :foo
@@ -273,7 +273,7 @@ InstanceVariableAssumption:
273
273
 
274
274
  Running Reek on:
275
275
 
276
- ```Ruby
276
+ ```ruby
277
277
  class Dummy
278
278
  def test
279
279
  @ivar
@@ -283,13 +283,13 @@ InstanceVariableAssumption:
283
283
 
284
284
  would report:
285
285
 
286
- ```Bash
286
+ ```bash
287
287
  [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar
288
288
  ```
289
289
 
290
290
  Note that this example would trigger this smell warning as well:
291
291
 
292
- ```Ruby
292
+ ```ruby
293
293
  class Parent
294
294
  def initialize(omg)
295
295
  @omg = omg
@@ -305,7 +305,7 @@ InstanceVariableAssumption:
305
305
 
306
306
  The way to address the smell warning is that you should create an `attr_reader` to use `@omg` in the subclass and not access `@omg` directly like this:
307
307
 
308
- ```Ruby
308
+ ```ruby
309
309
  class Parent
310
310
  attr_reader :omg
311
311
 
@@ -325,7 +325,7 @@ InstanceVariableAssumption:
325
325
 
326
326
  If you don't want to expose those methods as public API just make them private like this:
327
327
 
328
- ```Ruby
328
+ ```ruby
329
329
  class Parent
330
330
  def initialize(omg)
331
331
  @omg = omg
@@ -360,7 +360,7 @@ IrresponsibleModule:
360
360
 
361
361
  Given
362
362
 
363
- ```Ruby
363
+ ```ruby
364
364
  class Dummy
365
365
  # Do things...
366
366
  end
@@ -375,7 +375,7 @@ IrresponsibleModule:
375
375
 
376
376
  Fixing this is simple - just an explaining comment:
377
377
 
378
- ```Ruby
378
+ ```ruby
379
379
  # The Dummy class is responsible for ...
380
380
  class Dummy
381
381
  # Do things...
@@ -390,7 +390,7 @@ LongParameterList:
390
390
 
391
391
  Given
392
392
 
393
- ```Ruby
393
+ ```ruby
394
394
  class Dummy
395
395
  def long_list(foo,bar,baz,fling,flung)
396
396
  puts foo,bar,baz,fling,flung
@@ -413,7 +413,7 @@ LongYieldList:
413
413
 
414
414
  ## Example
415
415
 
416
- ```Ruby
416
+ ```ruby
417
417
  class Dummy
418
418
  def yields_a_lot(foo,bar,baz,fling,flung)
419
419
  yield foo,bar,baz,fling,flung
@@ -436,7 +436,7 @@ ManualDispatch:
436
436
 
437
437
  ## Example
438
438
 
439
- ```Ruby
439
+ ```ruby
440
440
  class MyManualDispatcher
441
441
  attr_reader :foo
442
442
 
@@ -467,7 +467,7 @@ ModuleInitialize:
467
467
 
468
468
  The `Foo` module below contains a method `initialize`. Although class `B` inherits from `A`, the inclusion of `Foo` stops `A#initialize` from being called.
469
469
 
470
- ```Ruby
470
+ ```ruby
471
471
  class A
472
472
  def initialize(a)
473
473
  @a = a
@@ -492,7 +492,7 @@ ModuleInitialize:
492
492
 
493
493
  A simple solution is to rename `Foo#initialize` and call that method by name:
494
494
 
495
- ```Ruby
495
+ ```ruby
496
496
  module Foo
497
497
  def setup_foo_module(foo)
498
498
  @foo = foo
@@ -518,7 +518,7 @@ NestedIterators:
518
518
 
519
519
  Given
520
520
 
521
- ```Ruby
521
+ ```ruby
522
522
  class Duck
523
523
  class << self
524
524
  def duck_names
@@ -549,7 +549,7 @@ NilCheck:
549
549
 
550
550
  Given
551
551
 
552
- ```Ruby
552
+ ```ruby
553
553
  class Klass
554
554
  def nil_checker(argument)
555
555
  if argument.nil?
@@ -582,7 +582,7 @@ MissingSafeMethod:
582
582
 
583
583
  Given
584
584
 
585
- ```Ruby
585
+ ```ruby
586
586
  class C
587
587
  def foo; end
588
588
  def foo!; end
@@ -595,7 +595,7 @@ MissingSafeMethod:
595
595
  Reek reports this smell only in a class context, not in a module context in order to allow perfectly legit code like this:
596
596
 
597
597
 
598
- ```Ruby
598
+ ```ruby
599
599
  class Parent
600
600
  def foo; end
601
601
  end
@@ -622,7 +622,7 @@ RepeatedConditional:
622
622
 
623
623
  Given
624
624
 
625
- ```Ruby
625
+ ```ruby
626
626
  class RepeatedConditionals
627
627
  attr_accessor :switch
628
628
 
@@ -664,7 +664,7 @@ TooManyInstanceVariables:
664
664
 
665
665
  and this code:
666
666
 
667
- ```Ruby
667
+ ```ruby
668
668
  class TooManyInstanceVariables
669
669
  def initialize
670
670
  @arg_1 = :dummy
@@ -697,7 +697,7 @@ TooManyConstants:
697
697
 
698
698
  and this code:
699
699
 
700
- ```Ruby
700
+ ```ruby
701
701
  class TooManyConstants
702
702
  CONST_1 = :dummy
703
703
  CONST_2 = :dummy
@@ -728,7 +728,7 @@ TooManyMethods:
728
728
 
729
729
  and this code:
730
730
 
731
- ```Ruby
731
+ ```ruby
732
732
  class TooManyMethods
733
733
  def one; end
734
734
  def two; end
@@ -752,7 +752,7 @@ TooManyStatements:
752
752
 
753
753
  So the following method would score +6 in Reek's statement-counting algorithm:
754
754
 
755
- ```Ruby
755
+ ```ruby
756
756
  def parse(arg, argv, &error)
757
757
  if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
758
758
  return nil, block, nil # +1
@@ -804,7 +804,7 @@ UnusedParameters:
804
804
 
805
805
  Given:
806
806
 
807
- ```Ruby
807
+ ```ruby
808
808
  class Klass
809
809
  def unused_parameters(x,y,z)
810
810
  puts x,y # but not z
@@ -830,7 +830,7 @@ UnusedPrivateMethod:
830
830
 
831
831
  Given:
832
832
 
833
- ```Ruby
833
+ ```ruby
834
834
  class Car
835
835
  private
836
836
  def drive; end
@@ -3,7 +3,7 @@
3
3
  require 'digest'
4
4
 
5
5
  module Reek
6
- module Report
6
+ module CodeClimate
7
7
  # Generates a string to uniquely identify a smell
8
8
  class CodeClimateFingerprint
9
9
  NON_IDENTIFYING_PARAMETERS = [:count, :depth].freeze
@@ -36,7 +36,7 @@ module Reek
36
36
  end
37
37
 
38
38
  def parameters
39
- warning.parameters.reject { |key, _| NON_IDENTIFYING_PARAMETERS.include?(key) }.sort.to_s
39
+ warning.parameters.except(*NON_IDENTIFYING_PARAMETERS).sort.to_s
40
40
  end
41
41
 
42
42
  def warning_uniquely_identifiable?
@@ -4,7 +4,7 @@ require 'codeclimate_engine'
4
4
  require_relative 'code_climate_configuration'
5
5
 
6
6
  module Reek
7
- module Report
7
+ module CodeClimate
8
8
  # Generates a hash in the structure specified by the Code Climate engine spec
9
9
  class CodeClimateFormatter
10
10
  def initialize(warning)
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base_report'
3
+ require_relative '../report/base_report'
4
4
  require_relative 'code_climate_formatter'
5
5
 
6
6
  module Reek
7
- module Report
7
+ module CodeClimate
8
8
  #
9
9
  # Displays a list of smells in Code Climate engine format
10
10
  # (https://github.com/codeclimate/spec/blob/master/SPEC.md)
11
11
  # JSON with empty array for 0 smells
12
12
  #
13
- class CodeClimateReport < BaseReport
13
+ class CodeClimateReport < Report::BaseReport
14
14
  def show(out = $stdout)
15
15
  smells.map do |smell|
16
16
  out.print CodeClimateFormatter.new(smell).render
@@ -19,8 +19,8 @@ module Reek
19
19
  (\w+) # smell detector e.g.: UncommunicativeVariableName
20
20
  (:?\s*) # separator
21
21
  (\{.*?\})? # details in hash style e.g.: { max_methods: 30 }
22
- /x.freeze
23
- SANITIZE_REGEX = /(#|\n|\s)+/.freeze # Matches '#', newlines and > 1 whitespaces.
22
+ /x
23
+ SANITIZE_REGEX = /(#|\n|\s)+/ # Matches '#', newlines and > 1 whitespaces.
24
24
  DISABLE_DETECTOR_CONFIGURATION = '{ enabled: false }'
25
25
  MINIMUM_CONTENT_LENGTH = 2
26
26
 
@@ -170,7 +170,7 @@ module Reek
170
170
 
171
171
  # @return [Set] the configuration keys that are found in the code comment
172
172
  def given_configuration_keys
173
- parsed_options.keys.map(&:to_sym).to_set
173
+ parsed_options.keys.to_set(&:to_sym)
174
174
  end
175
175
 
176
176
  # @return [String] all keys from the code comment that look bad
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
- require_relative './configuration_file_finder'
5
- require_relative './configuration_validator'
6
- require_relative './default_directive'
7
- require_relative './directory_directives'
8
- require_relative './excluded_paths'
4
+ require_relative 'configuration_file_finder'
5
+ require_relative 'configuration_validator'
6
+ require_relative 'default_directive'
7
+ require_relative 'directory_directives'
8
+ require_relative 'excluded_paths'
9
9
 
10
10
  module Reek
11
11
  module Configuration
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './configuration_validator'
3
+ require_relative 'configuration_validator'
4
4
 
5
5
  module Reek
6
6
  module Configuration
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
- require_relative './configuration_converter'
5
- require_relative './schema_validator'
4
+ require_relative 'configuration_converter'
5
+ require_relative 'schema_validator'
6
6
  require_relative '../errors/config_file_error'
7
7
 
8
8
  module Reek
@@ -58,11 +58,11 @@ module Reek
58
58
 
59
59
  begin
60
60
  configuration = YAML.load_file(path) || {}
61
+ SchemaValidator.new(configuration).validate
61
62
  rescue StandardError => error
62
63
  raise Errors::ConfigFileError, "Invalid configuration file #{path}, error is #{error}"
63
64
  end
64
65
 
65
- SchemaValidator.new(configuration).validate
66
66
  ConfigurationConverter.new(configuration).convert
67
67
  end
68
68
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './configuration_validator'
3
+ require_relative 'configuration_validator'
4
4
 
5
5
  module Reek
6
6
  module Configuration
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './configuration_validator'
3
+ require_relative 'configuration_validator'
4
4
 
5
5
  module Reek
6
6
  module Configuration
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './configuration_validator'
3
+ require_relative 'configuration_validator'
4
4
  require_relative '../errors/config_file_error'
5
5
 
6
6
  module Reek
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/schema'
4
+
5
+ module Reek
6
+ module Configuration
7
+ #
8
+ # Configuration schema constants.
9
+ #
10
+ class Schema
11
+ # Enable the :info extension so we can introspect
12
+ # your keys and types
13
+ Dry::Schema.load_extensions(:info)
14
+
15
+ # rubocop:disable Metrics/BlockLength
16
+ ALL_DETECTORS_SCHEMA = Dry::Schema.Params do
17
+ optional(:Attribute).filled(:hash) do
18
+ optional(:enabled).filled(:bool)
19
+ optional(:exclude).array(:string)
20
+ end
21
+ optional(:BooleanParameter).filled(:hash) do
22
+ optional(:enabled).filled(:bool)
23
+ optional(:exclude).array(:string)
24
+ end
25
+ optional(:ClassVariable).filled(:hash) do
26
+ optional(:enabled).filled(:bool)
27
+ optional(:exclude).array(:string)
28
+ end
29
+ optional(:ControlParameter).filled(:hash) do
30
+ optional(:enabled).filled(:bool)
31
+ optional(:exclude).array(:string)
32
+ end
33
+ optional(:DataClump).filled(:hash) do
34
+ optional(:enabled).filled(:bool)
35
+ optional(:exclude).array(:string)
36
+ optional(:max_copies).filled(:integer)
37
+ optional(:min_clump_size).filled(:integer)
38
+ end
39
+ optional(:DuplicateMethodCall).filled(:hash) do
40
+ optional(:enabled).filled(:bool)
41
+ optional(:exclude).array(:string)
42
+ optional(:max_calls).filled(:integer)
43
+ optional(:allow_calls).array(:string)
44
+ end
45
+ optional(:FeatureEnvy).filled(:hash) do
46
+ optional(:enabled).filled(:bool)
47
+ optional(:exclude).array(:string)
48
+ end
49
+ optional(:InstanceVariableAssumption).filled(:hash) do
50
+ optional(:enabled).filled(:bool)
51
+ optional(:exclude).array(:string)
52
+ end
53
+ optional(:IrresponsibleModule).filled(:hash) do
54
+ optional(:enabled).filled(:bool)
55
+ optional(:exclude).array(:string)
56
+ end
57
+ optional(:LongParameterList).filled(:hash) do
58
+ optional(:enabled).filled(:bool)
59
+ optional(:exclude).array(:string)
60
+ optional(:max_params).filled(:integer)
61
+ optional(:overrides).filled(:hash) do
62
+ required(:initialize).filled(:hash) do
63
+ required(:max_params).filled(:integer)
64
+ end
65
+ end
66
+ end
67
+ optional(:LongYieldList).filled(:hash) do
68
+ optional(:enabled).filled(:bool)
69
+ optional(:exclude).array(:string)
70
+ optional(:max_params).filled(:integer)
71
+ end
72
+ optional(:ManualDispatch).filled(:hash) do
73
+ optional(:enabled).filled(:bool)
74
+ optional(:exclude).array(:string)
75
+ end
76
+ optional(:MissingSafeMethod).filled(:hash) do
77
+ optional(:enabled).filled(:bool)
78
+ optional(:exclude).array(:string)
79
+ end
80
+ optional(:ModuleInitialize).filled(:hash) do
81
+ optional(:enabled).filled(:bool)
82
+ optional(:exclude).array(:string)
83
+ end
84
+ optional(:NestedIterators).filled(:hash) do
85
+ optional(:enabled).filled(:bool)
86
+ optional(:exclude).array(:string)
87
+ optional(:max_allowed_nesting).filled(:integer)
88
+ optional(:ignore_iterators) { array(:string) & filled? }
89
+ end
90
+ optional(:NilCheck).filled(:hash) do
91
+ optional(:enabled).filled(:bool)
92
+ optional(:exclude).array(:string)
93
+ end
94
+ optional(:RepeatedConditional).filled(:hash) do
95
+ optional(:enabled).filled(:bool)
96
+ optional(:exclude).array(:string)
97
+ optional(:max_ifs).filled(:integer)
98
+ end
99
+ optional(:SubclassedFromCoreClass).filled(:hash) do
100
+ optional(:enabled).filled(:bool)
101
+ optional(:exclude).array(:string)
102
+ end
103
+ optional(:TooManyConstants).filled(:hash) do
104
+ optional(:enabled).filled(:bool)
105
+ optional(:exclude).array(:string)
106
+ optional(:max_constants).filled(:integer)
107
+ end
108
+ optional(:TooManyInstanceVariables).filled(:hash) do
109
+ optional(:enabled).filled(:bool)
110
+ optional(:exclude).array(:string)
111
+ optional(:max_instance_variables).filled(:integer)
112
+ end
113
+ optional(:TooManyMethods).filled(:hash) do
114
+ optional(:enabled).filled(:bool)
115
+ optional(:exclude).array(:string)
116
+ optional(:max_methods).filled(:integer)
117
+ end
118
+ optional(:TooManyStatements).filled(:hash) do
119
+ optional(:enabled).filled(:bool)
120
+ optional(:exclude).array(:string)
121
+ optional(:max_statements).filled(:integer)
122
+ end
123
+ optional(:UncommunicativeMethodName).filled(:hash) do
124
+ optional(:enabled).filled(:bool)
125
+ optional(:exclude).array(:string)
126
+ optional(:reject).array(:string)
127
+ optional(:accept).array(:string)
128
+ end
129
+ optional(:UncommunicativeModuleName).filled(:hash) do
130
+ optional(:enabled).filled(:bool)
131
+ optional(:exclude).array(:string)
132
+ optional(:reject).array(:string)
133
+ optional(:accept).array(:string)
134
+ end
135
+ optional(:UncommunicativeParameterName).filled(:hash) do
136
+ optional(:enabled).filled(:bool)
137
+ optional(:exclude).array(:string)
138
+ optional(:reject).array(:string)
139
+ optional(:accept).array(:string)
140
+ end
141
+ optional(:UncommunicativeVariableName).filled(:hash) do
142
+ optional(:enabled).filled(:bool)
143
+ optional(:exclude).array(:string)
144
+ optional(:reject).array(:string)
145
+ optional(:accept).array(:string)
146
+ end
147
+ optional(:UnusedParameters).filled(:hash) do
148
+ optional(:enabled).filled(:bool)
149
+ optional(:exclude).array(:string)
150
+ end
151
+ optional(:UnusedPrivateMethod).filled(:hash) do
152
+ optional(:enabled).filled(:bool)
153
+ optional(:exclude).array(:string)
154
+ end
155
+ optional(:UtilityFunction).filled(:hash) do
156
+ optional(:enabled).filled(:bool)
157
+ optional(:exclude).array(:string)
158
+ optional(:public_methods_only).filled(:bool)
159
+ end
160
+ end
161
+ # rubocop:enable Metrics/BlockLength
162
+
163
+ # @quality :reek:TooManyStatements { max_statements: 7 }
164
+ def self.schema(directories = [])
165
+ Dry::Schema.Params do
166
+ config.validate_keys = true
167
+
168
+ optional(:detectors).filled(ALL_DETECTORS_SCHEMA)
169
+ optional(:directories).filled(:hash) do
170
+ directories.each { |dir| optional(dir.to_sym).filled(ALL_DETECTORS_SCHEMA) }
171
+ end
172
+ optional(:exclude_paths).array(:string)
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end