rubocop 1.86.0 → 1.86.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8991e66e8594a8ba30b4122a2990df1d7f610e3e51515b016e68432bcd94855
4
- data.tar.gz: dadc1936594395ec71c4b628867d1ed2e2f585fcafedb886e5493d0b81c4cb2f
3
+ metadata.gz: e7e3463c6020de496396b13ecf80f691f532af83ac8f8627286f3887f07b11b2
4
+ data.tar.gz: 9e8c332d0f33ea078abcc71e0ddb7cd009497842a026dfdcae103a63fc909ba6
5
5
  SHA512:
6
- metadata.gz: f95a7d048724e297f77b42444bd2eae15889bfa1b9b815fabbde131af75e99e114ab6ba2b4c0d078c937be9abd899ec7d9fb0650354b4bfd3cfb5a554f4bcfc3
7
- data.tar.gz: ed088266152e384f4c2c82dead8363ced3c990b6492a4b4652f98a548ec16b0c57da73e1295dbbc302b00c5affd3fe2e540d9c012221068449d733d1c812139c
6
+ metadata.gz: 0f0d7cff4de9dc7d8f04cdea8f8f28d6e45d5c0676a40ca67daa4e3fd6e3397363d2c2f4b368b5bcbb165d7478bdfb33c5352c49d2fd52896f8aa6d488e017cc
7
+ data.tar.gz: 357c3047ffea023a5c10162e4e2f2ee782796b5ca87d7c4413bde296d284c41362033ca9d997609ac6d9eceea7227b46e240150340a8a26cad8071bc5cce33c7
data/config/default.yml CHANGED
@@ -4796,7 +4796,6 @@ Style/ModuleMemberExistenceCheck:
4796
4796
  Description: 'Checks for usage of `Module` methods returning arrays that can be replaced with equivalent predicates.'
4797
4797
  Enabled: pending
4798
4798
  VersionAdded: '1.82'
4799
- AllowedMethods: []
4800
4799
 
4801
4800
  Style/MultilineBlockChain:
4802
4801
  Description: 'Avoid multi-line chains of blocks.'
@@ -5112,7 +5111,11 @@ Style/OneClassPerFile:
5112
5111
  Description: 'Checks that each source file defines at most one top-level class or module.'
5113
5112
  Enabled: pending
5114
5113
  VersionAdded: '1.85'
5114
+ VersionChanged: '1.86'
5115
5115
  AllowedClasses: []
5116
+ Exclude:
5117
+ - 'spec/**/*'
5118
+ - 'test/**/*'
5116
5119
 
5117
5120
  Style/OneLineConditional:
5118
5121
  Description: >-
@@ -5557,9 +5560,10 @@ Style/RedundantStringEscape:
5557
5560
 
5558
5561
  Style/RedundantStructKeywordInit:
5559
5562
  Description: 'Checks for redundant `keyword_init` option for `Struct.new`.'
5560
- Enabled: pending
5563
+ Enabled: false
5561
5564
  SafeAutoCorrect: false
5562
5565
  VersionAdded: '1.85'
5566
+ VersionChanged: '1.86'
5563
5567
 
5564
5568
  Style/RegexpLiteral:
5565
5569
  Description: 'Use / or %r around regular expressions.'
@@ -217,6 +217,9 @@ module RuboCop
217
217
  for_all_cops['StringLiteralsFrozenByDefault']
218
218
  end
219
219
 
220
+ # Returns true if the file matches any include pattern. If a block is given, the block is called
221
+ # to determine if the pattern is relevant (true returned by the block) or should be skipped
222
+ # (false returned).
220
223
  def file_to_include?(file)
221
224
  relative_file_path = path_relative_to_config(file)
222
225
 
@@ -228,11 +231,9 @@ module RuboCop
228
231
  absolute_file_path = File.expand_path(file)
229
232
 
230
233
  patterns_to_include.any? do |pattern|
231
- if block_given?
232
- yield pattern, relative_file_path, absolute_file_path
233
- else
234
- match_path?(pattern, relative_file_path) || match_path?(pattern, absolute_file_path)
235
- end
234
+ next if block_given? && !yield(pattern)
235
+
236
+ match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
236
237
  end
237
238
  end
238
239
 
@@ -242,10 +243,7 @@ module RuboCop
242
243
  # `bundler-console` conveys `Bundler::Console`).
243
244
  return true if File.extname(file) == '.gemspec'
244
245
 
245
- file_to_include?(file) do |pattern, relative_path, absolute_path|
246
- /[A-Z]/.match?(pattern.to_s) &&
247
- (match_path?(pattern, relative_path) || match_path?(pattern, absolute_path))
248
- end
246
+ file_to_include?(file) { |pattern| /[A-Z]/.match?(pattern.to_s) }
249
247
  end
250
248
 
251
249
  # Returns true if there's a chance that an Include pattern matches hidden
@@ -345,6 +343,12 @@ module RuboCop
345
343
 
346
344
  private
347
345
 
346
+ def match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
347
+ should_use_absolute_path = absolute?(pattern.to_s) || pattern.to_s.start_with?('..') ||
348
+ relative_file_path.start_with?('..')
349
+ match_path?(pattern, should_use_absolute_path ? absolute_file_path : relative_file_path)
350
+ end
351
+
348
352
  # @return [Float, nil] The Rails version as a `major.minor` Float.
349
353
  def target_rails_version_from_bundler_lock_file
350
354
  @target_rails_version_from_bundler_lock_file ||= read_rails_version_from_bundler_lock_file
@@ -45,6 +45,7 @@ module RuboCop
45
45
  base_config.each do |k, v|
46
46
  next unless v.is_a?(Hash)
47
47
 
48
+ only_base_has_include = v.key?('Include') && !hash.dig(k, 'Include')
48
49
  if hash.key?(k)
49
50
  v = merge(v, hash[k],
50
51
  cop_name: k, file: file, debug: debug,
@@ -52,7 +53,7 @@ module RuboCop
52
53
  inherit_mode: determine_inherit_mode(hash, k))
53
54
  end
54
55
  hash[k] = v
55
- fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
56
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if only_base_has_include
56
57
  end
57
58
  end
58
59
  end
@@ -55,10 +55,9 @@ module RuboCop
55
55
 
56
56
  # @api private
57
57
  def builtin?(cop_class)
58
- # any custom method will do
59
- return false unless (m = cop_class.instance_methods(false).first)
58
+ return false unless (name = cop_class.name)
60
59
 
61
- path, _line = cop_class.instance_method(m).source_location
60
+ path, _line = Module.const_source_location(name)
62
61
  path.start_with?(__dir__)
63
62
  end
64
63
  end
@@ -111,7 +111,7 @@ module RuboCop
111
111
  def contains_guard_clause?(node)
112
112
  return false unless (branch = node.if_branch)
113
113
 
114
- guard_clause_branch?(branch)
114
+ branch.guard_clause? || guard_clause_branch?(branch)
115
115
  end
116
116
 
117
117
  def next_line_empty_or_allowed_directive_comment?(line)
@@ -123,6 +123,7 @@ module RuboCop
123
123
  AlignmentCorrector.align_end(corrector, processed_source, node, alignment_node(node))
124
124
  end
125
125
 
126
+ # rubocop:disable Metrics/CyclomaticComplexity
126
127
  def check_assignment(node, rhs)
127
128
  # If there are method calls chained to the right hand side of the
128
129
  # assignment, we let rhs be the receiver of those method calls before
@@ -131,13 +132,14 @@ module RuboCop
131
132
 
132
133
  # If `rhs` is a `begin` node or a logical operator,
133
134
  # unwrap to find the leading conditional.
134
- rhs = rhs.child_nodes.first while rhs.type?(:begin, :or, :and)
135
+ rhs = rhs.child_nodes.first while rhs&.type?(:begin, :or, :and)
135
136
 
136
- return unless rhs.conditional?
137
+ return unless rhs&.conditional?
137
138
  return if rhs.if_type? && rhs.ternary?
138
139
 
139
140
  check_asgn_alignment(node, rhs)
140
141
  end
142
+ # rubocop:enable Metrics/CyclomaticComplexity
141
143
 
142
144
  def check_asgn_alignment(outer_node, inner_node)
143
145
  align_with = {
@@ -406,9 +406,11 @@ module RuboCop
406
406
  end
407
407
 
408
408
  def string_delimiter(node)
409
- delimiter = node.loc.begin
410
- delimiter ||= node.parent.loc.begin if node.parent&.dstr_type? && node.parent.loc?(:begin)
411
- delimiter = delimiter&.source
409
+ delimiter = if node.loc?(:begin)
410
+ node.loc.begin
411
+ elsif node.parent&.dstr_type? && node.parent.loc?(:begin)
412
+ node.parent.loc.begin
413
+ end&.source
412
414
 
413
415
  delimiter if %w[' "].include?(delimiter)
414
416
  end
@@ -308,7 +308,7 @@ module RuboCop
308
308
  def anonymous_class_block(node)
309
309
  first_block = node.each_ancestor(:block).first
310
310
  return unless class_or_module_new_block?(first_block)
311
- return if first_block.parent&.type?(:lvasgn, :block)
311
+ return if first_block.parent&.type?(:lvasgn)
312
312
  return if node.each_ancestor(:sclass).any? { |s| !s.children.first.self_type? }
313
313
 
314
314
  first_block
@@ -316,15 +316,20 @@ module RuboCop
316
316
 
317
317
  def anon_block_scope_id(anon_block)
318
318
  parent = anon_block.parent
319
- return unless parent&.call_type?
319
+ return unless parent&.type?(:any_block, :begin, :call, :casgn, :any_def)
320
320
 
321
- if parent.receiver
322
- "#{parent.receiver.source}.#{parent.method_name}"
323
- else
321
+ if (receiver = named_receiver(parent))
322
+ "#{receiver.source}.#{parent.method_name}"
323
+ elsif !parent.begin_type? || parent.parent&.any_block_type?
324
324
  source_location(anon_block)
325
325
  end
326
326
  end
327
327
 
328
+ def named_receiver(node)
329
+ receiver = node.receiver
330
+ receiver unless class_or_module_new_block?(receiver)
331
+ end
332
+
328
333
  def found_sclass_method(node, name)
329
334
  singleton_ancestor = node.each_ancestor.find(&:sclass_type?)
330
335
  return unless singleton_ancestor
@@ -26,7 +26,31 @@ module RuboCop
26
26
  "#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
27
27
  'configure using `TargetRubyVersion` parameter, under `AllCops`)'
28
28
  end
29
- add_offense(diagnostic.location, message: message, severity: diagnostic.level)
29
+ location = diagnostic_location(diagnostic.location)
30
+ add_offense(location, message: message, severity: diagnostic.level)
31
+ end
32
+
33
+ # Expand zero-length diagnostic ranges so that editors and formatters
34
+ # can display them. This typically occurs when the parser reports
35
+ # `unexpected token $end` at EOF.
36
+ def diagnostic_location(location)
37
+ return location if location.size.positive?
38
+
39
+ source_buffer = location.source_buffer
40
+ if location.end_pos < source_buffer.source.size
41
+ location.resize(1)
42
+ elsif location.begin_pos.positive?
43
+ location.adjust(begin_pos: -1)
44
+ else
45
+ location
46
+ end
47
+ end
48
+
49
+ # Override to skip multiline_ranges check which requires AST.
50
+ # Syntax errors mean the AST is nil, so we go directly to
51
+ # the EOL comment insertion path.
52
+ def disable_offense(offense_range)
53
+ disable_offense_with_eol_or_surround_comment(offense_range)
30
54
  end
31
55
 
32
56
  def add_offense_from_error(error)
@@ -95,10 +95,20 @@ module RuboCop
95
95
  return unless variable.method_argument?
96
96
  return if variable.keyword_argument? && cop_config['AllowUnusedKeywordArguments']
97
97
  return if ignored_method?(variable.scope.node.body)
98
+ return if block_argument_with_yield?(variable)
98
99
 
99
100
  super
100
101
  end
101
102
 
103
+ def block_argument_with_yield?(variable)
104
+ return false unless variable.declaration_node.blockarg_type?
105
+
106
+ method_body = variable.scope.node.body
107
+ return false unless method_body
108
+
109
+ method_body.yield_type? || method_body.each_descendant(:yield).any?
110
+ end
111
+
102
112
  def ignored_method?(body)
103
113
  (cop_config['IgnoreEmptyMethods'] && body.nil?) ||
104
114
  (cop_config['IgnoreNotImplementedMethods'] && not_implemented?(body))
@@ -84,14 +84,13 @@ module RuboCop
84
84
 
85
85
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
86
86
  def sole_condition_of_parent_if?(node)
87
+ child = node
87
88
  parent = node.parent
88
89
 
89
90
  while parent
90
91
  if parent.if_type?
91
92
  condition = parent.condition
92
- if condition == node || (condition.csend_type? && !condition.receiver.equal?(node))
93
- return true
94
- end
93
+ return true if !child.equal?(condition) && non_nil_condition?(condition, node)
95
94
 
96
95
  parent = find_top_if(parent) if parent.elsif?
97
96
  elsif else_branch?(parent)
@@ -99,6 +98,7 @@ module RuboCop
99
98
  parent = parent.parent
100
99
  end
101
100
 
101
+ child = parent
102
102
  parent = parent&.parent
103
103
  end
104
104
 
@@ -106,6 +106,12 @@ module RuboCop
106
106
  end
107
107
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
108
108
 
109
+ def non_nil_condition?(condition, node)
110
+ return true if condition == node
111
+
112
+ condition.csend_type? && csend_root_receiver(condition) == node
113
+ end
114
+
109
115
  def else_branch?(node)
110
116
  node.parent&.if_type? && node.parent.else_branch == node
111
117
  end
@@ -115,6 +121,14 @@ module RuboCop
115
121
 
116
122
  node
117
123
  end
124
+
125
+ def csend_root_receiver(node)
126
+ return unless (receiver = node.receiver)
127
+
128
+ receiver = receiver.receiver while receiver.call_type? && receiver.receiver
129
+
130
+ receiver
131
+ end
118
132
  end
119
133
  end
120
134
  end
@@ -348,8 +348,20 @@ module RuboCop
348
348
 
349
349
  def remove_modifier_node_within_begin(corrector, modifier_node, begin_node)
350
350
  def_node = begin_node.children[begin_node.children.index(modifier_node) + 1]
351
- range = modifier_node.source_range.begin.join(def_node.source_range.begin)
352
- corrector.remove(range)
351
+ # Stop the removal range at the first comment that precedes the def, if
352
+ # any exist. Without this, comments between the modifier and the def are
353
+ # dropped because they fall inside the removed range.
354
+ end_pos = first_comment_or_node_start(def_node)
355
+ corrector.remove(modifier_node.source_range.begin.join(end_pos))
356
+ end
357
+
358
+ def first_comment_or_node_start(node)
359
+ preceding = processed_source.ast_with_comments[node].select do |comment|
360
+ comment.loc.line < node.loc.line
361
+ end
362
+ return node.source_range.begin if preceding.empty?
363
+
364
+ preceding.first.source_range.begin
353
365
  end
354
366
 
355
367
  def def_source(node, def_nodes)
@@ -224,15 +224,18 @@ module RuboCop
224
224
  end
225
225
 
226
226
  def find_heredoc_argument(node)
227
- return unless node&.call_type?
227
+ return unless node
228
228
 
229
- last_arg = node.last_argument
229
+ node = node.children.first while node.begin_type?
230
+ return node if heredoc?(node)
231
+ return unless node.call_type?
230
232
 
231
- if heredoc?(last_arg)
232
- last_arg
233
- elsif last_arg&.call_type?
234
- find_heredoc_argument(last_arg)
233
+ node.arguments.reverse_each do |argument|
234
+ heredoc_argument = find_heredoc_argument(argument)
235
+ return heredoc_argument if heredoc_argument
235
236
  end
237
+
238
+ find_heredoc_argument(node.receiver)
236
239
  end
237
240
 
238
241
  def autocorrect_heredoc_argument(corrector, node, heredoc_node, leave_branch, guard)
@@ -85,7 +85,7 @@ module RuboCop
85
85
  private
86
86
 
87
87
  def autocorrect(corrector, node)
88
- if then?(node)
88
+ if node.then?
89
89
  # If the nested `if` is a then node, correct it first,
90
90
  # then the next pass will use `correct_to_elsif_from_if_inside_else_form`
91
91
  IfThenCorrector.new(node, indentation: 0).call(corrector)
@@ -124,10 +124,6 @@ module RuboCop
124
124
  corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
125
125
  end
126
126
 
127
- def then?(node)
128
- node.loc.begin&.source == 'then'
129
- end
130
-
131
127
  def find_end_range(node)
132
128
  end_range = node.loc.end
133
129
  return end_range if end_range
@@ -32,7 +32,6 @@ module RuboCop
32
32
  # Array.private_instance_methods.include?(:foo)
33
33
  # Array.protected_instance_methods.include?(:foo)
34
34
  # Array.public_instance_methods.include?(:foo)
35
- # Array.included_modules.include?(:foo)
36
35
  #
37
36
  # # good
38
37
  # Array.class_variable_defined?(:foo)
@@ -40,15 +39,8 @@ module RuboCop
40
39
  # Array.private_method_defined?(:foo)
41
40
  # Array.protected_method_defined?(:foo)
42
41
  # Array.public_method_defined?(:foo)
43
- # Array.include?(:foo)
44
- #
45
- # @example AllowedMethods: [included_modules]
46
- #
47
- # # good
48
- # Array.included_modules.include?(:foo)
49
42
  #
50
43
  class ModuleMemberExistenceCheck < Base
51
- include AllowedMethods
52
44
  extend AutoCorrector
53
45
 
54
46
  MSG = 'Use `%<replacement>s` instead.'
@@ -64,14 +56,13 @@ module RuboCop
64
56
  METHOD_REPLACEMENTS = {
65
57
  class_variables: :class_variable_defined?,
66
58
  constants: :const_defined?,
67
- included_modules: :include?,
68
59
  instance_methods: :method_defined?,
69
60
  private_instance_methods: :private_method_defined?,
70
61
  protected_instance_methods: :protected_method_defined?,
71
62
  public_instance_methods: :public_method_defined?
72
63
  }.freeze
73
64
 
74
- METHODS_WITHOUT_INHERIT_PARAM = Set[:class_variables, :included_modules].freeze
65
+ METHODS_WITHOUT_INHERIT_PARAM = Set[:class_variables].freeze
75
66
  METHODS_WITH_INHERIT_PARAM =
76
67
  (METHOD_REPLACEMENTS.keys.to_set - METHODS_WITHOUT_INHERIT_PARAM).freeze
77
68
 
@@ -81,7 +72,6 @@ module RuboCop
81
72
  return unless (parent = node.parent)
82
73
  return unless module_member_inclusion?(parent)
83
74
  return unless simple_method_argument?(node) && simple_method_argument?(parent)
84
- return if allowed_method?(node.method_name)
85
75
 
86
76
  offense_range = node.location.selector.join(parent.source_range.end)
87
77
  replacement = replacement_for(node, parent)
@@ -13,30 +13,50 @@ module RuboCop
13
13
  # classes that logically belong with the main class.
14
14
  #
15
15
  # @example
16
- # # bad
16
+ # # bad - Multiple top-level classes
17
17
  # class Foo
18
18
  # end
19
19
  #
20
20
  # class Bar
21
21
  # end
22
22
  #
23
- # # bad
23
+ # # bad - Multiple top-level modules
24
+ # module Foo
25
+ # end
26
+ #
27
+ # module Bar
28
+ # end
29
+ #
30
+ # # bad - A top-level class and a top-level module
24
31
  # class Foo
25
32
  # end
26
33
  #
27
34
  # module Bar
28
35
  # end
29
36
  #
30
- # # good
37
+ # # good - A single top-level class
31
38
  # class Foo
32
39
  # end
33
40
  #
34
- # # good
41
+ # # good - A single top-level module
42
+ # module Foo
43
+ # end
44
+ #
45
+ # # good - Nested classes within a single top-level class
35
46
  # class Foo
36
47
  # class Bar
37
48
  # end
38
49
  # end
39
50
  #
51
+ # # good - Multiple classes within a single top-level module
52
+ # module Foo
53
+ # class Bar
54
+ # end
55
+ #
56
+ # class Baz
57
+ # end
58
+ # end
59
+ #
40
60
  # @example AllowedClasses: ['AllowedClass']
41
61
  # # good
42
62
  # class Foo
@@ -82,6 +82,7 @@ module RuboCop
82
82
  tIDENTIFIER kBREAK kNEXT kRETURN kSUPER kYIELD
83
83
  ].freeze
84
84
  ARITHMETIC_OPERATOR_TOKENS = %i[tDIVIDE tDSTAR tMINUS tPERCENT tPLUS tSTAR2].freeze
85
+ STRING_LITERAL_BEGIN_TOKENS = %i[tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tSYMBEG].freeze
85
86
 
86
87
  def on_new_investigation
87
88
  return unless processed_source.ast
@@ -105,6 +106,7 @@ module RuboCop
105
106
  string_concatenation?(range.source_line) ||
106
107
  start_with_arithmetic_operator?(range) ||
107
108
  inside_string_literal_or_method_with_argument?(range) ||
109
+ inside_string_literal_with_interpolation?(range) ||
108
110
  leading_dot_method_chain_with_blank_line?(range)
109
111
  end
110
112
 
@@ -132,6 +134,20 @@ module RuboCop
132
134
  end
133
135
  end
134
136
 
137
+ def inside_string_literal_with_interpolation?(range)
138
+ string_depth = 0
139
+ processed_source.tokens.each do |token|
140
+ break if token.pos.begin_pos >= range.begin_pos
141
+
142
+ if STRING_LITERAL_BEGIN_TOKENS.include?(token.type)
143
+ string_depth += 1
144
+ elsif token.type == :tSTRING_END
145
+ string_depth -= 1
146
+ end
147
+ end
148
+ string_depth.positive?
149
+ end
150
+
135
151
  def leading_dot_method_chain_with_blank_line?(range)
136
152
  return false unless range.source_line.strip.start_with?('.', '&.')
137
153
 
@@ -270,14 +270,17 @@ module RuboCop
270
270
  end
271
271
  end
272
272
 
273
+ # rubocop:disable Metrics/CyclomaticComplexity
273
274
  def body_range?(begin_node, node)
275
+ return false if begin_node.chained?
274
276
  return false unless node.range_type?
275
277
  return false unless (parent = begin_node.parent)
276
- return false if parent.pair_type?
278
+ return false unless parent.begin_type?
277
279
 
278
280
  (node.begin.nil? && begin_node == parent.children.first) ||
279
281
  (node.end.nil? && begin_node == parent.children.last)
280
282
  end
283
+ # rubocop:enable Metrics/CyclomaticComplexity
281
284
 
282
285
  def disallowed_one_line_pattern_matching?(begin_node, node)
283
286
  if (parent = begin_node.parent)
@@ -9,6 +9,16 @@ module RuboCop
9
9
  # Therefore, this cop detects and autocorrects redundant `keyword_init: nil`
10
10
  # and `keyword_init: true` in `Struct.new`.
11
11
  #
12
+ # This cop is disabled by default because `keyword_init: true` is not purely
13
+ # redundant. It changes behavior in the following ways:
14
+ #
15
+ # - `Struct#keyword_init?` returns `true` instead of `nil`.
16
+ # - A `Struct` with `keyword_init: true` accepts a `Hash` argument and
17
+ # expands it as keyword arguments, whereas without it the `Hash` is
18
+ # treated as a positional argument.
19
+ # - `keyword_init: true` raises an `ArgumentError` for positional arguments,
20
+ # enforcing keyword-only initialization.
21
+ #
12
22
  # @safety
13
23
  # This autocorrect is unsafe because when the value of `keyword_init` changes
14
24
  # from `true` to `nil`, the return value of `Struct#keyword_init?` changes.
@@ -190,6 +190,8 @@ module RuboCop
190
190
  result = yield(path, source_code, safety)
191
191
 
192
192
  ::MCP::Tool::Response.new([{ type: 'text', text: result }])
193
+ rescue RuboCop::Error => e
194
+ ::MCP::Tool::Response.new([{ type: 'text', text: e.message }], error: true)
193
195
  end
194
196
  end
195
197
  # rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
@@ -6,6 +6,12 @@ require 'tempfile'
6
6
  module CopHelper
7
7
  extend RSpec::SharedContext
8
8
 
9
+ @integrated_plugins = false
10
+
11
+ class << self
12
+ attr_accessor :integrated_plugins
13
+ end
14
+
9
15
  let(:ruby_version) do
10
16
  # The minimum version Prism can parse is 3.3.
11
17
  ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
@@ -18,11 +24,13 @@ module CopHelper
18
24
 
19
25
  before(:all) do
20
26
  next if ENV['RUBOCOP_CORE_DEVELOPMENT']
27
+ next if CopHelper.integrated_plugins
21
28
 
22
29
  plugins = Gem.loaded_specs.filter_map do |feature_name, feature_specification|
23
30
  feature_name if feature_specification.metadata['default_lint_roller_plugin']
24
31
  end
25
32
  RuboCop::Plugin.integrate_plugins(RuboCop::Config.new, plugins)
33
+ CopHelper.integrated_plugins = true
26
34
  end
27
35
 
28
36
  def inspect_source(source, file = nil)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.86.0'
6
+ STRING = '1.86.1'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.86.0
4
+ version: 1.86.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -57,14 +57,14 @@ dependencies:
57
57
  name: parallel
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - "~>"
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '1.10'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - "~>"
67
+ - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.10'
70
70
  - !ruby/object:Gem::Dependency
@@ -1114,7 +1114,7 @@ licenses:
1114
1114
  - MIT
1115
1115
  metadata:
1116
1116
  homepage_uri: https://rubocop.org/
1117
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.86.0
1117
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.86.1
1118
1118
  source_code_uri: https://github.com/rubocop/rubocop/
1119
1119
  documentation_uri: https://docs.rubocop.org/rubocop/1.86/
1120
1120
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues