rubocop 1.71.2 → 1.73.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 +3 -3
- data/config/default.yml +51 -11
- data/config/internal_affairs.yml +16 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_loader.rb +44 -8
- data/lib/rubocop/config_loader_resolver.rb +23 -9
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -16
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +26 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -6
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +104 -7
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +252 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +18 -18
- data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +3 -3
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +12 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/variable_name.rb +64 -6
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +34 -0
- data/lib/rubocop/cop/style/redundant_format.rb +250 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -4
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/directive_comment.rb +35 -2
- data/lib/rubocop/lsp/runtime.rb +2 -0
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/options.rb +26 -11
- data/lib/rubocop/path_util.rb +4 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/shared_contexts.rb +15 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +35 -2
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/version.rb +17 -2
- data/lib/rubocop.rb +5 -1
- data/lib/ruby_lsp/rubocop/addon.rb +7 -10
- data/lib/ruby_lsp/rubocop/{wraps_built_in_lsp_runtime.rb → runtime_adapter.rb} +5 -8
- metadata +35 -10
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3d6b4b7f7dd2a3128259ff94614da64550ae7c4148106a681987a9ee739b905
|
4
|
+
data.tar.gz: 023ed07c7e4445c1dc44b3062cf0199321e3cc7fc6d4abf55287d281519bdb11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfc82c25468c882682017c7ab8f750970896dcacae270fc00fc6482e4a7d12a20c97f7f56509811fec8c811981be457fc450c977c058d72700490ae72a4aff0a
|
7
|
+
data.tar.gz: 04cfd985c5527d40ba6fd11e33e64278f37b8fcd78a63cfcdf5fef317bef248bfc8771febfa39a05a474372c1ad56190766dc7a188ea9e17bc72031f16d672da
|
data/README.md
CHANGED
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
52
52
|
in your `Gemfile`:
|
53
53
|
|
54
54
|
```rb
|
55
|
-
gem 'rubocop', '~> 1.
|
55
|
+
gem 'rubocop', '~> 1.73', require: false
|
56
56
|
```
|
57
57
|
|
58
58
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -241,9 +241,9 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
|
241
241
|
<a href="https://opencollective.com/rubocop/organization/28/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/28/avatar.svg"></a>
|
242
242
|
<a href="https://opencollective.com/rubocop/organization/29/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/29/avatar.svg"></a>
|
243
243
|
|
244
|
-
##
|
244
|
+
## Release Notes
|
245
245
|
|
246
|
-
RuboCop's
|
246
|
+
RuboCop's release notes are available [here](https://github.com/rubocop/rubocop/releases).
|
247
247
|
|
248
248
|
## Copyright
|
249
249
|
|
data/config/default.yml
CHANGED
@@ -1685,6 +1685,11 @@ Lint/ConstantResolution:
|
|
1685
1685
|
# Restrict this cop from only looking at certain names
|
1686
1686
|
Ignore: []
|
1687
1687
|
|
1688
|
+
Lint/CopDirectiveSyntax:
|
1689
|
+
Description: 'Checks that `# rubocop:` directives are strictly formatted.'
|
1690
|
+
Enabled: pending
|
1691
|
+
VersionAdded: '1.72'
|
1692
|
+
|
1688
1693
|
Lint/Debugger:
|
1689
1694
|
Description: 'Check for debugger calls.'
|
1690
1695
|
Enabled: true
|
@@ -2041,6 +2046,7 @@ Lint/LambdaWithoutLiteralBlock:
|
|
2041
2046
|
Lint/LiteralAsCondition:
|
2042
2047
|
Description: 'Checks of literals used in conditions.'
|
2043
2048
|
Enabled: true
|
2049
|
+
AutoCorrect: contextual
|
2044
2050
|
VersionAdded: '0.51'
|
2045
2051
|
|
2046
2052
|
Lint/LiteralAssignmentInCondition:
|
@@ -2254,9 +2260,8 @@ Lint/RedundantRegexpQuantifiers:
|
|
2254
2260
|
Lint/RedundantRequireStatement:
|
2255
2261
|
Description: 'Checks for unnecessary `require` statement.'
|
2256
2262
|
Enabled: true
|
2257
|
-
SafeAutoCorrect: false
|
2258
2263
|
VersionAdded: '0.76'
|
2259
|
-
VersionChanged: '1.
|
2264
|
+
VersionChanged: '1.73'
|
2260
2265
|
|
2261
2266
|
Lint/RedundantSafeNavigation:
|
2262
2267
|
Description: 'Checks for redundant safe navigation calls.'
|
@@ -2285,6 +2290,11 @@ Lint/RedundantStringCoercion:
|
|
2285
2290
|
VersionAdded: '0.19'
|
2286
2291
|
VersionChanged: '0.77'
|
2287
2292
|
|
2293
|
+
Lint/RedundantTypeConversion:
|
2294
|
+
Description: 'Checks for redundantly converting a literal to the same type.'
|
2295
|
+
Enabled: pending
|
2296
|
+
VersionAdded: '1.72'
|
2297
|
+
|
2288
2298
|
Lint/RedundantWithIndex:
|
2289
2299
|
Description: 'Checks for redundant `with_index`.'
|
2290
2300
|
Enabled: true
|
@@ -2433,6 +2443,12 @@ Lint/SuppressedException:
|
|
2433
2443
|
VersionAdded: '0.9'
|
2434
2444
|
VersionChanged: '1.12'
|
2435
2445
|
|
2446
|
+
Lint/SuppressedExceptionInNumberConversion:
|
2447
|
+
Description: 'Checks for cases where exceptions unrelated to the numeric constructors may be unintentionally swallowed.'
|
2448
|
+
Enabled: pending
|
2449
|
+
SafeAutoCorrect: false
|
2450
|
+
VersionAdded: '1.72'
|
2451
|
+
|
2436
2452
|
Lint/SymbolConversion:
|
2437
2453
|
Description: 'Checks for unnecessary symbol conversions.'
|
2438
2454
|
Enabled: pending
|
@@ -2588,6 +2604,11 @@ Lint/UselessAssignment:
|
|
2588
2604
|
VersionAdded: '0.11'
|
2589
2605
|
VersionChanged: '1.66'
|
2590
2606
|
|
2607
|
+
Lint/UselessConstantScoping:
|
2608
|
+
Description: 'Checks for useless constant scoping.'
|
2609
|
+
Enabled: pending
|
2610
|
+
VersionAdded: '1.72'
|
2611
|
+
|
2591
2612
|
Lint/UselessDefined:
|
2592
2613
|
Description: 'Checks for calls to `defined?` with strings and symbols. The result of such a call will always be truthy.'
|
2593
2614
|
Enabled: pending
|
@@ -3041,6 +3062,8 @@ Naming/PredicateName:
|
|
3041
3062
|
MethodDefinitionMacros:
|
3042
3063
|
- define_method
|
3043
3064
|
- define_singleton_method
|
3065
|
+
# Use Sorbet's T::Boolean return type to detect predicate methods.
|
3066
|
+
UseSorbetSigs: false
|
3044
3067
|
# Exclude Rspec specs because there is a strong convention to write spec
|
3045
3068
|
# helpers in the form of `have_something` or `be_something`.
|
3046
3069
|
Exclude:
|
@@ -3058,13 +3081,15 @@ Naming/VariableName:
|
|
3058
3081
|
StyleGuide: '#snake-case-symbols-methods-vars'
|
3059
3082
|
Enabled: true
|
3060
3083
|
VersionAdded: '0.50'
|
3061
|
-
VersionChanged: '1.
|
3084
|
+
VersionChanged: '1.73'
|
3062
3085
|
EnforcedStyle: snake_case
|
3063
3086
|
SupportedStyles:
|
3064
3087
|
- snake_case
|
3065
3088
|
- camelCase
|
3066
3089
|
AllowedIdentifiers: []
|
3067
3090
|
AllowedPatterns: []
|
3091
|
+
ForbiddenIdentifiers: []
|
3092
|
+
ForbiddenPatterns: []
|
3068
3093
|
|
3069
3094
|
Naming/VariableNumber:
|
3070
3095
|
Description: 'Use the configured style when numbering symbols, methods and variables.'
|
@@ -3899,6 +3924,8 @@ Style/EndlessMethod:
|
|
3899
3924
|
- allow_single_line
|
3900
3925
|
- allow_always
|
3901
3926
|
- disallow
|
3927
|
+
- require_single_line
|
3928
|
+
- require_always
|
3902
3929
|
|
3903
3930
|
Style/EnvHome:
|
3904
3931
|
Description: "Checks for consistent usage of `ENV['HOME']`."
|
@@ -5145,6 +5172,13 @@ Style/RedundantFilterChain:
|
|
5145
5172
|
VersionAdded: '1.52'
|
5146
5173
|
VersionChanged: '1.57'
|
5147
5174
|
|
5175
|
+
Style/RedundantFormat:
|
5176
|
+
Description: 'Checks for usages of `Kernel#format` or `Kernel#sprintf` with only a single argument.'
|
5177
|
+
Enabled: pending
|
5178
|
+
SafeAutoCorrect: false
|
5179
|
+
VersionAdded: '1.72'
|
5180
|
+
VersionChanged: '1.72'
|
5181
|
+
|
5148
5182
|
Style/RedundantFreeze:
|
5149
5183
|
Description: "Checks usages of Object#freeze on immutable objects."
|
5150
5184
|
Enabled: true
|
@@ -5671,14 +5705,17 @@ Style/TrailingCommaInArrayLiteral:
|
|
5671
5705
|
StyleGuide: '#no-trailing-array-commas'
|
5672
5706
|
Enabled: true
|
5673
5707
|
VersionAdded: '0.53'
|
5674
|
-
# If `comma`, the cop requires a comma after the last item in an array,
|
5675
|
-
#
|
5676
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5677
|
-
#
|
5708
|
+
# If `comma`, the cop requires a comma after the last item in an array, but only when each item is
|
5709
|
+
# on its own line.
|
5710
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5711
|
+
# array literals.
|
5712
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline array
|
5713
|
+
# literals, but only when that last item immediately precedes a newline.
|
5678
5714
|
EnforcedStyleForMultiline: no_comma
|
5679
5715
|
SupportedStylesForMultiline:
|
5680
5716
|
- comma
|
5681
5717
|
- consistent_comma
|
5718
|
+
- diff_comma
|
5682
5719
|
- no_comma
|
5683
5720
|
|
5684
5721
|
Style/TrailingCommaInBlockArgs:
|
@@ -5690,14 +5727,17 @@ Style/TrailingCommaInBlockArgs:
|
|
5690
5727
|
Style/TrailingCommaInHashLiteral:
|
5691
5728
|
Description: 'Checks for trailing comma in hash literals.'
|
5692
5729
|
Enabled: true
|
5693
|
-
# If `comma`, the cop requires a comma after the last item in a hash,
|
5694
|
-
#
|
5695
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5696
|
-
#
|
5730
|
+
# If `comma`, the cop requires a comma after the last item in a hash, but only when each item is
|
5731
|
+
# on its own line.
|
5732
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5733
|
+
# hash literals.
|
5734
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline hash
|
5735
|
+
# literals, but only when that last item immediately precedes a newline.
|
5697
5736
|
EnforcedStyleForMultiline: no_comma
|
5698
5737
|
SupportedStylesForMultiline:
|
5699
5738
|
- comma
|
5700
5739
|
- consistent_comma
|
5740
|
+
- diff_comma
|
5701
5741
|
- no_comma
|
5702
5742
|
VersionAdded: '0.53'
|
5703
5743
|
|
data/config/internal_affairs.yml
CHANGED
@@ -6,6 +6,22 @@ InternalAffairs/CopDescription:
|
|
6
6
|
Include:
|
7
7
|
- 'lib/rubocop/cop/**/*.rb'
|
8
8
|
|
9
|
+
InternalAffairs/ExampleHeredocDelimiter:
|
10
|
+
Include:
|
11
|
+
- 'spec/rubocop/cop/**/*.rb'
|
12
|
+
|
13
|
+
InternalAffairs/ExampleDescription:
|
14
|
+
Include:
|
15
|
+
- 'spec/rubocop/cop/**/*.rb'
|
16
|
+
|
17
|
+
InternalAffairs/OnSendWithoutOnCSend:
|
18
|
+
Include:
|
19
|
+
- 'lib/rubocop/cop/**/*.rb'
|
20
|
+
|
21
|
+
InternalAffairs/UndefinedConfig:
|
22
|
+
Include:
|
23
|
+
- 'lib/rubocop/cop/**/*.rb'
|
24
|
+
|
9
25
|
InternalAffairs/UselessMessageAssertion:
|
10
26
|
Include:
|
11
27
|
- '**/*_spec.rb'
|
@@ -97,7 +97,13 @@ module RuboCop
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def loaded_extensions
|
100
|
-
@config_store.for_pwd
|
100
|
+
rubocop_config = @config_store.for_pwd
|
101
|
+
|
102
|
+
plugin_names = rubocop_config.loaded_plugins.map do |plugin|
|
103
|
+
plugin.about.name
|
104
|
+
end
|
105
|
+
|
106
|
+
plugin_names + rubocop_config.loaded_features.to_a
|
101
107
|
end
|
102
108
|
|
103
109
|
def installed_and_not_loaded_extensions
|
data/lib/rubocop/config.rb
CHANGED
@@ -33,13 +33,14 @@ module RuboCop
|
|
33
33
|
attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
|
34
34
|
:ignore_unrecognized_cops
|
35
35
|
attr_writer :default_configuration
|
36
|
-
attr_reader :loaded_features
|
36
|
+
attr_reader :loaded_plugins, :loaded_features
|
37
37
|
|
38
38
|
alias debug? debug
|
39
39
|
alias ignore_parent_exclusion? ignore_parent_exclusion
|
40
40
|
|
41
41
|
def clear_options
|
42
42
|
@debug = nil
|
43
|
+
@loaded_plugins = Set.new
|
43
44
|
@loaded_features = Set.new
|
44
45
|
@disable_pending_cops = nil
|
45
46
|
@enable_pending_cops = nil
|
@@ -48,11 +49,17 @@ module RuboCop
|
|
48
49
|
FileFinder.root_level = nil
|
49
50
|
end
|
50
51
|
|
52
|
+
# rubocop:disable Metrics/AbcSize
|
51
53
|
def load_file(file, check: true)
|
52
54
|
path = file_path(file)
|
53
55
|
|
54
56
|
hash = load_yaml_configuration(path)
|
55
57
|
|
58
|
+
rubocop_config = Config.create(hash, path, check: false)
|
59
|
+
plugins = hash.delete('plugins')
|
60
|
+
loaded_plugins = resolver.resolve_plugins(rubocop_config, plugins)
|
61
|
+
add_loaded_plugins(loaded_plugins)
|
62
|
+
|
56
63
|
loaded_features = resolver.resolve_requires(path, hash)
|
57
64
|
add_loaded_features(loaded_features)
|
58
65
|
|
@@ -67,6 +74,7 @@ module RuboCop
|
|
67
74
|
|
68
75
|
Config.create(hash, path, check: check)
|
69
76
|
end
|
77
|
+
# rubocop:enable Metrics/AbcSize
|
70
78
|
|
71
79
|
def load_yaml_configuration(absolute_path)
|
72
80
|
file_contents = read_file(absolute_path)
|
@@ -155,14 +163,35 @@ module RuboCop
|
|
155
163
|
end
|
156
164
|
end
|
157
165
|
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
166
|
+
# This API is primarily intended for testing and documenting plugins.
|
167
|
+
# When testing a plugin using `rubocop/rspec/support`, the plugin is loaded automatically,
|
168
|
+
# so this API is usually not needed. It is intended to be used only when implementing tests
|
169
|
+
# that do not use `rubocop/rspec/support`.
|
170
|
+
# rubocop:disable Metrics/MethodLength
|
171
|
+
def inject_defaults!(config_yml_path)
|
172
|
+
if Pathname(config_yml_path).directory?
|
173
|
+
# TODO: Since the warning noise is expected to be high until some time after the release,
|
174
|
+
# warnings will only be issued when `RUBYOPT=-w` is specified.
|
175
|
+
# To proceed step by step, the next step is to remove `$VERBOSE` and always issue warning.
|
176
|
+
# Eventually, `project_root` will no longer be accepted.
|
177
|
+
if $VERBOSE
|
178
|
+
warn Rainbow(<<~MESSAGE).yellow, uplevel: 1
|
179
|
+
Use config YAML file path instead of project root directory.
|
180
|
+
e.g., `path/to/config/default.yml`
|
181
|
+
MESSAGE
|
182
|
+
end
|
183
|
+
# NOTE: For compatibility.
|
184
|
+
project_root = config_yml_path
|
185
|
+
path = File.join(project_root, 'config', 'default.yml')
|
186
|
+
config = load_file(path)
|
187
|
+
else
|
188
|
+
hash = ConfigLoader.load_yaml_configuration(config_yml_path.to_s)
|
189
|
+
config = Config.new(hash, config_yml_path).tap(&:make_excludes_absolute)
|
190
|
+
end
|
191
|
+
|
192
|
+
@default_configuration = ConfigLoader.merge_with_default(config, path)
|
165
193
|
end
|
194
|
+
# rubocop:enable Metrics/MethodLength
|
166
195
|
|
167
196
|
# Returns the path RuboCop inferred as the root of the project. No file
|
168
197
|
# searches will go past this directory.
|
@@ -196,6 +225,13 @@ module RuboCop
|
|
196
225
|
resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
|
197
226
|
end
|
198
227
|
|
228
|
+
# @api private
|
229
|
+
# Used to add plugins that were required inside a config or from
|
230
|
+
# the CLI using `--plugin`.
|
231
|
+
def add_loaded_plugins(loaded_plugins)
|
232
|
+
@loaded_plugins.merge(Array(loaded_plugins))
|
233
|
+
end
|
234
|
+
|
199
235
|
# @api private
|
200
236
|
# Used to add features that were required inside a config or from
|
201
237
|
# the CLI using `--require`.
|
@@ -2,16 +2,34 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'yaml'
|
5
|
+
require_relative 'plugin'
|
5
6
|
|
6
7
|
module RuboCop
|
7
8
|
# A help class for ConfigLoader that handles configuration resolution.
|
8
9
|
# @api private
|
9
10
|
class ConfigLoaderResolver # rubocop:disable Metrics/ClassLength
|
11
|
+
def resolve_plugins(rubocop_config, plugins)
|
12
|
+
return if (plugins = Array(plugins)).empty?
|
13
|
+
|
14
|
+
Plugin.integrate_plugins(rubocop_config, plugins)
|
15
|
+
end
|
16
|
+
|
10
17
|
def resolve_requires(path, hash)
|
11
18
|
config_dir = File.dirname(path)
|
12
19
|
hash.delete('require').tap do |loaded_features|
|
13
20
|
Array(loaded_features).each do |feature|
|
14
|
-
|
21
|
+
if Plugin.plugin_capable?(feature)
|
22
|
+
# NOTE: Compatibility for before plugins style.
|
23
|
+
warn Rainbow(<<~MESSAGE).yellow
|
24
|
+
#{feature} extension supports plugin, specify `plugins: #{feature}` instead of `require: #{feature}` in #{path}.
|
25
|
+
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
|
26
|
+
MESSAGE
|
27
|
+
rubocop_config = Config.create(hash, path, check: false)
|
28
|
+
|
29
|
+
resolve_plugins(rubocop_config, feature)
|
30
|
+
else
|
31
|
+
FeatureLoader.load(config_directory_path: config_dir, feature: feature)
|
32
|
+
end
|
15
33
|
end
|
16
34
|
end
|
17
35
|
end
|
@@ -105,7 +123,7 @@ module RuboCop
|
|
105
123
|
elsif merge_hashes?(base_hash, derived_hash, key)
|
106
124
|
result[key] = merge(base_hash[key], derived_hash[key], **opts)
|
107
125
|
elsif should_union?(derived_hash, base_hash, opts[:inherit_mode], key)
|
108
|
-
result[key] = base_hash[key] | derived_hash[key]
|
126
|
+
result[key] = Array(base_hash[key]) | Array(derived_hash[key])
|
109
127
|
elsif opts[:debug]
|
110
128
|
warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
|
111
129
|
end
|
@@ -157,7 +175,7 @@ module RuboCop
|
|
157
175
|
return false if inherited_file.nil? # Not inheritance resolving merge
|
158
176
|
return false if inherited_file.start_with?('..') # Legitimate override
|
159
177
|
return false if base_hash[key] == derived_hash[key] # Same value
|
160
|
-
return false if remote_file?(inherited_file) # Can't change
|
178
|
+
return false if PathUtil.remote_file?(inherited_file) # Can't change
|
161
179
|
|
162
180
|
Gem.path.none? { |dir| inherited_file.start_with?(dir) } # Can change?
|
163
181
|
end
|
@@ -187,7 +205,7 @@ module RuboCop
|
|
187
205
|
end
|
188
206
|
|
189
207
|
def should_union?(derived_hash, base_hash, root_mode, key)
|
190
|
-
return false unless base_hash[key].is_a?(Array)
|
208
|
+
return false unless base_hash[key].is_a?(Array) || derived_hash[key].is_a?(Array)
|
191
209
|
|
192
210
|
derived_mode = derived_hash['inherit_mode']
|
193
211
|
return false if should_override?(derived_mode, key)
|
@@ -225,7 +243,7 @@ module RuboCop
|
|
225
243
|
end
|
226
244
|
|
227
245
|
def inherited_file(path, inherit_from, file)
|
228
|
-
if remote_file?(inherit_from)
|
246
|
+
if PathUtil.remote_file?(inherit_from)
|
229
247
|
# A remote configuration, e.g. `inherit_from: http://example.com/rubocop.yml`.
|
230
248
|
RemoteConfig.new(inherit_from, File.dirname(path))
|
231
249
|
elsif Pathname.new(inherit_from).absolute?
|
@@ -245,10 +263,6 @@ module RuboCop
|
|
245
263
|
end
|
246
264
|
end
|
247
265
|
|
248
|
-
def remote_file?(uri)
|
249
|
-
uri.start_with?('http://', 'https://')
|
250
|
-
end
|
251
|
-
|
252
266
|
def remote_config?(file)
|
253
267
|
file.is_a?(RemoteConfig)
|
254
268
|
end
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
|
10
10
|
# @api private
|
11
11
|
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
|
12
|
-
Enabled].freeze
|
12
|
+
Enabled Reference].freeze
|
13
13
|
# @api private
|
14
14
|
INTERNAL_PARAMS = %w[Description StyleGuide
|
15
15
|
VersionAdded VersionChanged VersionRemoved
|
@@ -90,8 +90,10 @@ module RuboCop
|
|
90
90
|
description_text = string_contents(current_description)
|
91
91
|
return unless (new_description = correct_description(description_text, description_map))
|
92
92
|
|
93
|
+
quote = current_description.dstr_type? ? '"' : "'"
|
94
|
+
|
93
95
|
add_offense(current_description, message: message) do |corrector|
|
94
|
-
corrector.replace(current_description, "
|
96
|
+
corrector.replace(current_description, "#{quote}#{new_description}#{quote}")
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -106,7 +108,7 @@ module RuboCop
|
|
106
108
|
end
|
107
109
|
|
108
110
|
def string_contents(node)
|
109
|
-
node.
|
111
|
+
node.type?(:str, :dstr) ? node.value : node.source
|
110
112
|
end
|
111
113
|
end
|
112
114
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# When a node location may not exist, `Node#loc?` or `Node#loc_is?`
|
7
|
+
# can be used instead of calling `Node#respond_to?` before using
|
8
|
+
# the value.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# node.loc.respond_to?(:begin) && node.loc.begin
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# node.loc?(:begin)
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# node.loc.respond_to?(:begin) && node.loc.begin.is?('(')
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# node.loc_is?(:begin, '(')
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# node.loc.respond_to?(:begin) && node.loc.begin.source == '('
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# node.loc_is?(:begin, '(')
|
28
|
+
#
|
29
|
+
class LocationExists < Base
|
30
|
+
extend AutoCorrector
|
31
|
+
|
32
|
+
MSG = 'Use `%<replacement>s` instead of `%<source>s`.'
|
33
|
+
|
34
|
+
# @!method replaceable_with_loc_is(node)
|
35
|
+
def_node_matcher :replaceable_with_loc_is, <<~PATTERN
|
36
|
+
(and
|
37
|
+
(call
|
38
|
+
(call $_receiver :loc) :respond_to?
|
39
|
+
$(sym _location))
|
40
|
+
{
|
41
|
+
(call
|
42
|
+
(call
|
43
|
+
(call _receiver :loc) _location) :is?
|
44
|
+
$(str _))
|
45
|
+
(call
|
46
|
+
(call
|
47
|
+
(call
|
48
|
+
(call _receiver :loc) _location) :source) :==
|
49
|
+
$(str _))
|
50
|
+
})
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
# @!method replaceable_with_loc(node)
|
54
|
+
def_node_matcher :replaceable_with_loc, <<~PATTERN
|
55
|
+
(and
|
56
|
+
(call
|
57
|
+
(call $_receiver :loc) :respond_to?
|
58
|
+
$(sym _location))
|
59
|
+
(call
|
60
|
+
(call _receiver :loc) _location))
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
def on_and(node)
|
64
|
+
replace_with_loc(node) || replace_with_loc_is(node)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def replace_with_loc(node)
|
70
|
+
replaceable_with_loc(node) do |receiver, location|
|
71
|
+
if node.parent&.assignment?
|
72
|
+
register_offense(node, replace_assignment(receiver, location))
|
73
|
+
else
|
74
|
+
register_offense(node, replacement(receiver, "loc?(#{location.source})"))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def replace_with_loc_is(node)
|
80
|
+
replaceable_with_loc_is(node) do |receiver, location, value|
|
81
|
+
replacement = replacement(receiver, "loc_is?(#{location.source}, #{value.source})")
|
82
|
+
register_offense(node, replacement)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def register_offense(node, replacement)
|
87
|
+
message = format(MSG, replacement: replacement, source: node.source)
|
88
|
+
|
89
|
+
add_offense(node, message: message) do |corrector|
|
90
|
+
corrector.replace(node, replacement)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def replacement(receiver, rest)
|
95
|
+
"#{replace_receiver(receiver)}#{rest}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def replace_assignment(receiver, location)
|
99
|
+
prefix = replace_receiver(receiver)
|
100
|
+
|
101
|
+
"#{prefix}loc#{dot(receiver)}#{location.value} if #{prefix}loc?(#{location.source})"
|
102
|
+
end
|
103
|
+
|
104
|
+
def replace_receiver(receiver)
|
105
|
+
return '' unless receiver
|
106
|
+
|
107
|
+
"#{receiver.source}#{dot(receiver)}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def dot(node)
|
111
|
+
node.parent.loc.dot.source
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module InternalAffairs
|
6
|
-
# rubocop:disable InternalAffairs/RedundantSourceRange
|
6
|
+
# rubocop:disable InternalAffairs/RedundantSourceRange -- node here is a `NodePattern::Node`
|
7
7
|
class NodePatternGroups
|
8
8
|
# Walks an AST that has been processed by `InternalAffairs::NodePatternGroups::Processor`
|
9
9
|
# in order to find `node_type` and `node_sequence` nodes that can be replaced with a node
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lint_roller'
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module InternalAffairs
|
7
|
+
# A Plugin for `InternalAffairs` department, which has internal cops.
|
8
|
+
class Plugin < LintRoller::Plugin
|
9
|
+
def about
|
10
|
+
LintRoller::About.new(
|
11
|
+
name: 'rubocop-internal_affairs',
|
12
|
+
version: Version::STRING,
|
13
|
+
homepage: 'https://github.com/rubocop/rubocop/tree/master/lib/rubocop/cop/internal_affairs',
|
14
|
+
description: 'A collection of RuboCop cops to check for internal affairs.'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def supported?(context)
|
19
|
+
context.engine == :rubocop
|
20
|
+
end
|
21
|
+
|
22
|
+
def rules(_context)
|
23
|
+
require_relative '../internal_affairs'
|
24
|
+
|
25
|
+
LintRoller::Rules.new(
|
26
|
+
type: :path,
|
27
|
+
config_format: :rubocop,
|
28
|
+
value: Pathname.new(__dir__).join('../../../../config/internal_affairs.yml')
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -17,7 +17,13 @@ module RuboCop
|
|
17
17
|
'in `config/default.yml`.'
|
18
18
|
CONFIG_PATH = find_file_upwards('config/default.yml', Dir.pwd)
|
19
19
|
CONFIG = if CONFIG_PATH
|
20
|
-
|
20
|
+
begin
|
21
|
+
original_debug = ConfigLoader.debug
|
22
|
+
ConfigLoader.debug = false
|
23
|
+
ConfigLoader.load_yaml_configuration(CONFIG_PATH)
|
24
|
+
ensure
|
25
|
+
ConfigLoader.debug = original_debug
|
26
|
+
end
|
21
27
|
else
|
22
28
|
{}
|
23
29
|
end
|
@@ -8,6 +8,7 @@ require_relative 'internal_affairs/example_description'
|
|
8
8
|
require_relative 'internal_affairs/example_heredoc_delimiter'
|
9
9
|
require_relative 'internal_affairs/inherit_deprecated_cop_class'
|
10
10
|
require_relative 'internal_affairs/lambda_or_proc'
|
11
|
+
require_relative 'internal_affairs/location_exists'
|
11
12
|
require_relative 'internal_affairs/location_expression'
|
12
13
|
require_relative 'internal_affairs/location_line_equality_comparison'
|
13
14
|
require_relative 'internal_affairs/method_name_end_with'
|
@@ -36,19 +37,3 @@ require_relative 'internal_affairs/style_detected_api_use'
|
|
36
37
|
require_relative 'internal_affairs/undefined_config'
|
37
38
|
require_relative 'internal_affairs/useless_message_assertion'
|
38
39
|
require_relative 'internal_affairs/useless_restrict_on_send'
|
39
|
-
|
40
|
-
module RuboCop
|
41
|
-
# Patch in the InternalAffairs specific config values
|
42
|
-
module InternalAffairs
|
43
|
-
def self.inject!
|
44
|
-
path = File.join(ConfigLoader::RUBOCOP_HOME, 'config', 'internal_affairs.yml')
|
45
|
-
hash = ConfigLoader.load_yaml_configuration(path)
|
46
|
-
config = Config.new(hash, path)
|
47
|
-
puts "configuration from #{path}" if ConfigLoader.debug?
|
48
|
-
config = ConfigLoader.merge_with_default(config, path)
|
49
|
-
ConfigLoader.instance_variable_set(:@default_configuration, config)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
RuboCop::InternalAffairs.inject!
|