rubocop 1.67.0 → 1.68.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +40 -0
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +1 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +22 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/layout/leading_comment_space.rb +29 -1
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +7 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +3 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/offense.rb +2 -3
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +17 -2
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/endless_method.rb +1 -14
- data/lib/rubocop/cop/style/guard_clause.rb +14 -1
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/map_into_array.rb +6 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +28 -39
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +20 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -10
- data/lib/rubocop/cop/style/safe_navigation.rb +12 -0
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +5 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/cops_documentation_generator.rb +11 -9
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/runner.rb +16 -8
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +27 -8
- data/lib/rubocop.rb +8 -0
- metadata +15 -8
@@ -31,9 +31,6 @@ module RuboCop
|
|
31
31
|
# @!method allowed_pin_operator?(node)
|
32
32
|
def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
|
33
33
|
|
34
|
-
# @!method arg_in_call_with_block?(node)
|
35
|
-
def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)'
|
36
|
-
|
37
34
|
def on_begin(node)
|
38
35
|
return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node)
|
39
36
|
|
@@ -59,7 +56,6 @@ module RuboCop
|
|
59
56
|
|
60
57
|
def allowed_expression?(node)
|
61
58
|
allowed_ancestor?(node) ||
|
62
|
-
allowed_method_call?(node) ||
|
63
59
|
allowed_multiple_expression?(node) ||
|
64
60
|
allowed_ternary?(node) ||
|
65
61
|
node.parent&.range_type?
|
@@ -70,11 +66,6 @@ module RuboCop
|
|
70
66
|
keyword_ancestor?(node) && parens_required?(node)
|
71
67
|
end
|
72
68
|
|
73
|
-
def allowed_method_call?(node)
|
74
|
-
# Don't flag `method (arg) { }`
|
75
|
-
arg_in_call_with_block?(node) && !parentheses?(node.parent)
|
76
|
-
end
|
77
|
-
|
78
69
|
def allowed_multiple_expression?(node)
|
79
70
|
return false if node.children.one?
|
80
71
|
|
@@ -185,7 +176,8 @@ module RuboCop
|
|
185
176
|
return check_unary(begin_node, node) if node.unary_operation?
|
186
177
|
|
187
178
|
return unless method_call_with_redundant_parentheses?(node)
|
188
|
-
return if call_chain_starts_with_int?(begin_node, node)
|
179
|
+
return if call_chain_starts_with_int?(begin_node, node) ||
|
180
|
+
do_end_block_in_method_chain?(begin_node, node)
|
189
181
|
|
190
182
|
offense(begin_node, 'a method call')
|
191
183
|
end
|
@@ -285,6 +277,12 @@ module RuboCop
|
|
285
277
|
recv&.int_type? && (parent = begin_node.parent) &&
|
286
278
|
parent.send_type? && (parent.method?(:-@) || parent.method?(:+@))
|
287
279
|
end
|
280
|
+
|
281
|
+
def do_end_block_in_method_chain?(begin_node, node)
|
282
|
+
return false unless (block = node.each_descendant(:block, :numblock).first)
|
283
|
+
|
284
|
+
block.keywords? && begin_node.each_ancestor(:send, :csend).any?
|
285
|
+
end
|
288
286
|
end
|
289
287
|
end
|
290
288
|
end
|
@@ -21,6 +21,11 @@ module RuboCop
|
|
21
21
|
# We have limited the cop to not register an offense for method chains
|
22
22
|
# that exceed this option's value.
|
23
23
|
#
|
24
|
+
# NOTE: This cop will recognize offenses but not autocorrect code when the
|
25
|
+
# right hand side (RHS) of the `&&` statement is an `||` statement
|
26
|
+
# (eg. `foo && (foo.bar? || foo.baz?)`). It can be corrected
|
27
|
+
# manually by removing the `foo &&` and adding `&.` to each `foo` on the RHS.
|
28
|
+
#
|
24
29
|
# @safety
|
25
30
|
# Autocorrection is unsafe because if a value is `false`, the resulting
|
26
31
|
# code will have different behavior or raise an error.
|
@@ -121,6 +126,9 @@ module RuboCop
|
|
121
126
|
}
|
122
127
|
PATTERN
|
123
128
|
|
129
|
+
# @!method and_with_rhs_or?(node)
|
130
|
+
def_node_matcher :and_with_rhs_or?, '(and _ {or (begin or)})'
|
131
|
+
|
124
132
|
# @!method not_nil_check?(node)
|
125
133
|
def_node_matcher :not_nil_check?, '(send (send $_ :nil?) :!)'
|
126
134
|
|
@@ -172,6 +180,10 @@ module RuboCop
|
|
172
180
|
|
173
181
|
def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
|
174
182
|
add_offense(offense_range) do |corrector|
|
183
|
+
# If the RHS is an `or` we cannot safely autocorrect because in order to remove
|
184
|
+
# the non-nil check we need to add safe-navs to all clauses where the receiver is used
|
185
|
+
next if and_with_rhs_or?(node)
|
186
|
+
|
175
187
|
removal_ranges.each { |range| corrector.remove(range) }
|
176
188
|
yield corrector if block_given?
|
177
189
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Enforces safe navigation chains length to not exceed the configured maximum.
|
7
|
+
# The longer the chain is, the harder it becomes to track what on it could be
|
8
|
+
# returning `nil`.
|
9
|
+
#
|
10
|
+
# There is a potential interplay with `Style/SafeNavigation` - if both are enabled
|
11
|
+
# and their settings are "incompatible", one of the cops will complain about what
|
12
|
+
# the other proposes.
|
13
|
+
#
|
14
|
+
# E.g. if `Style/SafeNavigation` is configured with `MaxChainLength: 2` (default)
|
15
|
+
# and this cop is configured with `Max: 1`, then for `foo.bar.baz if foo` the former
|
16
|
+
# will suggest `foo&.bar&.baz`, which is an offense for the latter.
|
17
|
+
#
|
18
|
+
# @example Max: 2 (default)
|
19
|
+
# # bad
|
20
|
+
# user&.address&.zip&.upcase
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# user&.address&.zip
|
24
|
+
# user.address.zip if user
|
25
|
+
#
|
26
|
+
class SafeNavigationChainLength < Base
|
27
|
+
MSG = 'Avoid safe navigation chains longer than %<max>d calls.'
|
28
|
+
|
29
|
+
def on_csend(node)
|
30
|
+
safe_navigation_chains = safe_navigation_chains(node)
|
31
|
+
return if safe_navigation_chains.size < max
|
32
|
+
|
33
|
+
add_offense(safe_navigation_chains.last, message: format(MSG, max: max))
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def safe_navigation_chains(node)
|
39
|
+
node.each_ancestor.with_object([]) do |parent, chains|
|
40
|
+
break chains unless parent.csend_type?
|
41
|
+
|
42
|
+
chains << parent
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def max
|
47
|
+
cop_config['Max'] || 2
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -171,9 +171,7 @@ module RuboCop
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def unsafe_autocorrect?(condition)
|
174
|
-
condition.children.any?
|
175
|
-
unparenthesized_method_call?(child) || below_ternary_precedence?(child)
|
176
|
-
end
|
174
|
+
condition.children.any? { |child| below_ternary_precedence?(child) }
|
177
175
|
end
|
178
176
|
|
179
177
|
def unparenthesized_method_call?(child)
|
@@ -192,7 +190,7 @@ module RuboCop
|
|
192
190
|
# @!method method_name(node)
|
193
191
|
def_node_matcher :method_name, <<~PATTERN
|
194
192
|
{($:defined? _ ...)
|
195
|
-
(
|
193
|
+
(call {_ nil?} $_ _ ...)}
|
196
194
|
PATTERN
|
197
195
|
|
198
196
|
def correct_parenthesized(corrector, condition)
|
@@ -203,16 +201,39 @@ module RuboCop
|
|
203
201
|
# If we remove the parentheses, we need to add a space or we'll
|
204
202
|
# generate invalid code.
|
205
203
|
corrector.insert_after(condition.loc.end, ' ') unless whitespace_after?(condition)
|
204
|
+
|
205
|
+
if (send_node = condition.child_nodes.last) && node_args_need_parens?(send_node)
|
206
|
+
parenthesize_condition_arguments(corrector, send_node)
|
207
|
+
end
|
206
208
|
end
|
207
209
|
|
208
210
|
def correct_unparenthesized(corrector, condition)
|
209
211
|
corrector.wrap(condition, '(', ')')
|
210
212
|
end
|
211
213
|
|
214
|
+
def parenthesize_condition_arguments(corrector, send_node)
|
215
|
+
range_start = send_node.defined_type? ? send_node.loc.keyword : send_node.loc.selector
|
216
|
+
opening_range = range_start.end.join(send_node.first_argument.source_range.begin)
|
217
|
+
|
218
|
+
corrector.replace(opening_range, '(')
|
219
|
+
corrector.insert_after(send_node.last_argument, ')')
|
220
|
+
end
|
221
|
+
|
212
222
|
def whitespace_after?(node)
|
213
223
|
last_token = processed_source.last_token_of(node)
|
214
224
|
last_token.space_after?
|
215
225
|
end
|
226
|
+
|
227
|
+
def node_args_need_parens?(send_node)
|
228
|
+
return false unless node_with_args?(send_node)
|
229
|
+
return false if send_node.arguments.none? || send_node.parenthesized?
|
230
|
+
|
231
|
+
send_node.dot? || send_node.safe_navigation? || unparenthesized_method_call?(send_node)
|
232
|
+
end
|
233
|
+
|
234
|
+
def node_with_args?(node)
|
235
|
+
node.call_type? || node.defined_type?
|
236
|
+
end
|
216
237
|
end
|
217
238
|
end
|
218
239
|
end
|
@@ -9,9 +9,10 @@ module RuboCop
|
|
9
9
|
|
10
10
|
MULTIPLE_LEFT_HAND_SIDE_TYPE = :mlhs
|
11
11
|
|
12
|
-
attr_reader :node, :variable, :referenced, :references
|
12
|
+
attr_reader :node, :variable, :referenced, :references, :reassigned
|
13
13
|
|
14
14
|
alias referenced? referenced
|
15
|
+
alias reassigned? reassigned
|
15
16
|
|
16
17
|
def initialize(node, variable)
|
17
18
|
unless VARIABLE_ASSIGNMENT_TYPES.include?(node.type)
|
@@ -24,6 +25,7 @@ module RuboCop
|
|
24
25
|
@variable = variable
|
25
26
|
@referenced = false
|
26
27
|
@references = []
|
28
|
+
@reassigned = false
|
27
29
|
end
|
28
30
|
|
29
31
|
def name
|
@@ -39,8 +41,14 @@ module RuboCop
|
|
39
41
|
@referenced = true
|
40
42
|
end
|
41
43
|
|
44
|
+
def reassigned!
|
45
|
+
return if referenced?
|
46
|
+
|
47
|
+
@reassigned = true
|
48
|
+
end
|
49
|
+
|
42
50
|
def used?
|
43
|
-
@variable.captured_by_block? || @referenced
|
51
|
+
(!reassigned? && @variable.captured_by_block?) || @referenced
|
44
52
|
end
|
45
53
|
|
46
54
|
def regexp_named_capture?
|
@@ -102,6 +110,7 @@ module RuboCop
|
|
102
110
|
end
|
103
111
|
|
104
112
|
def multiple_assignment_node
|
113
|
+
return nil unless node.parent&.mlhs_type?
|
105
114
|
return nil unless (grandparent_node = node.parent&.parent)
|
106
115
|
if (node = find_multiple_assignment_node(grandparent_node))
|
107
116
|
return node
|
@@ -119,7 +128,13 @@ module RuboCop
|
|
119
128
|
end
|
120
129
|
|
121
130
|
def for_assignment_node
|
122
|
-
node.
|
131
|
+
return unless (parent_node = node.parent)
|
132
|
+
return parent_node if parent_node.for_type?
|
133
|
+
|
134
|
+
grandparent_node = parent_node.parent
|
135
|
+
return grandparent_node if parent_node.mlhs_type? && grandparent_node&.for_type?
|
136
|
+
|
137
|
+
nil
|
123
138
|
end
|
124
139
|
|
125
140
|
def find_multiple_assignment_node(grandparent_node)
|
@@ -29,7 +29,11 @@ module RuboCop
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def assign(node)
|
32
|
-
|
32
|
+
assignment = Assignment.new(node, self)
|
33
|
+
|
34
|
+
@assignments.last&.reassigned! unless captured_by_block?
|
35
|
+
|
36
|
+
@assignments << assignment
|
33
37
|
end
|
34
38
|
|
35
39
|
def referenced?
|
@@ -61,8 +61,8 @@ module RuboCop
|
|
61
61
|
"at #{node.source_range}, #{node.inspect}"
|
62
62
|
end
|
63
63
|
|
64
|
-
variable.assign(node)
|
65
64
|
mark_variable_as_captured_by_block_if_so(variable)
|
65
|
+
variable.assign(node)
|
66
66
|
end
|
67
67
|
|
68
68
|
def reference_variable(name, node)
|
@@ -87,8 +87,8 @@ module RuboCop
|
|
87
87
|
# So just skip.
|
88
88
|
return unless variable
|
89
89
|
|
90
|
-
variable.reference!(node)
|
91
90
|
mark_variable_as_captured_by_block_if_so(variable)
|
91
|
+
variable.reference!(node)
|
92
92
|
end
|
93
93
|
|
94
94
|
def find_variable(name)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'yard'
|
4
5
|
|
5
6
|
# Class for generating documentation of all cops departments
|
6
7
|
# @api private
|
@@ -35,13 +36,14 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
35
36
|
# This will insert the string returned from the lambda _after_ the section from RuboCop itself.
|
36
37
|
# See `CopsDocumentationGenerator::STRUCTURE` for available sections.
|
37
38
|
#
|
38
|
-
def initialize(departments: [], extra_info: {})
|
39
|
+
def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd)
|
39
40
|
@departments = departments.map(&:to_sym).sort!
|
40
41
|
@extra_info = extra_info
|
41
42
|
@cops = RuboCop::Cop::Registry.global
|
42
43
|
@config = RuboCop::ConfigLoader.default_configuration
|
43
|
-
@
|
44
|
-
|
44
|
+
@base_dir = base_dir
|
45
|
+
@docs_path = "#{base_dir}/docs/modules/ROOT"
|
46
|
+
FileUtils.mkdir_p("#{@docs_path}/pages")
|
45
47
|
end
|
46
48
|
|
47
49
|
def call
|
@@ -157,8 +159,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
157
159
|
end
|
158
160
|
|
159
161
|
def example_header(title, cop)
|
160
|
-
content = "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
161
|
-
content <<
|
162
|
+
content = +"[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
163
|
+
content << "==== #{title}\n"
|
162
164
|
content << "\n"
|
163
165
|
content
|
164
166
|
end
|
@@ -246,7 +248,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
246
248
|
else
|
247
249
|
wrap_backtick(val.nil? ? '<none>' : val)
|
248
250
|
end
|
249
|
-
value.gsub("#{
|
251
|
+
value.gsub("#{@base_dir}/", '').rstrip
|
250
252
|
end
|
251
253
|
|
252
254
|
def wrap_backtick(value)
|
@@ -275,7 +277,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
275
277
|
return '' unless department == :Layout
|
276
278
|
|
277
279
|
filename = "#{department_to_basename(department)}_footer.adoc"
|
278
|
-
file = "#{
|
280
|
+
file = "#{docs_path}/partials/#{filename}"
|
279
281
|
return '' unless File.exist?(file)
|
280
282
|
|
281
283
|
"\ninclude::../partials/#{filename}[]\n"
|
@@ -295,7 +297,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
295
297
|
HEADER
|
296
298
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
297
299
|
content << footer_for_department(department)
|
298
|
-
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
300
|
+
file_name = "#{docs_path}/pages/#{department_to_basename(department)}.adoc"
|
299
301
|
File.open(file_name, 'w') do |file|
|
300
302
|
puts "* generated #{file_name}"
|
301
303
|
file.write("#{content.strip}\n")
|
@@ -344,7 +346,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
344
346
|
end
|
345
347
|
|
346
348
|
def print_table_of_contents
|
347
|
-
path = "#{docs_path}/cops.adoc"
|
349
|
+
path = "#{docs_path}/pages/cops.adoc"
|
348
350
|
|
349
351
|
File.write(path, table_contents) and return unless File.exist?(path)
|
350
352
|
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
HEADING = <<~COMMENTS
|
11
11
|
# This configuration was generated by
|
12
12
|
# `%<command>s`
|
13
|
-
# %<timestamp>susing RuboCop version #{Version
|
13
|
+
# %<timestamp>susing RuboCop version #{Version::STRING}.
|
14
14
|
# The point is for the user to remove these configuration records
|
15
15
|
# one by one as the offenses are removed from the code base.
|
16
16
|
# Note that changes in the inspected code, or installation of new
|
data/lib/rubocop/runner.rb
CHANGED
@@ -139,7 +139,7 @@ module RuboCop
|
|
139
139
|
offenses = process_file(file)
|
140
140
|
yield file
|
141
141
|
|
142
|
-
if offenses.any? { |o| considered_failure?(o) }
|
142
|
+
if offenses.any? { |o| considered_failure?(o) && offense_displayed?(o) }
|
143
143
|
break false if @options[:fail_fast]
|
144
144
|
|
145
145
|
next false
|
@@ -363,8 +363,12 @@ module RuboCop
|
|
363
363
|
result = ruby_extractor.call(processed_source)
|
364
364
|
break result if result
|
365
365
|
rescue StandardError
|
366
|
-
|
367
|
-
|
366
|
+
location = if ruby_extractor.is_a?(Proc)
|
367
|
+
ruby_extractor.source_location
|
368
|
+
else
|
369
|
+
ruby_extractor.method(:call).source_location
|
370
|
+
end
|
371
|
+
raise Error, "Ruby extractor #{location[0]} failed to process #{processed_source.path}."
|
368
372
|
end
|
369
373
|
end
|
370
374
|
|
@@ -436,18 +440,22 @@ module RuboCop
|
|
436
440
|
!offense.corrected? && offense.severity >= minimum_severity_to_fail
|
437
441
|
end
|
438
442
|
|
439
|
-
def
|
443
|
+
def offense_displayed?(offense)
|
440
444
|
if @options[:display_only_fail_level_offenses]
|
441
|
-
|
445
|
+
considered_failure?(offense)
|
442
446
|
elsif @options[:display_only_safe_correctable]
|
443
|
-
|
447
|
+
supports_safe_autocorrect?(offense)
|
444
448
|
elsif @options[:display_only_correctable]
|
445
|
-
|
449
|
+
offense.correctable?
|
446
450
|
else
|
447
|
-
|
451
|
+
true
|
448
452
|
end
|
449
453
|
end
|
450
454
|
|
455
|
+
def offenses_to_report(offenses)
|
456
|
+
offenses.select { |o| offense_displayed?(o) }
|
457
|
+
end
|
458
|
+
|
451
459
|
def supports_safe_autocorrect?(offense)
|
452
460
|
cop_class = Cop::Registry.global.find_by_cop_name(offense.cop_name)
|
453
461
|
default_cfg = default_config(offense.cop_name)
|
data/lib/rubocop/target_ruby.rb
CHANGED
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.68.0'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
@@ -18,12 +18,13 @@ module RuboCop
|
|
18
18
|
'rubocop-md' => 'markdown', 'rubocop-factory_bot' => 'factory_bot'
|
19
19
|
}.freeze
|
20
20
|
|
21
|
+
# NOTE: Marked as private but used by gems like standard.
|
21
22
|
# @api private
|
22
23
|
def self.version(debug: false, env: nil)
|
23
24
|
if debug
|
24
25
|
verbose_version = format(MSG, version: STRING, parser_version: parser_version,
|
25
26
|
rubocop_ast_version: RuboCop::AST::Version::STRING,
|
26
|
-
target_ruby_version:
|
27
|
+
target_ruby_version: target_ruby_version(env),
|
27
28
|
ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
|
28
29
|
server_mode: server_mode,
|
29
30
|
ruby_platform: RUBY_PLATFORM)
|
@@ -41,6 +42,11 @@ module RuboCop
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
45
|
+
# @api private
|
46
|
+
def self.verbose(env: nil)
|
47
|
+
version(debug: true, env: env)
|
48
|
+
end
|
49
|
+
|
44
50
|
# @api private
|
45
51
|
def self.parser_version
|
46
52
|
config_path = ConfigFinder.find_config_path(Dir.pwd)
|
@@ -58,12 +64,7 @@ module RuboCop
|
|
58
64
|
|
59
65
|
# @api private
|
60
66
|
def self.extension_versions(env)
|
61
|
-
features =
|
62
|
-
# Suppress any config issues when loading the config (ie. deprecations,
|
63
|
-
# pending cops, etc.).
|
64
|
-
env.config_store.unvalidated.for_pwd.loaded_features.sort
|
65
|
-
end
|
66
|
-
|
67
|
+
features = config_for_pwd(env).loaded_features.sort
|
67
68
|
features.filter_map do |loaded_feature|
|
68
69
|
next unless (match = loaded_feature.match(/rubocop-(?<feature>.*)/))
|
69
70
|
|
@@ -85,6 +86,24 @@ module RuboCop
|
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
89
|
+
# @api private
|
90
|
+
def self.target_ruby_version(env)
|
91
|
+
if env
|
92
|
+
config_for_pwd(env).target_ruby_version
|
93
|
+
else
|
94
|
+
TargetRuby.new(Config.new).version
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @api private
|
99
|
+
def self.config_for_pwd(env)
|
100
|
+
Util.silence_warnings do
|
101
|
+
# Suppress any config issues when loading the config (ie. deprecations,
|
102
|
+
# pending cops, etc.).
|
103
|
+
env.config_store.unvalidated.for_pwd
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
88
107
|
# Returns feature version in one of two ways:
|
89
108
|
#
|
90
109
|
# * Find by RuboCop core version style (e.g. rubocop-performance, rubocop-rspec)
|
data/lib/rubocop.rb
CHANGED
@@ -11,6 +11,7 @@ require 'rainbow'
|
|
11
11
|
|
12
12
|
require 'regexp_parser'
|
13
13
|
require 'set'
|
14
|
+
require 'stringio'
|
14
15
|
require 'unicode/display_width'
|
15
16
|
|
16
17
|
# we have to require RuboCop's version, before rubocop-ast's
|
@@ -90,6 +91,7 @@ require_relative 'rubocop/cop/mixin/annotation_comment' # relies on range
|
|
90
91
|
require_relative 'rubocop/cop/mixin/empty_lines_around_body' # relies on range
|
91
92
|
require_relative 'rubocop/cop/mixin/empty_parameter'
|
92
93
|
require_relative 'rubocop/cop/mixin/end_keyword_alignment'
|
94
|
+
require_relative 'rubocop/cop/mixin/endless_method_rewriter'
|
93
95
|
require_relative 'rubocop/cop/mixin/enforce_superclass'
|
94
96
|
require_relative 'rubocop/cop/mixin/first_element_line_break'
|
95
97
|
require_relative 'rubocop/cop/mixin/frozen_string_literal'
|
@@ -403,6 +405,7 @@ require_relative 'rubocop/cop/lint/top_level_return_with_argument'
|
|
403
405
|
require_relative 'rubocop/cop/lint/trailing_comma_in_attribute_declaration'
|
404
406
|
require_relative 'rubocop/cop/lint/triple_quotes'
|
405
407
|
require_relative 'rubocop/cop/lint/underscore_prefixed_variable_name'
|
408
|
+
require_relative 'rubocop/cop/lint/unescaped_bracket_in_regexp'
|
406
409
|
require_relative 'rubocop/cop/lint/unexpected_block_arity'
|
407
410
|
require_relative 'rubocop/cop/lint/unified_integer'
|
408
411
|
require_relative 'rubocop/cop/lint/unmodified_reduce_accumulator'
|
@@ -460,6 +463,7 @@ require_relative 'rubocop/cop/naming/variable_number'
|
|
460
463
|
require_relative 'rubocop/cop/style/access_modifier_declarations'
|
461
464
|
require_relative 'rubocop/cop/style/accessor_grouping'
|
462
465
|
require_relative 'rubocop/cop/style/alias'
|
466
|
+
require_relative 'rubocop/cop/style/ambiguous_endless_method_definition'
|
463
467
|
require_relative 'rubocop/cop/style/and_or'
|
464
468
|
require_relative 'rubocop/cop/style/arguments_forwarding'
|
465
469
|
require_relative 'rubocop/cop/style/array_coercion'
|
@@ -472,6 +476,7 @@ require_relative 'rubocop/cop/style/auto_resource_cleanup'
|
|
472
476
|
require_relative 'rubocop/cop/style/bare_percent_literals'
|
473
477
|
require_relative 'rubocop/cop/style/begin_block'
|
474
478
|
require_relative 'rubocop/cop/style/bisected_attr_accessor'
|
479
|
+
require_relative 'rubocop/cop/style/bitwise_predicate'
|
475
480
|
require_relative 'rubocop/cop/style/block_comments'
|
476
481
|
require_relative 'rubocop/cop/style/block_delimiters'
|
477
482
|
require_relative 'rubocop/cop/style/case_equality'
|
@@ -487,6 +492,7 @@ require_relative 'rubocop/cop/style/collection_compact'
|
|
487
492
|
require_relative 'rubocop/cop/style/collection_methods'
|
488
493
|
require_relative 'rubocop/cop/style/colon_method_call'
|
489
494
|
require_relative 'rubocop/cop/style/colon_method_definition'
|
495
|
+
require_relative 'rubocop/cop/style/combinable_defined'
|
490
496
|
require_relative 'rubocop/cop/style/combinable_loops'
|
491
497
|
require_relative 'rubocop/cop/style/command_literal'
|
492
498
|
require_relative 'rubocop/cop/style/comment_annotation'
|
@@ -559,6 +565,7 @@ require_relative 'rubocop/cop/style/inverse_methods'
|
|
559
565
|
require_relative 'rubocop/cop/style/inline_comment'
|
560
566
|
require_relative 'rubocop/cop/style/invertible_unless_condition'
|
561
567
|
require_relative 'rubocop/cop/style/ip_addresses'
|
568
|
+
require_relative 'rubocop/cop/style/keyword_arguments_merging'
|
562
569
|
require_relative 'rubocop/cop/style/keyword_parameters_order'
|
563
570
|
require_relative 'rubocop/cop/style/lambda'
|
564
571
|
require_relative 'rubocop/cop/style/lambda_call'
|
@@ -592,6 +599,7 @@ require_relative 'rubocop/cop/style/redundant_regexp_constructor'
|
|
592
599
|
require_relative 'rubocop/cop/style/redundant_self_assignment'
|
593
600
|
require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
|
594
601
|
require_relative 'rubocop/cop/style/require_order'
|
602
|
+
require_relative 'rubocop/cop/style/safe_navigation_chain_length'
|
595
603
|
require_relative 'rubocop/cop/style/single_line_do_end_block'
|
596
604
|
require_relative 'rubocop/cop/style/sole_nested_conditional'
|
597
605
|
require_relative 'rubocop/cop/style/static_class'
|