rubocop 1.71.2 → 1.72.1
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/config/default.yml +28 -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 +21 -7
- 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_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- 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/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +74 -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/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +18 -18
- 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/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/style/redundant_format.rb +222 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -3
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- 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 +141 -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 +39 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/rspec/cop_helper.rb +7 -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 -0
- 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 -9
data/lib/rubocop/lsp/server.rb
CHANGED
@@ -22,8 +22,6 @@ module RuboCop
|
|
22
22
|
def initialize(config_store)
|
23
23
|
$PROGRAM_NAME = "rubocop --lsp #{ConfigFinder.project_root}"
|
24
24
|
|
25
|
-
RuboCop::LSP.enable
|
26
|
-
|
27
25
|
@reader = LanguageServer::Protocol::Transport::Io::Reader.new($stdin)
|
28
26
|
@writer = LanguageServer::Protocol::Transport::Io::Writer.new($stdout)
|
29
27
|
@runtime = RuboCop::LSP::Runtime.new(config_store)
|
data/lib/rubocop/options.rb
CHANGED
@@ -243,6 +243,7 @@ module RuboCop
|
|
243
243
|
option(opts, '--init')
|
244
244
|
option(opts, '-c', '--config FILE')
|
245
245
|
option(opts, '-d', '--debug')
|
246
|
+
option(opts, '--plugin FILE') { |f| plugin_feature(f) }
|
246
247
|
option(opts, '-r', '--require FILE') { |f| require_feature(f) }
|
247
248
|
option(opts, '--[no-]color')
|
248
249
|
option(opts, '-v', '--version')
|
@@ -299,11 +300,25 @@ module RuboCop
|
|
299
300
|
long_opt[2..].sub('[no-]', '').sub(/ .*/, '').tr('-', '_').gsub(/[\[\]]/, '').to_sym
|
300
301
|
end
|
301
302
|
|
302
|
-
def
|
303
|
-
# If any features were added on the CLI from `--
|
303
|
+
def plugin_feature(file)
|
304
|
+
# If any features were added on the CLI from `--plugin`,
|
304
305
|
# add them to the config.
|
305
|
-
|
306
|
-
|
306
|
+
ConfigLoaderResolver.new.resolve_plugins(Config.new, file)
|
307
|
+
end
|
308
|
+
|
309
|
+
def require_feature(file)
|
310
|
+
if Plugin.plugin_capable?(file)
|
311
|
+
# NOTE: Compatibility for before plugins style.
|
312
|
+
warn Rainbow(<<~MESSAGE).yellow
|
313
|
+
#{file} gem supports plugin, use `--plugin` instead of `--require`.
|
314
|
+
MESSAGE
|
315
|
+
plugin_feature(file)
|
316
|
+
else
|
317
|
+
# If any features were added on the CLI from `--require`,
|
318
|
+
# add them to the config.
|
319
|
+
require file
|
320
|
+
ConfigLoader.add_loaded_features(file)
|
321
|
+
end
|
307
322
|
end
|
308
323
|
end
|
309
324
|
|
@@ -397,7 +412,7 @@ module RuboCop
|
|
397
412
|
return if @options[:format] == 'junit'
|
398
413
|
|
399
414
|
raise OptionArgumentError,
|
400
|
-
|
415
|
+
'--display-only-failed can only be used together with --format junit.'
|
401
416
|
end
|
402
417
|
|
403
418
|
def validate_display_only_correctable_and_autocorrect
|
@@ -415,14 +430,13 @@ module RuboCop
|
|
415
430
|
!@options.key?(:display_only_safe_correctable)
|
416
431
|
|
417
432
|
raise OptionArgumentError,
|
418
|
-
|
433
|
+
'--display-only-failed cannot be used together with other display options.'
|
419
434
|
end
|
420
435
|
|
421
436
|
def validate_lsp_and_editor_mode
|
422
437
|
return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
|
423
438
|
|
424
|
-
raise OptionArgumentError,
|
425
|
-
format('Do not specify `--editor-mode` as it is redundant in `--lsp`.')
|
439
|
+
raise OptionArgumentError, 'Do not specify `--editor-mode` as it is redundant in `--lsp`.'
|
426
440
|
end
|
427
441
|
|
428
442
|
def validate_autocorrect
|
@@ -436,7 +450,7 @@ module RuboCop
|
|
436
450
|
return unless @options.key?(:disable_uncorrectable)
|
437
451
|
|
438
452
|
raise OptionArgumentError,
|
439
|
-
|
453
|
+
'--disable-uncorrectable can only be used together with --autocorrect.'
|
440
454
|
end
|
441
455
|
|
442
456
|
def disable_parallel_when_invalid_option_combo
|
@@ -504,6 +518,7 @@ module RuboCop
|
|
504
518
|
only_guide_cops: ['Run only cops for rules that link to a',
|
505
519
|
'style guide.'],
|
506
520
|
except: 'Exclude the given cop(s).',
|
521
|
+
plugin: 'Load a RuboCop plugin.',
|
507
522
|
require: 'Require Ruby file.',
|
508
523
|
config: 'Specify configuration file.',
|
509
524
|
auto_gen_config: ['Generate a configuration file acting as a',
|
@@ -542,8 +557,8 @@ module RuboCop
|
|
542
557
|
only_recognized_file_types: ['Inspect files given on the command line only if',
|
543
558
|
'they are listed in `AllCops/Include` parameters',
|
544
559
|
'of user configuration or default configuration.'],
|
545
|
-
ignore_disable_comments: ['
|
546
|
-
'
|
560
|
+
ignore_disable_comments: ['Report offenses even if they have been manually disabled',
|
561
|
+
'with a `rubocop:disable` or `rubocop:todo` directive.'],
|
547
562
|
ignore_parent_exclusion: ['Prevent from inheriting `AllCops/Exclude` from',
|
548
563
|
'parent folders.'],
|
549
564
|
ignore_unrecognized_cops: ['Ignore unrecognized cops or departments in the config.'],
|
data/lib/rubocop/path_util.rb
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lint_roller/context'
|
4
|
+
require_relative 'not_supported_error'
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
module Plugin
|
8
|
+
# A class for integrating plugin configurations into RuboCop.
|
9
|
+
# Handles configuration merging, validation, and compatibility for plugins.
|
10
|
+
# @api private
|
11
|
+
class ConfigurationIntegrator
|
12
|
+
class << self
|
13
|
+
def integrate_plugins_into_rubocop_config(rubocop_config, plugins)
|
14
|
+
default_config = ConfigLoader.default_configuration
|
15
|
+
runner_context = create_context(rubocop_config)
|
16
|
+
|
17
|
+
validate_plugins!(plugins, runner_context)
|
18
|
+
|
19
|
+
plugin_config = combine_rubocop_configs(default_config, runner_context, plugins).to_h
|
20
|
+
|
21
|
+
merge_plugin_config_into_all_cops!(default_config, plugin_config)
|
22
|
+
merge_plugin_config_into_default_config!(default_config, plugin_config)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def create_context(rubocop_config)
|
28
|
+
LintRoller::Context.new(
|
29
|
+
runner: :rubocop,
|
30
|
+
runner_version: Version.version,
|
31
|
+
engine: :rubocop,
|
32
|
+
engine_version: Version.version,
|
33
|
+
target_ruby_version: rubocop_config.target_ruby_version
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_plugins!(plugins, runner_context)
|
38
|
+
unsupported_plugins = plugins.reject { |plugin| plugin.supported?(runner_context) }
|
39
|
+
return if unsupported_plugins.none?
|
40
|
+
|
41
|
+
raise Plugin::NotSupportedError, unsupported_plugins
|
42
|
+
end
|
43
|
+
|
44
|
+
def combine_rubocop_configs(default_config, runner_context, plugins)
|
45
|
+
fake_out_rubocop_default_configuration(default_config) do |fake_config|
|
46
|
+
all_cop_keys_configured_by_plugins = []
|
47
|
+
|
48
|
+
plugins.reduce(fake_config) do |combined_config, plugin|
|
49
|
+
RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, combined_config)
|
50
|
+
|
51
|
+
print 'Plugin ' if ConfigLoader.debug
|
52
|
+
|
53
|
+
plugin_config, plugin_config_path = load_plugin_rubocop_config(plugin, runner_context)
|
54
|
+
|
55
|
+
plugin_config['AllCops'], all_cop_keys_configured_by_plugins = merge_all_cop_settings(
|
56
|
+
combined_config['AllCops'], plugin_config['AllCops'],
|
57
|
+
all_cop_keys_configured_by_plugins
|
58
|
+
)
|
59
|
+
|
60
|
+
ConfigLoader.merge_with_default(plugin_config, plugin_config_path)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def merge_plugin_config_into_all_cops!(rubocop_config, plugin_config)
|
66
|
+
rubocop_config['AllCops'].merge!(plugin_config['AllCops'])
|
67
|
+
end
|
68
|
+
|
69
|
+
def merge_plugin_config_into_default_config!(default_config, plugin_config)
|
70
|
+
plugin_config.each do |key, value|
|
71
|
+
default_config[key] = if default_config[key].is_a?(Hash)
|
72
|
+
resolver.merge(default_config[key], value)
|
73
|
+
else
|
74
|
+
value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def fake_out_rubocop_default_configuration(default_config)
|
80
|
+
orig_default_config = ConfigLoader.instance_variable_get(:@default_configuration)
|
81
|
+
|
82
|
+
result = yield default_config
|
83
|
+
|
84
|
+
ConfigLoader.instance_variable_set(:@default_configuration, orig_default_config)
|
85
|
+
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
# rubocop:disable Metrics/AbcSize
|
90
|
+
def load_plugin_rubocop_config(plugin, runner_context)
|
91
|
+
rules = plugin.rules(runner_context)
|
92
|
+
|
93
|
+
case rules.type
|
94
|
+
when :path
|
95
|
+
[ConfigLoader.load_file(rules.value, check: false), rules.value]
|
96
|
+
when :object
|
97
|
+
path = plugin.method(:rules).source_location[0]
|
98
|
+
[Config.create(rules.value, path, check: true), path]
|
99
|
+
when :error
|
100
|
+
plugin_name = plugin.about&.name || plugin.inspect
|
101
|
+
error_message = rules.value.respond_to?(:message) ? rules.value.message : rules.value
|
102
|
+
|
103
|
+
raise "Plugin `#{plugin_name}' failed to load with error: #{error_message}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# rubocop:enable Metrics/AbcSize
|
107
|
+
|
108
|
+
# This is how we ensure "first-in wins": plugins can override AllCops settings that are
|
109
|
+
# set by RuboCop's default configuration, but once a plugin sets an AllCop setting, they
|
110
|
+
# have exclusive first-in-wins rights to that setting.
|
111
|
+
#
|
112
|
+
# The one exception to this are array fields, because we don't want to
|
113
|
+
# overwrite the AllCops defaults but rather munge the arrays (`existing |
|
114
|
+
# new`) to allow plugins to add to the array, for example Include and
|
115
|
+
# Exclude paths and patterns.
|
116
|
+
def merge_all_cop_settings(existing_all_cops, new_all_cops, already_configured_keys)
|
117
|
+
return [existing_all_cops, already_configured_keys] unless new_all_cops.is_a?(Hash)
|
118
|
+
|
119
|
+
combined_all_cops = existing_all_cops.dup
|
120
|
+
combined_configured_keys = already_configured_keys.dup
|
121
|
+
|
122
|
+
new_all_cops.each do |key, value|
|
123
|
+
if combined_all_cops[key].is_a?(Array) && value.is_a?(Array)
|
124
|
+
combined_all_cops[key] |= value
|
125
|
+
combined_configured_keys |= [key]
|
126
|
+
elsif !combined_configured_keys.include?(key)
|
127
|
+
combined_all_cops[key] = value
|
128
|
+
combined_configured_keys << key
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
[combined_all_cops, combined_configured_keys]
|
133
|
+
end
|
134
|
+
|
135
|
+
def resolver
|
136
|
+
@resolver ||= ConfigLoaderResolver.new
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Plugin
|
5
|
+
# An exception raised when a plugin fails to load.
|
6
|
+
# @api private
|
7
|
+
class LoadError < Error
|
8
|
+
def initialize(plugin_name)
|
9
|
+
super
|
10
|
+
|
11
|
+
@plugin_name = plugin_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
<<~MESSAGE
|
16
|
+
Failed to load plugin `#{@plugin_name}` because the corresponding plugin class could not be determined for instantiation.
|
17
|
+
Try upgrading it first (e.g., `bundle update #{@plugin_name}`).
|
18
|
+
If `#{@plugin_name}` is not yet a plugin, use `require: #{@plugin_name}` instead of `plugins: `#{@plugin_name}` in your configuration.
|
19
|
+
|
20
|
+
For further assistance, check with the developer regarding the following points:
|
21
|
+
https://docs.rubocop.org/rubocop/plugin_migration_guide.html
|
22
|
+
MESSAGE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../feature_loader'
|
4
|
+
require_relative 'load_error'
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
module Plugin
|
8
|
+
# A class for loading and resolving plugins.
|
9
|
+
# @api private
|
10
|
+
class Loader
|
11
|
+
# rubocop:disable Layout/LineLength
|
12
|
+
DEFAULT_PLUGIN_CONFIG = {
|
13
|
+
'enabled' => true,
|
14
|
+
'require_path' => nil, # If not set, will be set to the plugin name
|
15
|
+
'plugin_class_name' => nil # If not set, looks for gemspec `spec.metadata["default_lint_roller_plugin"]`
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# rubocop:enable Layout/LineLength
|
19
|
+
class << self
|
20
|
+
def load(plugins)
|
21
|
+
normalized_plugin_configs = normalize(plugins)
|
22
|
+
normalized_plugin_configs.filter_map do |plugin_name, plugin_config|
|
23
|
+
next unless plugin_config['enabled']
|
24
|
+
|
25
|
+
plugin_class = constantize_plugin_from(plugin_name, plugin_config)
|
26
|
+
|
27
|
+
plugin_class.new(plugin_config)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
34
|
+
def normalize(plugin_configs)
|
35
|
+
plugin_configs.to_h do |plugin_config|
|
36
|
+
if plugin_config == Plugin::OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
|
37
|
+
warn Rainbow(<<~MESSAGE).yellow
|
38
|
+
Specify `rubocop-internal_affairs` instead of `rubocop/cop/internal_affairs` in your configuration.
|
39
|
+
MESSAGE
|
40
|
+
plugin_config = Plugin::INTERNAL_AFFAIRS_PLUGIN_NAME
|
41
|
+
end
|
42
|
+
|
43
|
+
if plugin_config.is_a?(Hash)
|
44
|
+
plugin_name = plugin_config.keys.first
|
45
|
+
|
46
|
+
[
|
47
|
+
plugin_name, DEFAULT_PLUGIN_CONFIG.merge(
|
48
|
+
{ 'require_path' => plugin_name }, plugin_config.values.first
|
49
|
+
)
|
50
|
+
]
|
51
|
+
# NOTE: Compatibility is maintained when `require: rubocop/cop/internal_affairs` remains
|
52
|
+
# specified in `.rubocop.yml`.
|
53
|
+
elsif (builtin_plugin_config = Plugin::BUILTIN_INTERNAL_PLUGINS[plugin_config])
|
54
|
+
[plugin_config, builtin_plugin_config]
|
55
|
+
else
|
56
|
+
[plugin_config, DEFAULT_PLUGIN_CONFIG.merge('require_path' => plugin_config)]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def constantize_plugin_from(plugin_name, plugin_config)
|
62
|
+
if plugin_name.is_a?(String) || plugin_name.is_a?(Symbol)
|
63
|
+
constantize(plugin_name, plugin_config)
|
64
|
+
else
|
65
|
+
plugin_name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# rubocop:enable Metrics/MethodLength
|
70
|
+
def constantize(plugin_name, plugin_config)
|
71
|
+
require_plugin(plugin_config['require_path'])
|
72
|
+
|
73
|
+
if (constant_name = plugin_config['plugin_class_name'])
|
74
|
+
begin
|
75
|
+
Kernel.const_get(constant_name)
|
76
|
+
rescue StandardError
|
77
|
+
raise <<~MESSAGE
|
78
|
+
Failed while configuring plugin `#{plugin_name}': no constant with name `#{constant_name}' was found.
|
79
|
+
MESSAGE
|
80
|
+
end
|
81
|
+
else
|
82
|
+
constantize_plugin_from_gemspec_metadata(plugin_name)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def require_plugin(require_path)
|
87
|
+
FeatureLoader.load(config_directory_path: Dir.pwd, feature: require_path)
|
88
|
+
end
|
89
|
+
|
90
|
+
def constantize_plugin_from_gemspec_metadata(plugin_name)
|
91
|
+
plugin_class_name = Gem.loaded_specs[plugin_name].metadata['default_lint_roller_plugin']
|
92
|
+
|
93
|
+
Kernel.const_get(plugin_class_name)
|
94
|
+
rescue LoadError, StandardError
|
95
|
+
raise Plugin::LoadError, plugin_name
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Plugin
|
5
|
+
# An exception raised when a plugin is not supported by the RuboCop engine.
|
6
|
+
# @api private
|
7
|
+
class NotSupportedError < Error
|
8
|
+
def initialize(unsupported_plugins)
|
9
|
+
super
|
10
|
+
|
11
|
+
@unsupported_plugins = unsupported_plugins
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
if @unsupported_plugins.one?
|
16
|
+
about = @unsupported_plugins.first.about
|
17
|
+
|
18
|
+
"#{about.name} #{about.version} is not a plugin supported by RuboCop engine."
|
19
|
+
else
|
20
|
+
unsupported_plugin_names = @unsupported_plugins.map do |plugin|
|
21
|
+
"#{plugin.about.name} #{plugin.about.version}"
|
22
|
+
end.join(', ')
|
23
|
+
|
24
|
+
"#{unsupported_plugin_names} are not plugins supported by RuboCop engine."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'plugin/configuration_integrator'
|
4
|
+
require_relative 'plugin/loader'
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
# Provides a plugin for RuboCop extensions that conform to lint_roller.
|
8
|
+
# https://github.com/standardrb/lint_roller
|
9
|
+
# @api private
|
10
|
+
module Plugin
|
11
|
+
BUILTIN_INTERNAL_PLUGINS = {
|
12
|
+
'rubocop-internal_affairs' => {
|
13
|
+
'enabled' => true,
|
14
|
+
'require_path' => 'rubocop/cop/internal_affairs/plugin',
|
15
|
+
'plugin_class_name' => 'RuboCop::InternalAffairs::Plugin'
|
16
|
+
}
|
17
|
+
}.freeze
|
18
|
+
INTERNAL_AFFAIRS_PLUGIN_NAME = Plugin::BUILTIN_INTERNAL_PLUGINS.keys.first
|
19
|
+
OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME = 'rubocop/cop/internal_affairs'
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def plugin_capable?(feature_name)
|
23
|
+
return true if BUILTIN_INTERNAL_PLUGINS.key?(feature_name)
|
24
|
+
return true if feature_name == OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
|
25
|
+
return false unless (gem = Gem.loaded_specs[feature_name])
|
26
|
+
|
27
|
+
!!gem.metadata['default_lint_roller_plugin']
|
28
|
+
end
|
29
|
+
|
30
|
+
def integrate_plugins(rubocop_config, plugins)
|
31
|
+
plugins = Plugin::Loader.load(plugins)
|
32
|
+
|
33
|
+
ConfigurationIntegrator.integrate_plugins_into_rubocop_config(rubocop_config, plugins)
|
34
|
+
|
35
|
+
plugins
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/rubocop/rake_task.rb
CHANGED
@@ -12,7 +12,8 @@ module RuboCop
|
|
12
12
|
# Use global Rake namespace here to avoid namespace issues with custom
|
13
13
|
# rubocop-rake tasks
|
14
14
|
class RakeTask < ::Rake::TaskLib
|
15
|
-
attr_accessor :name, :verbose, :fail_on_error, :patterns, :formatters, :
|
15
|
+
attr_accessor :name, :verbose, :fail_on_error, :patterns, :formatters, :plugins, :requires,
|
16
|
+
:options
|
16
17
|
|
17
18
|
def initialize(name = :rubocop, *args, &task_block)
|
18
19
|
super()
|
@@ -54,6 +55,7 @@ module RuboCop
|
|
54
55
|
|
55
56
|
def full_options
|
56
57
|
formatters.map { |f| ['--format', f] }.flatten
|
58
|
+
.concat(plugins.map { |plugin| ['--plugin', plugin] }.flatten)
|
57
59
|
.concat(requires.map { |r| ['--require', r] }.flatten)
|
58
60
|
.concat(options.flatten)
|
59
61
|
.concat(patterns)
|
@@ -64,6 +66,7 @@ module RuboCop
|
|
64
66
|
@verbose = true
|
65
67
|
@fail_on_error = true
|
66
68
|
@patterns = []
|
69
|
+
@plugins = []
|
67
70
|
@requires = []
|
68
71
|
@options = []
|
69
72
|
@formatters = []
|
@@ -13,6 +13,13 @@ module CopHelper
|
|
13
13
|
let(:parser_engine) { ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym }
|
14
14
|
let(:rails_version) { false }
|
15
15
|
|
16
|
+
before(:all) do
|
17
|
+
plugins = Gem.loaded_specs.filter_map do |feature_name, feature_specification|
|
18
|
+
feature_name if feature_specification.metadata['default_lint_roller_plugin']
|
19
|
+
end
|
20
|
+
RuboCop::Plugin.integrate_plugins(RuboCop::Config.new, plugins)
|
21
|
+
end
|
22
|
+
|
16
23
|
def inspect_source(source, file = nil)
|
17
24
|
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
|
18
25
|
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'digest'
|
4
4
|
require 'pathname'
|
5
|
+
require 'yaml'
|
5
6
|
require_relative '../cache_config'
|
6
7
|
require_relative '../config_finder'
|
8
|
+
require_relative '../path_util'
|
7
9
|
|
8
10
|
#
|
9
11
|
# This code is based on https://github.com/fohte/rubocop-daemon.
|
@@ -50,9 +52,11 @@ module RuboCop
|
|
50
52
|
end.find(&:exist?)
|
51
53
|
version_data = lockfile_path&.read || RuboCop::Version::STRING
|
52
54
|
config_data = Pathname(ConfigFinder.find_config_path(Dir.pwd)).read
|
53
|
-
|
55
|
+
yaml = YAML.safe_load(config_data, permitted_classes: [Regexp, Symbol], aliases: true)
|
56
|
+
inherit_from_data = inherit_from_data(yaml)
|
57
|
+
require_data = require_data(yaml)
|
54
58
|
|
55
|
-
Digest::SHA1.hexdigest(version_data + config_data +
|
59
|
+
Digest::SHA1.hexdigest(version_data + config_data + inherit_from_data + require_data)
|
56
60
|
end
|
57
61
|
# rubocop:enable Metrics/AbcSize
|
58
62
|
|
@@ -164,6 +168,35 @@ module RuboCop
|
|
164
168
|
def write_version_file(version)
|
165
169
|
version_path.write(version)
|
166
170
|
end
|
171
|
+
|
172
|
+
def inherit_from_data(yaml)
|
173
|
+
return '' unless (inherit_from_paths = yaml['inherit_from'])
|
174
|
+
|
175
|
+
Array(inherit_from_paths).map do |path|
|
176
|
+
next if PathUtil.remote_file?(path)
|
177
|
+
|
178
|
+
path = Pathname(path)
|
179
|
+
|
180
|
+
path.exist? ? path.read : ''
|
181
|
+
end.join
|
182
|
+
end
|
183
|
+
|
184
|
+
def require_data(yaml)
|
185
|
+
return '' unless (require_paths = yaml['require'])
|
186
|
+
|
187
|
+
Array(require_paths).map do |path|
|
188
|
+
# NOTE: This targets only relative or absolute path specifications.
|
189
|
+
# For example, specifications like `require: rubocop-performance`,
|
190
|
+
# which can be loaded from `$LOAD_PATH`, are ignored.
|
191
|
+
next unless path.start_with?('.', '/')
|
192
|
+
|
193
|
+
# NOTE: `.so` files are not typically specified, so only `.rb` files are targeted.
|
194
|
+
path = "#{path}.rb" unless path.end_with?('.rb')
|
195
|
+
path = Pathname(path)
|
196
|
+
|
197
|
+
path.exist? ? path.read : ''
|
198
|
+
end.join
|
199
|
+
end
|
167
200
|
end
|
168
201
|
end
|
169
202
|
end
|
data/lib/rubocop/server/cli.rb
CHANGED
@@ -86,7 +86,7 @@ module RuboCop
|
|
86
86
|
end
|
87
87
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
88
88
|
|
89
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
89
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
90
90
|
def run_command(server_command, detach:)
|
91
91
|
case server_command
|
92
92
|
when '--server'
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
Server::ClientCommand::Status.new.run
|
108
108
|
end
|
109
109
|
end
|
110
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
110
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
111
111
|
|
112
112
|
def fetch_cache_root_path_from(arguments)
|
113
113
|
cache_root = arguments.detect { |argument| argument.start_with?('--cache-root') }
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '1.
|
6
|
+
STRING = '1.72.1'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
@@ -63,9 +63,21 @@ module RuboCop
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# @api private
|
66
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
66
67
|
def self.extension_versions(env)
|
68
|
+
plugins = config_for_pwd(env).loaded_plugins
|
69
|
+
plugin_versions = plugins.filter_map do |plugin|
|
70
|
+
next if Plugin::BUILTIN_INTERNAL_PLUGINS.key?(plugin.about.name)
|
71
|
+
next unless (plugin_name = plugin.about.name)
|
72
|
+
|
73
|
+
" - #{plugin_name} #{plugin.about.version}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# TODO: It needs to be maintained for a while to ensure compatibility with extensions that
|
77
|
+
# don't support plugins. It should be removed in future once the old style becomes obsolete.
|
67
78
|
features = config_for_pwd(env).loaded_features.sort
|
68
|
-
features.
|
79
|
+
features -= plugins.map { |plugin| plugin.about.name }
|
80
|
+
feature_versions = features.filter_map do |loaded_feature|
|
69
81
|
next unless (match = loaded_feature.match(/rubocop-(?<feature>.*)/))
|
70
82
|
|
71
83
|
# Get the expected name of the folder containing the extension code.
|
@@ -84,7 +96,10 @@ module RuboCop
|
|
84
96
|
|
85
97
|
" - #{loaded_feature} #{feature_version}"
|
86
98
|
end
|
99
|
+
|
100
|
+
plugin_versions + feature_versions
|
87
101
|
end
|
102
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
88
103
|
|
89
104
|
# @api private
|
90
105
|
def self.target_ruby_version(env)
|
data/lib/rubocop.rb
CHANGED
@@ -304,6 +304,7 @@ require_relative 'rubocop/cop/lint/constant_definition_in_block'
|
|
304
304
|
require_relative 'rubocop/cop/lint/constant_overwritten_in_rescue'
|
305
305
|
require_relative 'rubocop/cop/lint/constant_reassignment'
|
306
306
|
require_relative 'rubocop/cop/lint/constant_resolution'
|
307
|
+
require_relative 'rubocop/cop/lint/cop_directive_syntax'
|
307
308
|
require_relative 'rubocop/cop/lint/debugger'
|
308
309
|
require_relative 'rubocop/cop/lint/deprecated_class_methods'
|
309
310
|
require_relative 'rubocop/cop/lint/deprecated_constants'
|
@@ -384,6 +385,7 @@ require_relative 'rubocop/cop/lint/redundant_require_statement'
|
|
384
385
|
require_relative 'rubocop/cop/lint/redundant_safe_navigation'
|
385
386
|
require_relative 'rubocop/cop/lint/redundant_splat_expansion'
|
386
387
|
require_relative 'rubocop/cop/lint/redundant_string_coercion'
|
388
|
+
require_relative 'rubocop/cop/lint/redundant_type_conversion'
|
387
389
|
require_relative 'rubocop/cop/lint/redundant_with_index'
|
388
390
|
require_relative 'rubocop/cop/lint/redundant_with_object'
|
389
391
|
require_relative 'rubocop/cop/lint/refinement_import_methods'
|
@@ -405,6 +407,7 @@ require_relative 'rubocop/cop/lint/shadowed_exception'
|
|
405
407
|
require_relative 'rubocop/cop/lint/shadowing_outer_local_variable'
|
406
408
|
require_relative 'rubocop/cop/lint/struct_new_override'
|
407
409
|
require_relative 'rubocop/cop/lint/suppressed_exception'
|
410
|
+
require_relative 'rubocop/cop/lint/suppressed_exception_in_number_conversion'
|
408
411
|
require_relative 'rubocop/cop/lint/symbol_conversion'
|
409
412
|
require_relative 'rubocop/cop/lint/syntax'
|
410
413
|
require_relative 'rubocop/cop/lint/to_enum_arguments'
|
@@ -425,6 +428,7 @@ require_relative 'rubocop/cop/lint/uri_escape_unescape'
|
|
425
428
|
require_relative 'rubocop/cop/lint/uri_regexp'
|
426
429
|
require_relative 'rubocop/cop/lint/useless_access_modifier'
|
427
430
|
require_relative 'rubocop/cop/lint/useless_assignment'
|
431
|
+
require_relative 'rubocop/cop/lint/useless_constant_scoping'
|
428
432
|
require_relative 'rubocop/cop/lint/useless_defined'
|
429
433
|
require_relative 'rubocop/cop/lint/useless_else_without_rescue'
|
430
434
|
require_relative 'rubocop/cop/lint/useless_method_definition'
|
@@ -604,6 +608,7 @@ require_relative 'rubocop/cop/style/redundant_each'
|
|
604
608
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
605
609
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
606
610
|
require_relative 'rubocop/cop/style/redundant_filter_chain'
|
611
|
+
require_relative 'rubocop/cop/style/redundant_format'
|
607
612
|
require_relative 'rubocop/cop/style/redundant_heredoc_delimiter_quotes'
|
608
613
|
require_relative 'rubocop/cop/style/redundant_initialize'
|
609
614
|
require_relative 'rubocop/cop/style/redundant_interpolation_unfreeze'
|