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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/console +1 -0
- data/config/default.yml +2 -1
- data/lib/rubocop.rb +3 -0
- data/lib/rubocop/ast/node.rb +1 -7
- data/lib/rubocop/config.rb +17 -537
- data/lib/rubocop/config_obsoletion.rb +201 -0
- data/lib/rubocop/config_validator.rb +239 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +14 -53
- data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
- data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +22 -40
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +56 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +6 -1
- data/lib/rubocop/cop/metrics/line_length.rb +6 -0
- data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +8 -28
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -3
- data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
- data/lib/rubocop/cop/style/guard_clause.rb +39 -10
- data/lib/rubocop/cop/style/lambda.rb +0 -2
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
- data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/processed_source.rb +4 -0
- data/lib/rubocop/rspec/expect_offense.rb +4 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7299e4e21bbddcdbfec2725fec41c384d50867b70a986d87ea0f6f7f08dd3ebe
|
4
|
+
data.tar.gz: 504dae598bbb526afed6bc9ecc56d86a27656d535bf52e30c85e7ab005af99f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
55
|
+
gem 'rubocop', '~> 0.74.0', require: false
|
56
56
|
```
|
57
57
|
|
58
58
|
## Quickstart
|
data/bin/console
CHANGED
data/config/default.yml
CHANGED
@@ -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.
|
3056
|
+
VersionAdded: '0.73'
|
3056
3057
|
|
3057
3058
|
Style/MultipleComparison:
|
3058
3059
|
Description: >-
|
data/lib/rubocop.rb
CHANGED
@@ -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'
|
data/lib/rubocop/ast/node.rb
CHANGED
@@ -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
|
data/lib/rubocop/config.rb
CHANGED
@@ -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
|
-
|
269
|
-
|
270
|
-
|
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
|
-
|
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
|
629
|
-
return
|
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
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
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
|
-
|
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
|