rubocop 0.73.0 → 0.74.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/console +1 -0
  4. data/config/default.yml +2 -1
  5. data/lib/rubocop.rb +3 -0
  6. data/lib/rubocop/ast/node.rb +1 -7
  7. data/lib/rubocop/config.rb +17 -537
  8. data/lib/rubocop/config_obsoletion.rb +201 -0
  9. data/lib/rubocop/config_validator.rb +239 -0
  10. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -53
  11. data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
  12. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  13. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +22 -40
  14. data/lib/rubocop/cop/lint/debugger.rb +0 -2
  15. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  16. data/lib/rubocop/cop/lint/erb_new_arguments.rb +56 -0
  17. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  18. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  19. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +6 -1
  20. data/lib/rubocop/cop/metrics/line_length.rb +6 -0
  21. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  22. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  23. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  24. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  25. data/lib/rubocop/cop/style/commented_keyword.rb +8 -28
  26. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -3
  27. data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
  28. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  29. data/lib/rubocop/cop/style/lambda.rb +0 -2
  30. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  31. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  32. data/lib/rubocop/path_util.rb +1 -1
  33. data/lib/rubocop/processed_source.rb +4 -0
  34. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  35. data/lib/rubocop/version.rb +1 -1
  36. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65d141c7453c4d515c8e6a54e88cbc82305193f9fdd078148939550973c06eef
4
- data.tar.gz: 78246e2ffa87ef9a0206e73227f323bfd9d1fdf97f565660c12f52854d2e75f0
3
+ metadata.gz: 7299e4e21bbddcdbfec2725fec41c384d50867b70a986d87ea0f6f7f08dd3ebe
4
+ data.tar.gz: 504dae598bbb526afed6bc9ecc56d86a27656d535bf52e30c85e7ab005af99f3
5
5
  SHA512:
6
- metadata.gz: 48f6c20451589a69ebf28b1dacb70193d9baa0b6a5c6a5f2c065c00df2a7df284575705ac65027f4884b0673d1b62babf862ad2c9bdb461f909c4b38cb15a138
7
- data.tar.gz: ea5877d8c872db2adf5f45e6613d01881227b7a22394c8e661fb41e78b5a9d75fb2662471a1876f287718092120ef2953105f27392c2a741273f9dd131544b29
6
+ metadata.gz: 57b94e3a5a06724249509077ada410188ad29b52ae6dfda9d8b56582cc08bdb443a60e75744abf0d2ac664b3124db18e3e5382f72ccacfd4be64faf2c489b0ae
7
+ data.tar.gz: fb563b7256b89462268c6b3dc4b5cbf626764d2a3097dc5a332187a78c4f7d9d0c80c6dd2ba83692d48ba354696467329a87acf25474261a24bd9bffcd42f35a
data/README.md CHANGED
@@ -52,7 +52,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
52
52
  might want to use a conservative version lock in your `Gemfile`:
53
53
 
54
54
  ```rb
55
- gem 'rubocop', '~> 0.73.0', require: false
55
+ gem 'rubocop', '~> 0.74.0', require: false
56
56
  ```
57
57
 
58
58
  ## Quickstart
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'bundler/setup'
4
5
  require 'pry'
5
6
  require 'rubocop'
6
7
 
@@ -1662,6 +1662,7 @@ Lint/UnneededSplatExpansion:
1662
1662
  Description: 'Checks for splat unnecessarily being called on literals.'
1663
1663
  Enabled: true
1664
1664
  VersionAdded: '0.43'
1665
+ VersionChanged: '0.74'
1665
1666
 
1666
1667
  Lint/UnreachableCode:
1667
1668
  Description: 'Unreachable code.'
@@ -3052,7 +3053,7 @@ Style/MultilineWhenThen:
3052
3053
  Description: 'Do not use then for multi-line when statement.'
3053
3054
  StyleGuide: '#no-then'
3054
3055
  Enabled: true
3055
- VersionAdded: '0.72'
3056
+ VersionAdded: '0.73'
3056
3057
 
3057
3058
  Style/MultipleComparison:
3058
3059
  Description: >-
@@ -122,6 +122,7 @@ require_relative 'rubocop/cop/mixin/ignored_pattern'
122
122
  require_relative 'rubocop/cop/mixin/ignored_methods'
123
123
  require_relative 'rubocop/cop/mixin/ignored_method_patterns'
124
124
  require_relative 'rubocop/cop/mixin/integer_node'
125
+ require_relative 'rubocop/cop/mixin/interpolation'
125
126
  require_relative 'rubocop/cop/mixin/match_range'
126
127
  require_relative 'rubocop/cop/mixin/method_complexity'
127
128
  require_relative 'rubocop/cop/mixin/method_preference'
@@ -586,7 +587,9 @@ require_relative 'rubocop/cached_data'
586
587
  require_relative 'rubocop/config'
587
588
  require_relative 'rubocop/config_loader_resolver'
588
589
  require_relative 'rubocop/config_loader'
590
+ require_relative 'rubocop/config_obsoletion'
589
591
  require_relative 'rubocop/config_store'
592
+ require_relative 'rubocop/config_validator'
590
593
  require_relative 'rubocop/target_finder'
591
594
  require_relative 'rubocop/token'
592
595
  require_relative 'rubocop/comment_config'
@@ -306,8 +306,6 @@ module RuboCop
306
306
  {(send $_ ...) (block (send $_ ...) ...)}
307
307
  PATTERN
308
308
 
309
- # Note: for masgn, #asgn_rhs will be an array node
310
- def_node_matcher :asgn_rhs, '[assignment? (... $_)]'
311
309
  def_node_matcher :str_content, '(str $_)'
312
310
 
313
311
  def const_name
@@ -480,7 +478,7 @@ module RuboCop
480
478
  end
481
479
 
482
480
  def_node_matcher :guard_clause?, <<~PATTERN
483
- [{(send nil? {:raise :fail} ...) return break next} single_line?]
481
+ [${(send nil? {:raise :fail} ...) return break next} single_line?]
484
482
  PATTERN
485
483
 
486
484
  def_node_matcher :proc?, <<~PATTERN
@@ -497,10 +495,6 @@ module RuboCop
497
495
  (block (send (const nil? {:Class :Module}) :new ...) ...)}
498
496
  PATTERN
499
497
 
500
- def_node_matcher :module_definition?, <<~PATTERN
501
- {class module (casgn _ _ class_constructor?)}
502
- PATTERN
503
-
504
498
  # Some expressions are evaluated for their value, some for their side
505
499
  # effects, and some for both
506
500
  # If we know that an expression is useful only for its side effects, that
@@ -8,237 +8,12 @@ module RuboCop
8
8
  # file from which it was read. Several different Configs can be used
9
9
  # during a run of the rubocop program, if files in several
10
10
  # directories are inspected.
11
-
12
- # rubocop:disable Metrics/ClassLength
13
11
  class Config
14
12
  include PathUtil
15
13
  include FileFinder
14
+ extend Forwardable
16
15
 
17
- COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
18
- AutoCorrect StyleGuide Details].freeze
19
- INTERNAL_PARAMS = %w[Description StyleGuide VersionAdded
20
- VersionChanged Reference Safe SafeAutoCorrect].freeze
21
-
22
- # 2.3 is the oldest officially supported Ruby version.
23
- DEFAULT_RUBY_VERSION = 2.3
24
- KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
25
- OBSOLETE_RUBIES = {
26
- 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
27
- }.freeze
28
- RUBY_VERSION_FILENAME = '.ruby-version'
29
16
  DEFAULT_RAILS_VERSION = 5.0
30
- OBSOLETE_COPS = {
31
- 'Style/FlipFlop' =>
32
- 'The `Style/FlipFlop` cop has been moved to `Lint/FlipFlop`.',
33
- 'Style/TrailingComma' =>
34
- 'The `Style/TrailingComma` cop no longer exists. Please use ' \
35
- '`Style/TrailingCommaInArguments`, ' \
36
- '`Style/TrailingCommaInArrayLiteral`, and/or ' \
37
- '`Style/TrailingCommaInHashLiteral` instead.',
38
- 'Style/TrailingCommaInLiteral' =>
39
- 'The `Style/TrailingCommaInLiteral` cop no longer exists. Please use ' \
40
- '`Style/TrailingCommaInArrayLiteral` and/or ' \
41
- '`Style/TrailingCommaInHashLiteral` instead.',
42
- 'Rails/DefaultScope' =>
43
- 'The `Rails/DefaultScope` cop no longer exists.',
44
- 'Lint/InvalidCharacterLiteral' =>
45
- 'The `Lint/InvalidCharacterLiteral` cop has been removed since it ' \
46
- 'was never being actually triggered.',
47
- 'Style/SingleSpaceBeforeFirstArg' =>
48
- 'The `Style/SingleSpaceBeforeFirstArg` cop has been renamed to ' \
49
- '`Layout/SpaceBeforeFirstArg`.',
50
- 'Lint/RescueWithoutErrorClass' =>
51
- 'The `Lint/RescueWithoutErrorClass` cop has been replaced by ' \
52
- '`Style/RescueStandardError`.',
53
- 'Lint/SpaceBeforeFirstArg' =>
54
- 'The `Lint/SpaceBeforeFirstArg` cop has been removed, since it was a ' \
55
- 'duplicate of `Layout/SpaceBeforeFirstArg`. Please use ' \
56
- '`Layout/SpaceBeforeFirstArg` instead.',
57
- 'Layout/FirstParameterIndentation' =>
58
- 'The `Layout/FirstParameterIndentation` cop has been renamed to ' \
59
- '`Layout/IndentFirstArgument`.',
60
- 'Layout/IndentArray' =>
61
- 'The `Layout/IndentArray` cop has been renamed to ' \
62
- '`Layout/IndentFirstArrayElement`.',
63
- 'Layout/IndentHash' =>
64
- 'The `Layout/IndentHash` cop has been renamed to ' \
65
- '`Layout/IndentFirstHashElement`.',
66
- 'Layout/SpaceAfterControlKeyword' =>
67
- 'The `Layout/SpaceAfterControlKeyword` cop has been removed. Please ' \
68
- 'use `Layout/SpaceAroundKeyword` instead.',
69
- 'Layout/SpaceBeforeModifierKeyword' =>
70
- 'The `Layout/SpaceBeforeModifierKeyword` cop has been removed. ' \
71
- 'Please use `Layout/SpaceAroundKeyword` instead.',
72
- 'Style/SpaceAfterControlKeyword' =>
73
- 'The `Style/SpaceAfterControlKeyword` cop has been removed. Please ' \
74
- 'use `Layout/SpaceAroundKeyword` instead.',
75
- 'Style/SpaceBeforeModifierKeyword' =>
76
- 'The `Style/SpaceBeforeModifierKeyword` cop has been removed. Please ' \
77
- 'use `Layout/SpaceAroundKeyword` instead.',
78
- 'Style/MethodCallParentheses' =>
79
- 'The `Style/MethodCallParentheses` cop has been renamed to ' \
80
- '`Style/MethodCallWithoutArgsParentheses`.',
81
- 'Lint/Eval' =>
82
- 'The `Lint/Eval` cop has been renamed to `Security/Eval`.',
83
- 'Style/DeprecatedHashMethods' =>
84
- 'The `Style/DeprecatedHashMethods` cop has been renamed to ' \
85
- '`Style/PreferredHashMethods`.',
86
- 'Style/AccessorMethodName' =>
87
- 'The `Style/AccessorMethodName` cop has been moved to ' \
88
- '`Naming/AccessorMethodName`.',
89
- 'Style/AsciiIdentifiers' =>
90
- 'The `Style/AsciiIdentifiers` cop has been moved to ' \
91
- '`Naming/AccessorMethodName`.',
92
- 'Style/OpMethod' =>
93
- 'The `Style/OpMethod` cop has been renamed and moved to ' \
94
- '`Naming/BinaryOperatorParameterName`.',
95
- 'Style/ClassAndModuleCamelCase' =>
96
- 'The `Style/ClassAndModuleCamelCase` cop has been renamed to ' \
97
- '`Naming/ClassAndModuleCamelCase`.',
98
- 'Style/ConstantName' =>
99
- 'The `Style/ConstantName` cop has been renamed to ' \
100
- '`Naming/ConstantName`.',
101
- 'Style/FileName' =>
102
- 'The `Style/FileName` cop has been renamed to `Naming/FileName`.',
103
- 'Style/MethodName' =>
104
- 'The `Style/MethodName` cop has been renamed to ' \
105
- '`Naming/MethodName`.',
106
- 'Style/PredicateName' =>
107
- 'The `Style/PredicateName` cop has been renamed to ' \
108
- '`Naming/PredicateName`.',
109
- 'Style/VariableName' =>
110
- 'The `Style/VariableName` cop has been renamed to ' \
111
- '`Naming/VariableName`.',
112
- 'Style/VariableNumber' =>
113
- 'The `Style/VariableNumber` cop has been renamed to ' \
114
- '`Naming/VariableNumber`.',
115
- 'Lint/BlockAlignment' =>
116
- 'The `Lint/BlockAlignment` cop has been renamed to ' \
117
- '`Layout/BlockAlignment`.',
118
- 'Lint/EndAlignment' =>
119
- 'The `Lint/EndAlignment` cop has been renamed to ' \
120
- '`Layout/EndAlignment`.',
121
- 'Lint/DefEndAlignment' =>
122
- 'The `Lint/DefEndAlignment` cop has been renamed to ' \
123
- '`Layout/DefEndAlignment`.',
124
- 'Style/MethodMissing' =>
125
- 'The `Style/MethodMissing` cop has been split into ' \
126
- '`Style/MethodMissingSuper` and `Style/MissingRespondToMissing`.'
127
- }.freeze
128
-
129
- OBSOLETE_PARAMETERS = [
130
- {
131
- cop: 'Layout/SpaceAroundOperators',
132
- parameter: 'MultiSpaceAllowedForOperators',
133
- alternative: 'If your intention was to allow extra spaces ' \
134
- 'for alignment, please use AllowForAlignment: ' \
135
- 'true instead.'
136
- },
137
- {
138
- cop: 'Style/Encoding',
139
- parameter: 'EnforcedStyle',
140
- alternative: 'Style/Encoding no longer supports styles. ' \
141
- 'The "never" behavior is always assumed.'
142
- },
143
- {
144
- cop: 'Style/Encoding',
145
- parameter: 'SupportedStyles',
146
- alternative: 'Style/Encoding no longer supports styles. ' \
147
- 'The "never" behavior is always assumed.'
148
- },
149
- {
150
- cop: 'Style/Encoding',
151
- parameter: 'AutoCorrectEncodingComment',
152
- alternative: 'Style/Encoding no longer supports styles. ' \
153
- 'The "never" behavior is always assumed.'
154
- },
155
- {
156
- cop: 'Style/IfUnlessModifier',
157
- parameter: 'MaxLineLength',
158
- alternative:
159
- '`Style/IfUnlessModifier: MaxLineLength` has been removed. Use ' \
160
- '`Metrics/LineLength: Max` instead'
161
- },
162
- {
163
- cop: 'Style/SpaceAroundOperators',
164
- parameter: 'MultiSpaceAllowedForOperators',
165
- alternative: 'If your intention was to allow extra spaces ' \
166
- 'for alignment, please use AllowForAlignment: ' \
167
- 'true instead.'
168
- },
169
- {
170
- cop: 'Style/WhileUntilModifier',
171
- parameter: 'MaxLineLength',
172
- alternative:
173
- '`Style/WhileUntilModifier: MaxLineLength` has been removed. Use ' \
174
- '`Metrics/LineLength: Max` instead'
175
- },
176
- {
177
- cop: 'AllCops',
178
- parameter: 'RunRailsCops',
179
- alternative: "Use the following configuration instead:\n" \
180
- "Rails:\n Enabled: true"
181
- },
182
- {
183
- cop: 'Layout/CaseIndentation',
184
- parameter: 'IndentWhenRelativeTo',
185
- alternative: '`IndentWhenRelativeTo` has been renamed to ' \
186
- '`EnforcedStyle`'
187
- },
188
- {
189
- cop: 'Lint/BlockAlignment',
190
- parameter: 'AlignWith',
191
- alternative: '`AlignWith` has been renamed to ' \
192
- '`EnforcedStyleAlignWith`'
193
- },
194
- {
195
- cop: 'Layout/BlockAlignment',
196
- parameter: 'AlignWith',
197
- alternative: '`AlignWith` has been renamed to ' \
198
- '`EnforcedStyleAlignWith`'
199
- },
200
- {
201
- cop: 'Lint/EndAlignment',
202
- parameter: 'AlignWith',
203
- alternative: '`AlignWith` has been renamed to ' \
204
- '`EnforcedStyleAlignWith`'
205
- },
206
- {
207
- cop: 'Layout/EndAlignment',
208
- parameter: 'AlignWith',
209
- alternative: '`AlignWith` has been renamed to ' \
210
- '`EnforcedStyleAlignWith`'
211
- },
212
- {
213
- cop: 'Lint/DefEndAlignment',
214
- parameter: 'AlignWith',
215
- alternative: '`AlignWith` has been renamed to ' \
216
- '`EnforcedStyleAlignWith`'
217
- },
218
- {
219
- cop: 'Layout/DefEndAlignment',
220
- parameter: 'AlignWith',
221
- alternative: '`AlignWith` has been renamed to ' \
222
- '`EnforcedStyleAlignWith`'
223
- },
224
- {
225
- cop: 'Rails/UniqBeforePluck',
226
- parameter: 'EnforcedMode',
227
- alternative: '`EnforcedMode` has been renamed to ' \
228
- '`EnforcedStyle`'
229
- }
230
- ].freeze
231
-
232
- OBSOLETE_ENFORCED_STYLES = [
233
- {
234
- cop: 'Layout/IndentationConsistency',
235
- parameter: 'EnforcedStyle',
236
- enforced_style: 'rails',
237
- alternative: '`EnforcedStyle: rails` has been renamed to ' \
238
- '`EnforcedStyle: indented_internal_methods`'
239
- }
240
- ].freeze
241
-
242
17
  attr_reader :loaded_path
243
18
 
244
19
  def initialize(hash = {}, loaded_path = nil)
@@ -250,6 +25,7 @@ module RuboCop
250
25
  h[cop] = cop_options
251
26
  end
252
27
  @hash = hash
28
+ @validator = ConfigValidator.new(self)
253
29
  end
254
30
 
255
31
  def self.create(hash, path)
@@ -260,54 +36,14 @@ module RuboCop
260
36
  deprecation_check do |deprecation_message|
261
37
  warn("#{loaded_path} - #{deprecation_message}")
262
38
  end
263
- validate
39
+ @validator.validate
264
40
  make_excludes_absolute
265
41
  self
266
42
  end
267
43
 
268
- def [](key)
269
- @hash[key]
270
- end
271
-
272
- def []=(key, value)
273
- @hash[key] = value
274
- end
275
-
276
- def delete(key)
277
- @hash.delete(key)
278
- end
279
-
280
- def each(&block)
281
- @hash.each(&block)
282
- end
283
-
284
- def key?(key)
285
- @hash.key?(key)
286
- end
287
-
288
- def keys
289
- @hash.keys
290
- end
291
-
292
- def each_key(&block)
293
- @hash.each_key(&block)
294
- end
295
-
296
- def map(&block)
297
- @hash.map(&block)
298
- end
299
-
300
- def merge(other_hash)
301
- @hash.merge(other_hash)
302
- end
303
-
304
- def to_h
305
- @hash
306
- end
307
-
308
- def to_hash
309
- @hash
310
- end
44
+ def_delegators :@hash, :[], :[]=, :delete, :each, :key?, :keys, :each_key,
45
+ :map, :merge, :to_h, :to_hash
46
+ def_delegators :@validator, :validate, :target_ruby_version
311
47
 
312
48
  def to_s
313
49
  @to_s ||= @hash.to_s
@@ -319,7 +55,7 @@ module RuboCop
319
55
 
320
56
  def make_excludes_absolute
321
57
  each_key do |key|
322
- validate_section_presence(key)
58
+ @validator.validate_section_presence(key)
323
59
  next unless self[key]['Exclude']
324
60
 
325
61
  self[key]['Exclude'].map! do |exclude_elem|
@@ -364,25 +100,6 @@ module RuboCop
364
100
  @for_all_cops ||= self['AllCops'] || {}
365
101
  end
366
102
 
367
- def validate
368
- # Don't validate RuboCop's own files. Avoids infinite recursion.
369
- base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
370
- 'config'))
371
- return if File.expand_path(loaded_path).start_with?(base_config_path)
372
-
373
- valid_cop_names, invalid_cop_names = keys.partition do |key|
374
- ConfigLoader.default_configuration.key?(key)
375
- end
376
-
377
- reject_obsolete_cops_and_parameters
378
- warn_about_unrecognized_cops(invalid_cop_names)
379
- check_target_ruby
380
- validate_parameter_names(valid_cop_names)
381
- validate_enforced_styles(valid_cop_names)
382
- validate_syntax_cop
383
- reject_mutually_exclusive_defaults
384
- end
385
-
386
103
  def file_to_include?(file)
387
104
  relative_file_path = path_relative_to_config(file)
388
105
 
@@ -461,26 +178,6 @@ module RuboCop
461
178
  end
462
179
  end
463
180
 
464
- def target_ruby_version
465
- @target_ruby_version ||= begin
466
- if for_all_cops['TargetRubyVersion']
467
- @target_ruby_version_source = :rubocop_yml
468
-
469
- for_all_cops['TargetRubyVersion'].to_f
470
- elsif target_ruby_version_from_version_file
471
- @target_ruby_version_source = :ruby_version_file
472
-
473
- target_ruby_version_from_version_file
474
- elsif target_ruby_version_from_bundler_lock_file
475
- @target_ruby_version_source = :bundler_lock_file
476
-
477
- target_ruby_version_from_bundler_lock_file
478
- else
479
- DEFAULT_RUBY_VERSION
480
- end
481
- end
482
- end
483
-
484
181
  def target_rails_version
485
182
  @target_rails_version ||=
486
183
  if for_all_cops['TargetRailsVersion']
@@ -492,214 +189,22 @@ module RuboCop
492
189
  end
493
190
  end
494
191
 
495
- private
496
-
497
- def warn_about_unrecognized_cops(invalid_cop_names)
498
- invalid_cop_names.each do |name|
499
- # There could be a custom cop with this name. If so, don't warn
500
- next if Cop::Cop.registry.contains_cop_matching?([name])
501
-
502
- # Special case for inherit_mode, which is a directive that we keep in
503
- # the configuration (even though it's not a cop), because it's easier
504
- # to do so than to pass the value around to various methods.
505
- next if name == 'inherit_mode'
506
-
507
- warn Rainbow("Warning: unrecognized cop #{name} found in " \
508
- "#{smart_loaded_path}").yellow
509
- end
510
- end
511
-
512
- def validate_syntax_cop
513
- syntax_config = self['Lint/Syntax']
514
- default_config = ConfigLoader.default_configuration['Lint/Syntax']
515
-
516
- return unless syntax_config &&
517
- default_config.merge(syntax_config) != default_config
518
-
519
- raise ValidationError,
520
- "configuration for Syntax cop found in #{smart_loaded_path}\n" \
521
- 'It\'s not possible to disable this cop.'
522
- end
523
-
524
- def validate_section_presence(name)
525
- return unless key?(name) && self[name].nil?
526
-
527
- raise ValidationError,
528
- "empty section #{name} found in #{smart_loaded_path}"
529
- end
530
-
531
- def validate_parameter_names(valid_cop_names)
532
- valid_cop_names.each do |name|
533
- validate_section_presence(name)
534
- default_config = ConfigLoader.default_configuration[name]
535
-
536
- self[name].each_key do |param|
537
- next if COMMON_PARAMS.include?(param) || default_config.key?(param)
538
-
539
- message =
540
- "Warning: #{name} does not support #{param} parameter.\n\n" \
541
- "Supported parameters are:\n\n" \
542
- " - #{(default_config.keys - INTERNAL_PARAMS).join("\n - ")}\n"
543
-
544
- warn Rainbow(message).yellow.to_s
545
- end
546
- end
547
- end
548
-
549
- def validate_enforced_styles(valid_cop_names)
550
- valid_cop_names.each do |name|
551
- styles = self[name].select { |key, _| key.start_with?('Enforced') }
552
-
553
- styles.each do |style_name, style|
554
- supported_key = RuboCop::Cop::Util.to_supported_styles(style_name)
555
- valid = ConfigLoader.default_configuration[name][supported_key]
556
-
557
- next unless valid
558
- next if valid.include?(style)
559
- next if validate_support_and_has_list(name, style, valid)
560
-
561
- msg = "invalid #{style_name} '#{style}' for #{name} found in " \
562
- "#{smart_loaded_path}\n" \
563
- "Valid choices are: #{valid.join(', ')}"
564
- raise ValidationError, msg
565
- end
566
- end
567
- end
568
-
569
- def validate_support_and_has_list(name, formats, valid)
570
- ConfigLoader.default_configuration[name]['AllowMultipleStyles'] &&
571
- formats.is_a?(Array) &&
572
- formats.all? { |format| valid.include?(format) }
573
- end
574
-
575
- def reject_obsolete_cops_and_parameters
576
- messages = [
577
- obsolete_cops,
578
- obsolete_parameters,
579
- obsolete_enforced_style
580
- ].flatten.compact
581
- return if messages.empty?
582
-
583
- raise ValidationError, messages.join("\n")
584
- end
585
-
586
- def obsolete_parameters
587
- OBSOLETE_PARAMETERS.map do |params|
588
- obsolete_parameter_message(params[:cop], params[:parameter],
589
- params[:alternative])
590
- end
591
- end
592
-
593
- def obsolete_parameter_message(cop, parameter, alternative)
594
- return unless self[cop]&.key?(parameter)
595
-
596
- "obsolete parameter #{parameter} (for #{cop}) " \
597
- "found in #{smart_loaded_path}" \
598
- "\n#{alternative}"
599
- end
600
-
601
- def obsolete_cops
602
- OBSOLETE_COPS.map do |cop_name, message|
603
- next unless key?(cop_name) || key?(Cop::Badge.parse(cop_name).cop_name)
604
-
605
- message + "\n(obsolete configuration found in #{smart_loaded_path}," \
606
- ' please update it)'
607
- end
608
- end
609
-
610
- def obsolete_enforced_style
611
- OBSOLETE_ENFORCED_STYLES.map do |params|
612
- obsolete_enforced_style_message(params[:cop], params[:parameter],
613
- params[:enforced_style],
614
- params[:alternative])
615
- end
616
- end
617
-
618
- def obsolete_enforced_style_message(cop, param, enforced_style, alternative)
619
- style = self[cop]&.detect { |key, _| key.start_with?(param) }
620
-
621
- return unless style && style[1] == enforced_style
622
-
623
- "obsolete `#{param}: #{enforced_style}` (for #{cop}) " \
624
- "found in #{smart_loaded_path}" \
625
- "\n#{alternative}"
192
+ def smart_loaded_path
193
+ PathUtil.smart_path(@loaded_path)
626
194
  end
627
195
 
628
- def check_target_ruby
629
- return if KNOWN_RUBIES.include?(target_ruby_version)
630
-
631
- msg = if OBSOLETE_RUBIES.include?(target_ruby_version)
632
- "RuboCop found unsupported Ruby version #{target_ruby_version} " \
633
- "in #{target_ruby_source}. #{target_ruby_version}-compatible " \
634
- 'analysis was dropped after version ' \
635
- "#{OBSOLETE_RUBIES[target_ruby_version]}."
636
- else
637
- 'RuboCop found unknown Ruby version ' \
638
- "#{target_ruby_version.inspect} in #{target_ruby_source}."
639
- end
640
-
641
- msg += "\nSupported versions: #{KNOWN_RUBIES.join(', ')}"
642
-
643
- raise ValidationError, msg
644
- end
196
+ def bundler_lock_file_path
197
+ return nil unless loaded_path
645
198
 
646
- def target_ruby_source
647
- case @target_ruby_version_source
648
- when :ruby_version_file
649
- "`#{RUBY_VERSION_FILENAME}`"
650
- when :bundler_lock_file
651
- "`#{bundler_lock_file_path}`"
652
- when :rubocop_yml
653
- "`TargetRubyVersion` parameter (in #{smart_loaded_path})"
199
+ base_path = base_dir_for_path_parameters
200
+ ['gems.locked', 'Gemfile.lock'].each do |file_name|
201
+ path = find_file_upwards(file_name, base_path)
202
+ return path if path
654
203
  end
204
+ nil
655
205
  end
656
206
 
657
- def ruby_version_file
658
- @ruby_version_file ||=
659
- find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
660
- end
661
-
662
- def target_ruby_version_from_version_file
663
- file = ruby_version_file
664
- return unless file && File.file?(file)
665
-
666
- @target_ruby_version_from_version_file ||=
667
- File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
668
- md[:version].to_f
669
- end
670
- end
671
-
672
- def target_ruby_version_from_bundler_lock_file
673
- @target_ruby_version_from_bundler_lock_file ||=
674
- read_ruby_version_from_bundler_lock_file
675
- end
676
-
677
- def read_ruby_version_from_bundler_lock_file
678
- lock_file_path = bundler_lock_file_path
679
- return nil unless lock_file_path
680
-
681
- in_ruby_section = false
682
- File.foreach(lock_file_path) do |line|
683
- # If ruby is in Gemfile.lock or gems.lock, there should be two lines
684
- # towards the bottom of the file that look like:
685
- # RUBY VERSION
686
- # ruby W.X.YpZ
687
- # We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
688
- # extra logic to make sure we only start looking once we've seen the
689
- # "RUBY VERSION" line.
690
- in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
691
- next unless in_ruby_section
692
-
693
- # We currently only allow this feature to work with MRI ruby. If jruby
694
- # (or something else) is used by the project, it's lock file will have a
695
- # line that looks like:
696
- # RUBY VERSION
697
- # ruby W.X.YpZ (jruby x.x.x.x)
698
- # The regex won't match in this situation.
699
- result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
700
- return result.captures.first.to_f if result
701
- end
702
- end
207
+ private
703
208
 
704
209
  def target_rails_version_from_bundler_lock_file
705
210
  @target_rails_version_from_bundler_lock_file ||=
@@ -718,26 +223,6 @@ module RuboCop
718
223
  end
719
224
  end
720
225
 
721
- def bundler_lock_file_path
722
- return nil unless loaded_path
723
-
724
- base_path = base_dir_for_path_parameters
725
- ['gems.locked', 'Gemfile.lock'].each do |file_name|
726
- path = find_file_upwards(file_name, base_path)
727
- return path if path
728
- end
729
- nil
730
- end
731
-
732
- def reject_mutually_exclusive_defaults
733
- disabled_by_default = for_all_cops['DisabledByDefault']
734
- enabled_by_default = for_all_cops['EnabledByDefault']
735
- return unless disabled_by_default && enabled_by_default
736
-
737
- msg = 'Cops cannot be both enabled by default and disabled by default'
738
- raise ValidationError, msg
739
- end
740
-
741
226
  def enable_cop?(qualified_cop_name, cop_options)
742
227
  cop_department, cop_name = qualified_cop_name.split('/')
743
228
  department = cop_name.nil?
@@ -751,10 +236,5 @@ module RuboCop
751
236
 
752
237
  cop_options.fetch('Enabled') { !for_all_cops['DisabledByDefault'] }
753
238
  end
754
-
755
- def smart_loaded_path
756
- PathUtil.smart_path(@loaded_path)
757
- end
758
239
  end
759
- # rubocop:enable Metrics/ClassLength
760
240
  end