rubocop 1.66.1 → 1.67.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/config/default.yml +15 -6
- data/config/internal_affairs.yml +11 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/config_loader_resolver.rb +3 -3
- data/lib/rubocop/config_validator.rb +2 -1
- data/lib/rubocop/cop/base.rb +6 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
- data/lib/rubocop/cop/cop.rb +8 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +16 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +4 -5
- data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
- data/lib/rubocop/cop/lint/ensure_return.rb +0 -3
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +10 -4
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +105 -41
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +12 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -6
- data/lib/rubocop/cop/style/block_delimiters.rb +14 -1
- data/lib/rubocop/cop/style/collection_compact.rb +10 -10
- data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +1 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -3
- data/lib/rubocop/cop/style/lambda.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +53 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -7
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +4 -0
- data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
- data/lib/rubocop/cop/style/redundant_begin.rb +4 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +3 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +92 -50
- data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/team.rb +8 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +73 -34
- data/lib/rubocop/file_finder.rb +9 -4
- data/lib/rubocop/lsp/runtime.rb +2 -0
- data/lib/rubocop/lsp/server.rb +0 -1
- data/lib/rubocop/rspec/expect_offense.rb +1 -0
- data/lib/rubocop/runner.rb +3 -0
- data/lib/rubocop/server/cache.rb +6 -1
- data/lib/rubocop/server/core.rb +1 -0
- data/lib/rubocop/target_ruby.rb +12 -12
- data/lib/rubocop/version.rb +3 -1
- data/lib/rubocop/yaml_duplication_checker.rb +20 -27
- data/lib/rubocop.rb +2 -0
- metadata +10 -8
@@ -6,14 +6,38 @@ require 'fileutils'
|
|
6
6
|
# @api private
|
7
7
|
class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
8
8
|
include ::RuboCop::Cop::Documentation
|
9
|
+
CopData = Struct.new(
|
10
|
+
:cop, :description, :example_objects, :safety_objects, :see_objects, :config, keyword_init: true
|
11
|
+
)
|
12
|
+
|
13
|
+
STRUCTURE = {
|
14
|
+
name: ->(data) { cop_header(data.cop) },
|
15
|
+
required_ruby_version: ->(data) { required_ruby_version(data.cop) },
|
16
|
+
properties: ->(data) { properties(data.cop) },
|
17
|
+
description: ->(data) { "#{data.description}\n" },
|
18
|
+
safety: ->(data) { safety_object(data.safety_objects, data.cop) },
|
19
|
+
examples: ->(data) { examples(data.example_objects, data.cop) },
|
20
|
+
configuration: ->(data) { configurations(data.cop.department, data.config, data.cop) },
|
21
|
+
references: ->(data) { references(data.cop, data.see_objects) }
|
22
|
+
}.freeze
|
23
|
+
|
9
24
|
# This class will only generate documentation for cops that belong to one of
|
10
25
|
# the departments given in the `departments` array. E.g. if we only wanted
|
11
26
|
# documentation for Lint cops:
|
12
27
|
#
|
13
28
|
# CopsDocumentationGenerator.new(departments: ['Lint']).call
|
14
29
|
#
|
15
|
-
|
30
|
+
# You can append additional information:
|
31
|
+
#
|
32
|
+
# callback = ->(data) { required_rails_version(data.cop) }
|
33
|
+
# CopsDocumentationGenerator.new(extra_info: { ruby_version: callback }).call
|
34
|
+
#
|
35
|
+
# This will insert the string returned from the lambda _after_ the section from RuboCop itself.
|
36
|
+
# See `CopsDocumentationGenerator::STRUCTURE` for available sections.
|
37
|
+
#
|
38
|
+
def initialize(departments: [], extra_info: {})
|
16
39
|
@departments = departments.map(&:to_sym).sort!
|
40
|
+
@extra_info = extra_info
|
17
41
|
@cops = RuboCop::Cop::Registry.global
|
18
42
|
@config = RuboCop::ConfigLoader.default_configuration
|
19
43
|
@docs_path = "#{Dir.pwd}/docs/modules/ROOT/pages/"
|
@@ -37,24 +61,21 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
37
61
|
cops.with_department(department).sort!
|
38
62
|
end
|
39
63
|
|
40
|
-
def cops_body(
|
41
|
-
check_examples_to_have_the_default_enforced_style!(
|
42
|
-
|
43
|
-
content =
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
content << examples(examples_objects) if examples_objects.any?
|
49
|
-
content << configurations(cop.department, pars)
|
50
|
-
content << references(cop, see_objects)
|
64
|
+
def cops_body(data)
|
65
|
+
check_examples_to_have_the_default_enforced_style!(data.example_objects, data.cop)
|
66
|
+
|
67
|
+
content = +''
|
68
|
+
STRUCTURE.each do |section, block|
|
69
|
+
content << instance_exec(data, &block)
|
70
|
+
content << @extra_info[section].call(data) if @extra_info[section]
|
71
|
+
end
|
51
72
|
content
|
52
73
|
end
|
53
74
|
|
54
|
-
def check_examples_to_have_the_default_enforced_style!(
|
55
|
-
return if
|
75
|
+
def check_examples_to_have_the_default_enforced_style!(example_objects, cop)
|
76
|
+
return if example_objects.none?
|
56
77
|
|
57
|
-
examples_describing_enforced_style =
|
78
|
+
examples_describing_enforced_style = example_objects.map(&:name).grep(/EnforcedStyle:/)
|
58
79
|
return if examples_describing_enforced_style.none?
|
59
80
|
|
60
81
|
if examples_describing_enforced_style.index { |name| name.match?('default') }.nonzero?
|
@@ -66,16 +87,20 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
66
87
|
raise "Specify the default EnforcedStyle for #{cop.cop_name}"
|
67
88
|
end
|
68
89
|
|
69
|
-
def examples(
|
70
|
-
|
90
|
+
def examples(example_objects, cop)
|
91
|
+
return '' if example_objects.none?
|
92
|
+
|
93
|
+
example_objects.each_with_object(cop_subsection('Examples', cop).dup) do |example, content|
|
71
94
|
content << "\n" unless content.end_with?("\n\n")
|
72
|
-
content <<
|
95
|
+
content << example_header(example.name, cop) unless example.name == ''
|
73
96
|
content << code_example(example)
|
74
97
|
end
|
75
98
|
end
|
76
99
|
|
77
|
-
def safety_object(
|
78
|
-
|
100
|
+
def safety_object(safety_objects, cop)
|
101
|
+
return '' if safety_objects.all? { |s| s.text.blank? }
|
102
|
+
|
103
|
+
safety_objects.each_with_object(cop_subsection('Safety', cop).dup) do |safety_object, content|
|
79
104
|
next if safety_object.text.blank?
|
80
105
|
|
81
106
|
content << "\n" unless content.end_with?("\n\n")
|
@@ -115,22 +140,25 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
115
140
|
end
|
116
141
|
# rubocop:enable Metrics/MethodLength
|
117
142
|
|
118
|
-
def
|
143
|
+
def cop_header(cop)
|
119
144
|
content = +"\n"
|
120
|
-
content << "
|
145
|
+
content << "[##{to_anchor(cop.cop_name)}]\n"
|
146
|
+
content << "== #{cop.cop_name}\n"
|
121
147
|
content << "\n"
|
122
148
|
content
|
123
149
|
end
|
124
150
|
|
125
|
-
def
|
151
|
+
def cop_subsection(title, cop)
|
126
152
|
content = +"\n"
|
153
|
+
content << "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
127
154
|
content << "=== #{title}\n"
|
128
155
|
content << "\n"
|
129
156
|
content
|
130
157
|
end
|
131
158
|
|
132
|
-
def
|
133
|
-
content =
|
159
|
+
def example_header(title, cop)
|
160
|
+
content = "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
161
|
+
content << +"==== #{title}\n"
|
134
162
|
content << "\n"
|
135
163
|
content
|
136
164
|
end
|
@@ -142,7 +170,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
142
170
|
content
|
143
171
|
end
|
144
172
|
|
145
|
-
def configurations(department, pars)
|
173
|
+
def configurations(department, pars, cop)
|
146
174
|
return '' if pars.empty?
|
147
175
|
|
148
176
|
header = ['Name', 'Default value', 'Configurable values']
|
@@ -157,7 +185,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
157
185
|
[configuration_name(department, name), default, configurable]
|
158
186
|
end
|
159
187
|
|
160
|
-
|
188
|
+
cop_subsection('Configurable attributes', cop) + to_table(header, content)
|
161
189
|
end
|
162
190
|
|
163
191
|
def configuration_name(department, name)
|
@@ -235,7 +263,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
235
263
|
urls = RuboCop::Cop::MessageAnnotator.new(config, cop.name, cop_config, {}).urls
|
236
264
|
return '' if urls.empty? && see_objects.empty?
|
237
265
|
|
238
|
-
content =
|
266
|
+
content = cop_subsection('References', cop)
|
239
267
|
content << urls.map { |url| "* #{url}" }.join("\n")
|
240
268
|
content << "\n" unless urls.empty?
|
241
269
|
content << see_objects.map { |see| "* #{see.name}" }.join("\n")
|
@@ -283,14 +311,16 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
283
311
|
]
|
284
312
|
pars = cop_config.reject { |k| non_display_keys.include? k }
|
285
313
|
description = 'No documentation'
|
286
|
-
|
314
|
+
example_objects = safety_objects = see_objects = []
|
287
315
|
cop_code(cop) do |code_object|
|
288
316
|
description = code_object.docstring unless code_object.docstring.blank?
|
289
|
-
|
290
|
-
|
291
|
-
|
317
|
+
example_objects = code_object.tags('example')
|
318
|
+
safety_objects = code_object.tags('safety')
|
319
|
+
see_objects = code_object.tags('see')
|
292
320
|
end
|
293
|
-
|
321
|
+
data = CopData.new(cop: cop, description: description, example_objects: example_objects,
|
322
|
+
safety_objects: safety_objects, see_objects: see_objects, config: pars)
|
323
|
+
cops_body(data)
|
294
324
|
end
|
295
325
|
|
296
326
|
def cop_code(cop)
|
@@ -306,7 +336,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
306
336
|
filename = "#{department_to_basename(department)}.adoc"
|
307
337
|
content = +"=== Department xref:#{filename}[#{type_title}]\n\n"
|
308
338
|
cops_of_department(department).each do |cop|
|
309
|
-
anchor = cop.cop_name
|
339
|
+
anchor = to_anchor(cop.cop_name)
|
310
340
|
content << "* xref:#{filename}##{anchor}[#{cop.cop_name}]\n"
|
311
341
|
end
|
312
342
|
|
@@ -338,4 +368,13 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
338
368
|
|
339
369
|
status == 'pending' ? 'Pending' : 'Enabled'
|
340
370
|
end
|
371
|
+
|
372
|
+
# HTML anchor are somewhat limited in what characters they can contain, just
|
373
|
+
# accept a known-good subset. As long as it's consistent it doesn't matter.
|
374
|
+
#
|
375
|
+
# Style/AccessModifierDeclarations => styleaccessmodifierdeclarations
|
376
|
+
# OnlyFor: [] (default) => onlyfor_-__-_default_
|
377
|
+
def to_anchor(title)
|
378
|
+
title.delete('/').tr(' ', '-').gsub(/[^a-zA-Z0-9-]/, '_').downcase
|
379
|
+
end
|
341
380
|
end
|
data/lib/rubocop/file_finder.rb
CHANGED
@@ -23,15 +23,20 @@ module RuboCop
|
|
23
23
|
last_file
|
24
24
|
end
|
25
25
|
|
26
|
+
def traverse_directories_upwards(start_dir, stop_dir = nil)
|
27
|
+
Pathname.new(start_dir).expand_path.ascend do |dir|
|
28
|
+
yield(dir)
|
29
|
+
dir = dir.to_s
|
30
|
+
break if dir == stop_dir || dir == FileFinder.root_level
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
private
|
27
35
|
|
28
36
|
def traverse_files_upwards(filename, start_dir, stop_dir)
|
29
|
-
|
37
|
+
traverse_directories_upwards(start_dir, stop_dir) do |dir|
|
30
38
|
file = dir + filename
|
31
39
|
yield(file.to_s) if file.exist?
|
32
|
-
|
33
|
-
dir = dir.to_s
|
34
|
-
break if dir == stop_dir || dir == FileFinder.root_level
|
35
40
|
end
|
36
41
|
end
|
37
42
|
end
|
data/lib/rubocop/lsp/runtime.rb
CHANGED
data/lib/rubocop/lsp/server.rb
CHANGED
@@ -169,6 +169,7 @@ module RuboCop
|
|
169
169
|
raise 'Expected correction but no corrections were made' if new_source == source
|
170
170
|
|
171
171
|
expect(new_source).to eq(correction)
|
172
|
+
expect(@processed_source).to be_valid_syntax, 'Expected correction to be valid syntax'
|
172
173
|
end
|
173
174
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
174
175
|
|
data/lib/rubocop/runner.rb
CHANGED
@@ -362,6 +362,9 @@ module RuboCop
|
|
362
362
|
self.class.ruby_extractors.find do |ruby_extractor|
|
363
363
|
result = ruby_extractor.call(processed_source)
|
364
364
|
break result if result
|
365
|
+
rescue StandardError
|
366
|
+
raise Error, "Ruby extractor #{ruby_extractor.source_location[0]} failed to process " \
|
367
|
+
"#{processed_source.path}."
|
365
368
|
end
|
366
369
|
end
|
367
370
|
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -43,13 +43,18 @@ module RuboCop
|
|
43
43
|
@project_dir_cache_key ||= project_dir[1..].tr('/', '+')
|
44
44
|
end
|
45
45
|
|
46
|
+
# rubocop:disable Metrics/AbcSize
|
46
47
|
def restart_key
|
47
48
|
lockfile_path = LOCKFILE_NAMES.map do |lockfile_name|
|
48
49
|
Pathname(project_dir).join(lockfile_name)
|
49
50
|
end.find(&:exist?)
|
51
|
+
version_data = lockfile_path&.read || RuboCop::Version::STRING
|
52
|
+
config_data = Pathname(ConfigFinder.find_config_path(Dir.pwd)).read
|
53
|
+
todo_data = (rubocop_todo = Pathname('.rubocop_todo.yml')).exist? ? rubocop_todo.read : ''
|
50
54
|
|
51
|
-
Digest::SHA1.hexdigest(
|
55
|
+
Digest::SHA1.hexdigest(version_data + config_data + todo_data)
|
52
56
|
end
|
57
|
+
# rubocop:enable Metrics/AbcSize
|
53
58
|
|
54
59
|
def dir
|
55
60
|
Pathname.new(File.join(cache_path, project_dir_cache_key)).tap do |d|
|
data/lib/rubocop/server/core.rb
CHANGED
data/lib/rubocop/target_ruby.rb
CHANGED
@@ -53,8 +53,6 @@ module RuboCop
|
|
53
53
|
class GemspecFile < Source
|
54
54
|
extend NodePattern::Macros
|
55
55
|
|
56
|
-
GEMSPEC_EXTENSION = '.gemspec'
|
57
|
-
|
58
56
|
# @!method required_ruby_version(node)
|
59
57
|
def_node_search :required_ruby_version, <<~PATTERN
|
60
58
|
(send _ :required_ruby_version= $_)
|
@@ -68,7 +66,7 @@ module RuboCop
|
|
68
66
|
PATTERN
|
69
67
|
|
70
68
|
def name
|
71
|
-
"`required_ruby_version` parameter (in #{
|
69
|
+
"`required_ruby_version` parameter (in #{gemspec_filepath})"
|
72
70
|
end
|
73
71
|
|
74
72
|
private
|
@@ -83,16 +81,18 @@ module RuboCop
|
|
83
81
|
find_minimal_known_ruby(right_hand_side)
|
84
82
|
end
|
85
83
|
|
86
|
-
def gemspec_filename
|
87
|
-
@gemspec_filename ||= begin
|
88
|
-
basename = Pathname.new(@config.base_dir_for_path_parameters).basename.to_s
|
89
|
-
"#{basename}#{GEMSPEC_EXTENSION}"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
84
|
def gemspec_filepath
|
94
|
-
@gemspec_filepath
|
95
|
-
|
85
|
+
return @gemspec_filepath if defined?(@gemspec_filepath)
|
86
|
+
|
87
|
+
@gemspec_filepath =
|
88
|
+
@config.traverse_directories_upwards(@config.base_dir_for_path_parameters) do |dir|
|
89
|
+
# NOTE: Can't use `dir.glob` because of JRuby 9.4.8.0 incompatibility:
|
90
|
+
# https://github.com/jruby/jruby/issues/8358
|
91
|
+
candidates = Pathname.glob("#{dir}/*.gemspec")
|
92
|
+
# Bundler will use a gemspec whatever the filename is, as long as its the only one in
|
93
|
+
# the folder.
|
94
|
+
break candidates.first if candidates.one?
|
95
|
+
end
|
96
96
|
end
|
97
97
|
|
98
98
|
def version_from_gemspec_file(file)
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,10 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '1.
|
6
|
+
STRING = '1.67.0'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
10
|
+
'analyzing as Ruby %<target_ruby_version>s, ' \
|
10
11
|
'running on %<ruby_engine>s %<ruby_version>s)%<server_mode>s [%<ruby_platform>s]'
|
11
12
|
|
12
13
|
CANONICAL_FEATURE_NAMES = {
|
@@ -22,6 +23,7 @@ module RuboCop
|
|
22
23
|
if debug
|
23
24
|
verbose_version = format(MSG, version: STRING, parser_version: parser_version,
|
24
25
|
rubocop_ast_version: RuboCop::AST::Version::STRING,
|
26
|
+
target_ruby_version: TargetRuby.new(Config.new).version,
|
25
27
|
ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
|
26
28
|
server_mode: server_mode,
|
27
29
|
ruby_platform: RUBY_PLATFORM)
|
@@ -5,37 +5,30 @@ module RuboCop
|
|
5
5
|
# @api private
|
6
6
|
module YAMLDuplicationChecker
|
7
7
|
def self.check(yaml_string, filename, &on_duplicated)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
YAML.parse(yaml_string, filename: filename)
|
13
|
-
else
|
14
|
-
YAML.parse(yaml_string, filename)
|
15
|
-
end
|
16
|
-
return unless tree
|
17
|
-
|
18
|
-
traverse(tree, &on_duplicated)
|
19
|
-
tree
|
8
|
+
handler = DuplicationCheckHandler.new(&on_duplicated)
|
9
|
+
parser = Psych::Parser.new(handler)
|
10
|
+
parser.parse(yaml_string, filename)
|
11
|
+
parser.handler.root.children[0]
|
20
12
|
end
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
yield(exist, key) if exist
|
28
|
-
keys << key
|
29
|
-
traverse(value, &on_duplicated)
|
30
|
-
end
|
31
|
-
else
|
32
|
-
children = tree.children
|
33
|
-
return unless children
|
14
|
+
class DuplicationCheckHandler < Psych::TreeBuilder # :nodoc:
|
15
|
+
def initialize(&block)
|
16
|
+
super()
|
17
|
+
@block = block
|
18
|
+
end
|
34
19
|
|
35
|
-
|
20
|
+
def end_mapping
|
21
|
+
mapping_node = super
|
22
|
+
# OPTIMIZE: Use a hash for faster lookup since there can
|
23
|
+
# be quite a few keys at the top-level.
|
24
|
+
keys = {}
|
25
|
+
mapping_node.children.each_slice(2) do |key, _value|
|
26
|
+
duplicate = keys[key.value]
|
27
|
+
@block.call(duplicate, key) if duplicate
|
28
|
+
keys[key.value] = key
|
29
|
+
end
|
30
|
+
mapping_node
|
36
31
|
end
|
37
32
|
end
|
38
|
-
|
39
|
-
private_class_method :traverse
|
40
33
|
end
|
41
34
|
end
|
data/lib/rubocop.rb
CHANGED
@@ -312,6 +312,7 @@ require_relative 'rubocop/cop/lint/duplicate_methods'
|
|
312
312
|
require_relative 'rubocop/cop/lint/duplicate_regexp_character_class_element'
|
313
313
|
require_relative 'rubocop/cop/lint/duplicate_require'
|
314
314
|
require_relative 'rubocop/cop/lint/duplicate_rescue_exception'
|
315
|
+
require_relative 'rubocop/cop/lint/duplicate_set_element'
|
315
316
|
require_relative 'rubocop/cop/lint/each_with_object_argument'
|
316
317
|
require_relative 'rubocop/cop/lint/else_layout'
|
317
318
|
require_relative 'rubocop/cop/lint/empty_block'
|
@@ -750,6 +751,7 @@ require_relative 'rubocop/config_store'
|
|
750
751
|
require_relative 'rubocop/config_validator'
|
751
752
|
require_relative 'rubocop/feature_loader'
|
752
753
|
require_relative 'rubocop/lockfile'
|
754
|
+
require_relative 'rubocop/lsp'
|
753
755
|
require_relative 'rubocop/target_finder'
|
754
756
|
require_relative 'rubocop/directive_comment'
|
755
757
|
require_relative 'rubocop/comment_config'
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.67.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-
|
13
|
+
date: 2024-10-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -179,6 +179,7 @@ files:
|
|
179
179
|
- assets/output.css.erb
|
180
180
|
- assets/output.html.erb
|
181
181
|
- config/default.yml
|
182
|
+
- config/internal_affairs.yml
|
182
183
|
- config/obsoletion.yml
|
183
184
|
- exe/rubocop
|
184
185
|
- lib/rubocop.rb
|
@@ -425,6 +426,7 @@ files:
|
|
425
426
|
- lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb
|
426
427
|
- lib/rubocop/cop/lint/duplicate_require.rb
|
427
428
|
- lib/rubocop/cop/lint/duplicate_rescue_exception.rb
|
429
|
+
- lib/rubocop/cop/lint/duplicate_set_element.rb
|
428
430
|
- lib/rubocop/cop/lint/each_with_object_argument.rb
|
429
431
|
- lib/rubocop/cop/lint/else_layout.rb
|
430
432
|
- lib/rubocop/cop/lint/empty_block.rb
|
@@ -1017,12 +1019,12 @@ licenses:
|
|
1017
1019
|
- MIT
|
1018
1020
|
metadata:
|
1019
1021
|
homepage_uri: https://rubocop.org/
|
1020
|
-
changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.
|
1022
|
+
changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.67.0
|
1021
1023
|
source_code_uri: https://github.com/rubocop/rubocop/
|
1022
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
1024
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.67/
|
1023
1025
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
1024
1026
|
rubygems_mfa_required: 'true'
|
1025
|
-
post_install_message:
|
1027
|
+
post_install_message:
|
1026
1028
|
rdoc_options: []
|
1027
1029
|
require_paths:
|
1028
1030
|
- lib
|
@@ -1037,8 +1039,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1037
1039
|
- !ruby/object:Gem::Version
|
1038
1040
|
version: '0'
|
1039
1041
|
requirements: []
|
1040
|
-
rubygems_version: 3.
|
1041
|
-
signing_key:
|
1042
|
+
rubygems_version: 3.3.7
|
1043
|
+
signing_key:
|
1042
1044
|
specification_version: 4
|
1043
1045
|
summary: Automatic Ruby code style checking tool.
|
1044
1046
|
test_files: []
|