reek 6.1.4 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
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 +53 -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 +3 -2
  42. metadata +28 -14
  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