rubocop 1.40.0 → 1.43.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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +52 -2
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +34 -11
- data/lib/rubocop/config_loader.rb +9 -0
- data/lib/rubocop/config_loader_resolver.rb +5 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +83 -66
- data/lib/rubocop/cop/commissioner.rb +8 -3
- data/lib/rubocop/cop/cop.rb +29 -29
- data/lib/rubocop/cop/corrector.rb +23 -11
- data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +32 -11
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
- data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -5
- data/lib/rubocop/cop/layout/line_length.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -4
- data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +19 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -19
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +71 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -3
- data/lib/rubocop/cop/metrics/class_length.rb +1 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -4
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -2
- data/lib/rubocop/cop/mixin/line_length_help.rb +8 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
- data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/require_library.rb +2 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
- data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
- data/lib/rubocop/cop/registry.rb +28 -25
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/alias.rb +9 -1
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +86 -0
- data/lib/rubocop/cop/style/documentation.rb +11 -5
- data/lib/rubocop/cop/style/guard_clause.rb +17 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +13 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +11 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
- data/lib/rubocop/cop/style/map_to_set.rb +61 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -9
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +73 -0
- data/lib/rubocop/cop/style/missing_else.rb +13 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +15 -1
- data/lib/rubocop/cop/style/redundant_constant_base.rb +13 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
- data/lib/rubocop/cop/style/require_order.rb +63 -9
- data/lib/rubocop/cop/style/select_by_regexp.rb +6 -2
- data/lib/rubocop/cop/style/semicolon.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +8 -6
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
- data/lib/rubocop/cop/style/word_array.rb +41 -0
- data/lib/rubocop/cop/style/yoda_expression.rb +81 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
- data/lib/rubocop/cop/team.rb +29 -29
- data/lib/rubocop/cop/util.rb +31 -4
- data/lib/rubocop/cop/variable_force.rb +0 -3
- data/lib/rubocop/cops_documentation_generator.rb +33 -11
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/file_patterns.rb +43 -0
- data/lib/rubocop/formatter.rb +2 -0
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/path_util.rb +38 -22
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +0 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +7 -1
- metadata +16 -10
- data/lib/rubocop/optimized_patterns.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adbae8e6d8a8ad828f302b9d3bba545a8b7fe54727480077a1878d4c2109dbf3
|
4
|
+
data.tar.gz: fb30d554306879712c48bec3d389b4232ee8f8dde6d410dd139b73796a076d3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aa85cf4d34b4994422b5aa921d746b68bc282c97f7563affa2b2574a9b1102eefce4e10bed58801bb6ef9fb2ee2d3d563a63f5b114d754a69c872f6830a793e
|
7
|
+
data.tar.gz: 1e088db8ccb3cdcf2ab7b9e624b68bfc4513681e4cc8ee6bd69084dfa91fda775fc28483a4764962829230d6d2fd5726855299ba1ae622bf85cc66f55451c8c9
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
53
53
|
in your `Gemfile`:
|
54
54
|
|
55
55
|
```rb
|
56
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.43', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -246,5 +246,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
246
246
|
|
247
247
|
## Copyright
|
248
248
|
|
249
|
-
Copyright (c) 2012-
|
249
|
+
Copyright (c) 2012-2023 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
250
250
|
further details.
|
data/config/default.yml
CHANGED
@@ -762,6 +762,7 @@ Layout/FirstArrayElementLineBreak:
|
|
762
762
|
multi-line array.
|
763
763
|
Enabled: false
|
764
764
|
VersionAdded: '0.49'
|
765
|
+
AllowMultilineFinalElement: false
|
765
766
|
|
766
767
|
Layout/FirstHashElementIndentation:
|
767
768
|
Description: 'Checks the indentation of the first key in a hash literal.'
|
@@ -794,6 +795,7 @@ Layout/FirstHashElementLineBreak:
|
|
794
795
|
multi-line hash.
|
795
796
|
Enabled: false
|
796
797
|
VersionAdded: '0.49'
|
798
|
+
AllowMultilineFinalElement: false
|
797
799
|
|
798
800
|
Layout/FirstMethodArgumentLineBreak:
|
799
801
|
Description: >-
|
@@ -801,6 +803,7 @@ Layout/FirstMethodArgumentLineBreak:
|
|
801
803
|
multi-line method call.
|
802
804
|
Enabled: false
|
803
805
|
VersionAdded: '0.49'
|
806
|
+
AllowMultilineFinalElement: false
|
804
807
|
|
805
808
|
Layout/FirstMethodParameterLineBreak:
|
806
809
|
Description: >-
|
@@ -808,6 +811,7 @@ Layout/FirstMethodParameterLineBreak:
|
|
808
811
|
multi-line method parameter definition.
|
809
812
|
Enabled: false
|
810
813
|
VersionAdded: '0.49'
|
814
|
+
AllowMultilineFinalElement: false
|
811
815
|
|
812
816
|
Layout/FirstParameterIndentation:
|
813
817
|
Description: >-
|
@@ -1067,6 +1071,7 @@ Layout/MultilineArrayLineBreaks:
|
|
1067
1071
|
starts on a separate line.
|
1068
1072
|
Enabled: false
|
1069
1073
|
VersionAdded: '0.67'
|
1074
|
+
AllowMultilineFinalElement: false
|
1070
1075
|
|
1071
1076
|
Layout/MultilineAssignmentLayout:
|
1072
1077
|
Description: 'Check for a newline after the assignment operator in multi-line assignments.'
|
@@ -1117,6 +1122,7 @@ Layout/MultilineHashKeyLineBreaks:
|
|
1117
1122
|
starts on a separate line.
|
1118
1123
|
Enabled: false
|
1119
1124
|
VersionAdded: '0.67'
|
1125
|
+
AllowMultilineFinalElement: false
|
1120
1126
|
|
1121
1127
|
Layout/MultilineMethodArgumentLineBreaks:
|
1122
1128
|
Description: >-
|
@@ -1124,6 +1130,7 @@ Layout/MultilineMethodArgumentLineBreaks:
|
|
1124
1130
|
starts on a separate line.
|
1125
1131
|
Enabled: false
|
1126
1132
|
VersionAdded: '0.67'
|
1133
|
+
AllowMultilineFinalElement: false
|
1127
1134
|
|
1128
1135
|
Layout/MultilineMethodCallBraceLayout:
|
1129
1136
|
Description: >-
|
@@ -1178,6 +1185,7 @@ Layout/MultilineMethodParameterLineBreaks:
|
|
1178
1185
|
starts on a separate line.
|
1179
1186
|
Enabled: false
|
1180
1187
|
VersionAdded: '1.32'
|
1188
|
+
AllowMultilineFinalElement: false
|
1181
1189
|
|
1182
1190
|
Layout/MultilineOperationIndentation:
|
1183
1191
|
Description: >-
|
@@ -2444,6 +2452,11 @@ Lint/UselessMethodDefinition:
|
|
2444
2452
|
VersionChanged: '0.91'
|
2445
2453
|
Safe: false
|
2446
2454
|
|
2455
|
+
Lint/UselessRescue:
|
2456
|
+
Description: 'Checks for useless `rescue`s.'
|
2457
|
+
Enabled: pending
|
2458
|
+
VersionAdded: '1.43'
|
2459
|
+
|
2447
2460
|
Lint/UselessRuby2Keywords:
|
2448
2461
|
Description: 'Finds unnecessary uses of `ruby2_keywords`.'
|
2449
2462
|
Enabled: pending
|
@@ -3418,6 +3431,12 @@ Style/CommentedKeyword:
|
|
3418
3431
|
VersionAdded: '0.51'
|
3419
3432
|
VersionChanged: '1.19'
|
3420
3433
|
|
3434
|
+
Style/ConcatArrayLiterals:
|
3435
|
+
Description: 'Enforces the use of `Array#push(item)` instead of `Array#concat([item])` to avoid redundant array literals.'
|
3436
|
+
Enabled: pending
|
3437
|
+
Safe: false
|
3438
|
+
VersionAdded: '1.41'
|
3439
|
+
|
3421
3440
|
Style/ConditionalAssignment:
|
3422
3441
|
Description: >-
|
3423
3442
|
Use the return value of `if` and `case` statements for
|
@@ -3839,7 +3858,8 @@ Style/HashEachMethods:
|
|
3839
3858
|
Safe: false
|
3840
3859
|
VersionAdded: '0.80'
|
3841
3860
|
VersionChanged: '1.16'
|
3842
|
-
AllowedReceivers:
|
3861
|
+
AllowedReceivers:
|
3862
|
+
- Thread.current
|
3843
3863
|
|
3844
3864
|
Style/HashExcept:
|
3845
3865
|
Description: >-
|
@@ -3887,7 +3907,7 @@ Style/HashSyntax:
|
|
3887
3907
|
- never
|
3888
3908
|
# accepts both shorthand and explicit use of hash literal value.
|
3889
3909
|
- either
|
3890
|
-
#
|
3910
|
+
# forces use of the 3.1 syntax only if all values can be omitted in the hash.
|
3891
3911
|
- consistent
|
3892
3912
|
# Force hashes that have a symbol value to use hash rockets
|
3893
3913
|
UseHashRocketsWithSymbolValues: false
|
@@ -4096,6 +4116,12 @@ Style/MapToHash:
|
|
4096
4116
|
VersionAdded: '1.24'
|
4097
4117
|
Safe: false
|
4098
4118
|
|
4119
|
+
Style/MapToSet:
|
4120
|
+
Description: 'Prefer `to_set` with a block over `map.to_set`.'
|
4121
|
+
Enabled: pending
|
4122
|
+
Safe: false
|
4123
|
+
VersionAdded: '1.42'
|
4124
|
+
|
4099
4125
|
Style/MethodCallWithArgsParentheses:
|
4100
4126
|
Description: 'Use parentheses for method calls with arguments.'
|
4101
4127
|
StyleGuide: '#method-invocation-parens'
|
@@ -4154,6 +4180,12 @@ Style/MinMax:
|
|
4154
4180
|
Enabled: true
|
4155
4181
|
VersionAdded: '0.50'
|
4156
4182
|
|
4183
|
+
Style/MinMaxComparison:
|
4184
|
+
Description: 'Enforces the use of `max` or `min` instead of comparison for greater or less.'
|
4185
|
+
Enabled: pending
|
4186
|
+
Safe: false
|
4187
|
+
VersionAdded: '1.42'
|
4188
|
+
|
4157
4189
|
Style/MissingElse:
|
4158
4190
|
Description: >-
|
4159
4191
|
Require if/case expressions to have an else branches.
|
@@ -4731,6 +4763,11 @@ Style/RedundantConstantBase:
|
|
4731
4763
|
Enabled: pending
|
4732
4764
|
VersionAdded: '1.40'
|
4733
4765
|
|
4766
|
+
Style/RedundantDoubleSplatHashBraces:
|
4767
|
+
Description: 'Checks for redundant uses of double splat hash braces.'
|
4768
|
+
Enabled: pending
|
4769
|
+
VersionAdded: '1.41'
|
4770
|
+
|
4734
4771
|
Style/RedundantEach:
|
4735
4772
|
Description: 'Checks for redundant `each`.'
|
4736
4773
|
Enabled: pending
|
@@ -5407,6 +5444,19 @@ Style/YodaCondition:
|
|
5407
5444
|
VersionAdded: '0.49'
|
5408
5445
|
VersionChanged: '0.75'
|
5409
5446
|
|
5447
|
+
Style/YodaExpression:
|
5448
|
+
Description: 'Forbid the use of yoda expressions.'
|
5449
|
+
Enabled: false
|
5450
|
+
Safe: false
|
5451
|
+
VersionAdded: '1.42'
|
5452
|
+
VersionChanged: '1.43'
|
5453
|
+
SupportedOperators:
|
5454
|
+
- '*'
|
5455
|
+
- '+'
|
5456
|
+
- '&'
|
5457
|
+
- '|'
|
5458
|
+
- '^'
|
5459
|
+
|
5410
5460
|
Style/ZeroLengthPredicate:
|
5411
5461
|
Description: 'Use #empty? when testing for objects of length 0.'
|
5412
5462
|
Enabled: true
|
data/lib/rubocop/cli.rb
CHANGED
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
STATUS_SUCCESS = 0
|
8
8
|
STATUS_OFFENSES = 1
|
9
9
|
STATUS_ERROR = 2
|
10
|
-
STATUS_INTERRUPTED =
|
10
|
+
STATUS_INTERRUPTED = Signal.list['INT'] + 128
|
11
11
|
DEFAULT_PARALLEL_OPTIONS = %i[
|
12
12
|
color debug display_style_guide display_time display_only_fail_level_offenses
|
13
13
|
display_only_failed except extra_details fail_level fix_layout format
|
data/lib/rubocop/config.rb
CHANGED
@@ -21,6 +21,14 @@ module RuboCop
|
|
21
21
|
DEFAULT_RAILS_VERSION = 5.0
|
22
22
|
attr_reader :loaded_path
|
23
23
|
|
24
|
+
def self.create(hash, path, check: true)
|
25
|
+
config = new(hash, path)
|
26
|
+
config.check if check
|
27
|
+
|
28
|
+
config
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:disable Metrics/AbcSize
|
24
32
|
def initialize(hash = {}, loaded_path = nil)
|
25
33
|
@loaded_path = loaded_path
|
26
34
|
@for_cop = Hash.new do |h, cop|
|
@@ -32,14 +40,11 @@ module RuboCop
|
|
32
40
|
end
|
33
41
|
@hash = hash
|
34
42
|
@validator = ConfigValidator.new(self)
|
35
|
-
end
|
36
43
|
|
37
|
-
|
38
|
-
|
39
|
-
config.check if check
|
40
|
-
|
41
|
-
config
|
44
|
+
@badge_config_cache = {}.compare_by_identity
|
45
|
+
@clusivity_config_exists_cache = {}
|
42
46
|
end
|
47
|
+
# rubocop:enable Metrics/AbcSize
|
43
48
|
|
44
49
|
def loaded_features
|
45
50
|
@loaded_features ||= ConfigLoader.loaded_features
|
@@ -123,8 +128,25 @@ module RuboCop
|
|
123
128
|
# @return [Config] for the given cop merged with that of its department (if any)
|
124
129
|
# Note: the 'Enabled' attribute is same as that returned by `for_cop`
|
125
130
|
def for_badge(badge)
|
126
|
-
|
127
|
-
|
131
|
+
@badge_config_cache[badge] ||= begin
|
132
|
+
department_config = self[badge.department_name]
|
133
|
+
cop_config = for_cop(badge.to_s)
|
134
|
+
if department_config
|
135
|
+
department_config.merge(cop_config)
|
136
|
+
else
|
137
|
+
cop_config
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# @return [Boolean] whether config for this badge has 'Include' or 'Exclude' keys
|
143
|
+
# @api private
|
144
|
+
def clusivity_config_for_badge?(badge)
|
145
|
+
exists = @clusivity_config_exists_cache[badge.to_s]
|
146
|
+
return exists unless exists.nil?
|
147
|
+
|
148
|
+
cop_config = for_badge(badge)
|
149
|
+
@clusivity_config_exists_cache[badge.to_s] = cop_config['Include'] || cop_config['Exclude']
|
128
150
|
end
|
129
151
|
|
130
152
|
# @return [Config] for the given department name.
|
@@ -273,9 +295,10 @@ module RuboCop
|
|
273
295
|
return nil unless lock_file_path
|
274
296
|
|
275
297
|
File.foreach(lock_file_path) do |line|
|
276
|
-
# If
|
277
|
-
#
|
278
|
-
|
298
|
+
# If Rails (or one of its frameworks) is in Gemfile.lock or gems.lock, there should be
|
299
|
+
# a line like:
|
300
|
+
# railties (X.X.X)
|
301
|
+
result = line.match(/^\s+railties\s+\((\d+\.\d+)/)
|
279
302
|
return result.captures.first.to_f if result
|
280
303
|
end
|
281
304
|
end
|
@@ -137,6 +137,15 @@ module RuboCop
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
# @api private
|
141
|
+
def inject_defaults!(project_root)
|
142
|
+
path = File.join(project_root, 'config', 'default.yml')
|
143
|
+
config = load_file(path)
|
144
|
+
new_config = ConfigLoader.merge_with_default(config, path)
|
145
|
+
puts "configuration from #{path}" if debug?
|
146
|
+
@default_configuration = new_config
|
147
|
+
end
|
148
|
+
|
140
149
|
# Returns the path RuboCop inferred as the root of the project. No file
|
141
150
|
# searches will go past this directory.
|
142
151
|
# @deprecated Use `RuboCop::ConfigFinder.project_root` instead.
|
@@ -206,7 +206,11 @@ module RuboCop
|
|
206
206
|
end
|
207
207
|
|
208
208
|
def base_configs(path, inherit_from, file)
|
209
|
-
|
209
|
+
inherit_froms = Array(inherit_from).compact.flat_map do |f|
|
210
|
+
PathUtil.glob?(f) ? Dir.glob(f) : f
|
211
|
+
end
|
212
|
+
|
213
|
+
configs = inherit_froms.map do |f|
|
210
214
|
ConfigLoader.load_file(inherited_file(path, f, file))
|
211
215
|
end
|
212
216
|
|
@@ -162,7 +162,7 @@ module RuboCop
|
|
162
162
|
return unless syntax_config && default_config.merge(syntax_config) != default_config
|
163
163
|
|
164
164
|
raise ValidationError,
|
165
|
-
"configuration for Syntax cop found in #{smart_loaded_path}\n" \
|
165
|
+
"configuration for Lint/Syntax cop found in #{smart_loaded_path}\n" \
|
166
166
|
'It\'s not possible to disable this cop.'
|
167
167
|
end
|
168
168
|
|
data/lib/rubocop/cop/badge.rb
CHANGED
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# allow for badge references in source files that omit the department for
|
11
11
|
# RuboCop to infer.
|
12
12
|
class Badge
|
13
|
-
attr_reader :department, :cop_name
|
13
|
+
attr_reader :department, :department_name, :cop_name
|
14
14
|
|
15
15
|
def self.for(class_name)
|
16
16
|
parts = class_name.split('::')
|
@@ -18,19 +18,23 @@ module RuboCop
|
|
18
18
|
new(name_deep_enough ? parts[2..] : parts.last(2))
|
19
19
|
end
|
20
20
|
|
21
|
+
@parse_cache = {}
|
22
|
+
|
21
23
|
def self.parse(identifier)
|
22
|
-
new(identifier.split('/').map { |i| camel_case(i) })
|
24
|
+
@parse_cache[identifier] ||= new(identifier.split('/').map! { |i| camel_case(i) })
|
23
25
|
end
|
24
26
|
|
25
27
|
def self.camel_case(name_part)
|
26
28
|
return 'RSpec' if name_part == 'rspec'
|
29
|
+
return name_part unless name_part.match?(/^[a-z]|_[a-z]/)
|
27
30
|
|
28
|
-
name_part.gsub(
|
31
|
+
name_part.gsub(/^[a-z]|_[a-z]/) { |match| match[-1, 1].upcase }
|
29
32
|
end
|
30
33
|
|
31
34
|
def initialize(class_name_parts)
|
32
35
|
department_parts = class_name_parts[0...-1]
|
33
36
|
@department = (department_parts.join('/').to_sym unless department_parts.empty?)
|
37
|
+
@department_name = @department&.to_s
|
34
38
|
@cop_name = class_name_parts.last
|
35
39
|
end
|
36
40
|
|
@@ -40,7 +44,8 @@ module RuboCop
|
|
40
44
|
alias eql? ==
|
41
45
|
|
42
46
|
def hash
|
43
|
-
|
47
|
+
# Do hashing manually to reduce Array allocations.
|
48
|
+
department.hash ^ cop_name.hash # rubocop:disable Security/CompoundHash
|
44
49
|
end
|
45
50
|
|
46
51
|
def match?(other)
|
data/lib/rubocop/cop/base.rb
CHANGED
@@ -68,6 +68,64 @@ module RuboCop
|
|
68
68
|
Documentation.url_for(self) if builtin?
|
69
69
|
end
|
70
70
|
|
71
|
+
def self.inherited(subclass)
|
72
|
+
super
|
73
|
+
Registry.global.enlist(subclass)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Call for abstract Cop classes
|
77
|
+
def self.exclude_from_registry
|
78
|
+
Registry.global.dismiss(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns if class supports autocorrect.
|
82
|
+
# It is recommended to extend AutoCorrector instead of overriding
|
83
|
+
def self.support_autocorrect?
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
### Naming
|
88
|
+
|
89
|
+
def self.badge
|
90
|
+
@badge ||= Badge.for(name)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.cop_name
|
94
|
+
badge.to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.department
|
98
|
+
badge.department
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.lint?
|
102
|
+
department == :Lint
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns true if the cop name or the cop namespace matches any of the
|
106
|
+
# given names.
|
107
|
+
def self.match?(given_names)
|
108
|
+
return false unless given_names
|
109
|
+
|
110
|
+
given_names.include?(cop_name) || given_names.include?(badge.department_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Override and return the Force class(es) you need to join
|
114
|
+
def self.joining_forces; end
|
115
|
+
|
116
|
+
### Persistence
|
117
|
+
|
118
|
+
# Override if your cop should be called repeatedly for multiple investigations
|
119
|
+
# Between calls to `on_new_investigation` and `on_investigation_end`,
|
120
|
+
# the result of `processed_source` will remain constant.
|
121
|
+
# You should invalidate any caches that depend on the current `processed_source`
|
122
|
+
# in the `on_new_investigation` callback.
|
123
|
+
# If your cop does autocorrections, be aware that your instance may be called
|
124
|
+
# multiple times with the same `processed_source.path` but different content.
|
125
|
+
def self.support_multiple_source?
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
71
129
|
def initialize(config = nil, options = nil)
|
72
130
|
@config = config || Config.new
|
73
131
|
@options = options || { debug: false }
|
@@ -92,9 +150,6 @@ module RuboCop
|
|
92
150
|
# Typically do nothing here
|
93
151
|
end
|
94
152
|
|
95
|
-
# Override and return the Force class(es) you need to join
|
96
|
-
def self.joining_forces; end
|
97
|
-
|
98
153
|
# Gets called if no message is specified when calling `add_offense` or
|
99
154
|
# `add_global_offense`
|
100
155
|
# Cops are discouraged to override this; instead pass your message directly
|
@@ -107,8 +162,7 @@ module RuboCop
|
|
107
162
|
def add_global_offense(message = nil, severity: nil)
|
108
163
|
severity = find_severity(nil, severity)
|
109
164
|
message = find_message(nil, message)
|
110
|
-
|
111
|
-
Offense.new(severity, Offense::NO_LOCATION, message, name, :unsupported)
|
165
|
+
current_offenses << Offense.new(severity, Offense::NO_LOCATION, message, name, :unsupported)
|
112
166
|
end
|
113
167
|
|
114
168
|
# Adds an offense on the specified range (or node with an expression)
|
@@ -126,7 +180,7 @@ module RuboCop
|
|
126
180
|
|
127
181
|
status, corrector = enabled_line?(range.line) ? correct(range, &block) : :disabled
|
128
182
|
|
129
|
-
|
183
|
+
current_offenses << Offense.new(severity, range, message, name, status, corrector)
|
130
184
|
end
|
131
185
|
|
132
186
|
# This method should be overridden when a cop's behavior depends
|
@@ -148,48 +202,6 @@ module RuboCop
|
|
148
202
|
nil
|
149
203
|
end
|
150
204
|
|
151
|
-
def self.inherited(subclass)
|
152
|
-
super
|
153
|
-
Registry.global.enlist(subclass)
|
154
|
-
end
|
155
|
-
|
156
|
-
# Call for abstract Cop classes
|
157
|
-
def self.exclude_from_registry
|
158
|
-
Registry.global.dismiss(self)
|
159
|
-
end
|
160
|
-
|
161
|
-
# Returns if class supports autocorrect.
|
162
|
-
# It is recommended to extend AutoCorrector instead of overriding
|
163
|
-
def self.support_autocorrect?
|
164
|
-
false
|
165
|
-
end
|
166
|
-
|
167
|
-
### Naming
|
168
|
-
|
169
|
-
def self.badge
|
170
|
-
@badge ||= Badge.for(name)
|
171
|
-
end
|
172
|
-
|
173
|
-
def self.cop_name
|
174
|
-
badge.to_s
|
175
|
-
end
|
176
|
-
|
177
|
-
def self.department
|
178
|
-
badge.department
|
179
|
-
end
|
180
|
-
|
181
|
-
def self.lint?
|
182
|
-
department == :Lint
|
183
|
-
end
|
184
|
-
|
185
|
-
# Returns true if the cop name or the cop namespace matches any of the
|
186
|
-
# given names.
|
187
|
-
def self.match?(given_names)
|
188
|
-
return false unless given_names
|
189
|
-
|
190
|
-
given_names.include?(cop_name) || given_names.include?(department.to_s)
|
191
|
-
end
|
192
|
-
|
193
205
|
def cop_name
|
194
206
|
@cop_name ||= self.class.cop_name
|
195
207
|
end
|
@@ -225,6 +237,8 @@ module RuboCop
|
|
225
237
|
end
|
226
238
|
|
227
239
|
def relevant_file?(file)
|
240
|
+
return true unless @config.clusivity_config_for_badge?(self.class.badge)
|
241
|
+
|
228
242
|
file == RuboCop::AST::ProcessedSource::STRING_SOURCE_NAME ||
|
229
243
|
(file_name_matches_any?(file, 'Include', true) &&
|
230
244
|
!file_name_matches_any?(file, 'Exclude', false))
|
@@ -239,19 +253,6 @@ module RuboCop
|
|
239
253
|
ProcessedSource.new(source, target_ruby_version, path)
|
240
254
|
end
|
241
255
|
|
242
|
-
### Persistence
|
243
|
-
|
244
|
-
# Override if your cop should be called repeatedly for multiple investigations
|
245
|
-
# Between calls to `on_new_investigation` and `on_investigation_end`,
|
246
|
-
# the result of `processed_source` will remain constant.
|
247
|
-
# You should invalidate any caches that depend on the current `processed_source`
|
248
|
-
# in the `on_new_investigation` callback.
|
249
|
-
# If your cop does autocorrections, be aware that your instance may be called
|
250
|
-
# multiple times with the same `processed_source.path` but different content.
|
251
|
-
def self.support_multiple_source?
|
252
|
-
false
|
253
|
-
end
|
254
|
-
|
255
256
|
# @api private
|
256
257
|
# Called between investigations
|
257
258
|
def ready
|
@@ -270,6 +271,7 @@ module RuboCop
|
|
270
271
|
|
271
272
|
### Reserved for Commissioner
|
272
273
|
|
274
|
+
# rubocop:disable Layout/ClassStructure
|
273
275
|
# @api private
|
274
276
|
def callbacks_needed
|
275
277
|
self.class.callbacks_needed
|
@@ -282,6 +284,7 @@ module RuboCop
|
|
282
284
|
!Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
|
283
285
|
end
|
284
286
|
end
|
287
|
+
# rubocop:enable Layout/ClassStructure
|
285
288
|
|
286
289
|
private
|
287
290
|
|
@@ -292,7 +295,7 @@ module RuboCop
|
|
292
295
|
end
|
293
296
|
|
294
297
|
def apply_correction(corrector)
|
295
|
-
|
298
|
+
current_corrector&.merge!(corrector) if corrector
|
296
299
|
end
|
297
300
|
|
298
301
|
### Reserved for Commissioner:
|
@@ -305,28 +308,41 @@ module RuboCop
|
|
305
308
|
@currently_disabled_lines ||= Set.new
|
306
309
|
end
|
307
310
|
|
311
|
+
def current_corrector
|
312
|
+
@current_corrector ||= Corrector.new(@processed_source) if @processed_source.valid_syntax?
|
313
|
+
end
|
314
|
+
|
315
|
+
def current_offenses
|
316
|
+
@current_offenses ||= []
|
317
|
+
end
|
318
|
+
|
308
319
|
private_class_method def self.restrict_on_send
|
309
320
|
@restrict_on_send ||= self::RESTRICT_ON_SEND.to_a.freeze
|
310
321
|
end
|
311
322
|
|
312
323
|
# Called before any investigation
|
313
324
|
def begin_investigation(processed_source)
|
314
|
-
@current_offenses =
|
325
|
+
@current_offenses = nil
|
315
326
|
@current_offense_locations = nil
|
316
327
|
@currently_disabled_lines = nil
|
317
328
|
@processed_source = processed_source
|
318
|
-
@current_corrector =
|
329
|
+
@current_corrector = nil
|
319
330
|
end
|
320
331
|
|
332
|
+
EMPTY_OFFENSES = [].freeze
|
333
|
+
private_constant :EMPTY_OFFENSES
|
321
334
|
# Called to complete an investigation
|
322
335
|
def complete_investigation
|
323
|
-
InvestigationReport.new(
|
336
|
+
InvestigationReport.new(
|
337
|
+
self, processed_source, @current_offenses || EMPTY_OFFENSES, @current_corrector
|
338
|
+
)
|
324
339
|
ensure
|
325
340
|
reset_investigation
|
326
341
|
end
|
327
342
|
|
328
343
|
### Actually private methods
|
329
344
|
|
345
|
+
# rubocop:disable Layout/ClassStructure
|
330
346
|
def self.builtin?
|
331
347
|
return false unless (m = instance_methods(false).first) # any custom method will do
|
332
348
|
|
@@ -334,6 +350,7 @@ module RuboCop
|
|
334
350
|
path.start_with?(__dir__)
|
335
351
|
end
|
336
352
|
private_class_method :builtin?
|
353
|
+
# rubocop:enable Layout/ClassStructure
|
337
354
|
|
338
355
|
def reset_investigation
|
339
356
|
@currently_disabled_lines = @current_offenses = @processed_source = @current_corrector = nil
|
@@ -412,7 +429,7 @@ module RuboCop
|
|
412
429
|
patterns = cop_config[parameter]
|
413
430
|
return default_result unless patterns
|
414
431
|
|
415
|
-
patterns =
|
432
|
+
patterns = FilePatterns.from(patterns)
|
416
433
|
patterns.match?(config.path_relative_to_config(file)) || patterns.match?(file)
|
417
434
|
end
|
418
435
|
|
@@ -82,7 +82,8 @@ module RuboCop
|
|
82
82
|
@cops.each { |cop| cop.send :begin_investigation, processed_source }
|
83
83
|
if processed_source.valid_syntax?
|
84
84
|
invoke(:on_new_investigation, @cops)
|
85
|
-
|
85
|
+
invoke_with_argument(:investigate, @forces, processed_source)
|
86
|
+
|
86
87
|
walk(processed_source.ast) unless @cops.empty?
|
87
88
|
invoke(:on_investigation_end, @cops)
|
88
89
|
else
|
@@ -149,8 +150,12 @@ module RuboCop
|
|
149
150
|
map
|
150
151
|
end
|
151
152
|
|
152
|
-
def invoke(callback, cops
|
153
|
-
cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback
|
153
|
+
def invoke(callback, cops)
|
154
|
+
cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback) } }
|
155
|
+
end
|
156
|
+
|
157
|
+
def invoke_with_argument(callback, cops, arg)
|
158
|
+
cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback, arg) } }
|
154
159
|
end
|
155
160
|
|
156
161
|
# Allow blind rescues here, since we're absorbing and packaging or
|