rubocop 1.32.0 → 1.33.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 +2 -2
- data/config/default.yml +45 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +5 -45
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +32 -5
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +11 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +60 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +4 -9
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/symbol_proc.rb +29 -9
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/server/cache.rb +33 -1
- data/lib/rubocop/server/cli.rb +19 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +0 -1
- metadata +5 -4
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -159,10 +159,6 @@ module RuboCop
|
|
159
159
|
key_argument = node.argument_list.first.source
|
160
160
|
body = extract_body_if_nagated(node.body)
|
161
161
|
lhs, _method_name, rhs = *body
|
162
|
-
|
163
|
-
return lhs if body.method?('include?')
|
164
|
-
return lhs if body.method?('exclude?')
|
165
|
-
return rhs if body.method?('in?')
|
166
162
|
return if [lhs, rhs].map(&:source).none?(key_argument)
|
167
163
|
|
168
164
|
[lhs, rhs].find { |operand| operand.source != key_argument }
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def require_parentheses(node)
|
15
|
-
return if
|
15
|
+
return if allowed_method_name?(node.method_name)
|
16
16
|
return if matches_allowed_pattern?(node.method_name)
|
17
17
|
return if eligible_for_parentheses_omission?(node)
|
18
18
|
return unless node.arguments? && !node.parenthesized?
|
@@ -24,6 +24,10 @@ module RuboCop
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def allowed_method_name?(name)
|
28
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
29
|
+
end
|
30
|
+
|
27
31
|
def eligible_for_parentheses_omission?(node)
|
28
32
|
node.operator_method? || node.setter_method? || ignored_macro?(node)
|
29
33
|
end
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# Enforces the presence (default) or absence of parentheses in
|
7
7
|
# method calls containing parameters.
|
8
8
|
#
|
9
|
-
# In the default style (require_parentheses), macro methods are
|
10
|
-
# Additional methods can be added to the `
|
9
|
+
# In the default style (require_parentheses), macro methods are allowed.
|
10
|
+
# Additional methods can be added to the `AllowedMethods`
|
11
11
|
# or `AllowedPatterns` list. These options are
|
12
12
|
# valid only in the default style. Macros can be included by
|
13
13
|
# either setting `IgnoreMacros` to false or adding specific macros to
|
@@ -15,13 +15,13 @@ module RuboCop
|
|
15
15
|
#
|
16
16
|
# Precedence of options is all follows:
|
17
17
|
#
|
18
|
-
# 1. `
|
18
|
+
# 1. `AllowedMethods`
|
19
19
|
# 2. `AllowedPatterns`
|
20
20
|
# 3. `IncludedMacros`
|
21
21
|
#
|
22
22
|
# eg. If a method is listed in both
|
23
|
-
# `IncludedMacros` and `
|
24
|
-
# precedence (that is, the method is
|
23
|
+
# `IncludedMacros` and `AllowedMethods`, then the latter takes
|
24
|
+
# precedence (that is, the method is allowed).
|
25
25
|
#
|
26
26
|
# In the alternative style (omit_parentheses), there are three additional
|
27
27
|
# options.
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
65
65
|
# # Setter methods don't need parens
|
66
66
|
# foo.bar = baz
|
67
67
|
#
|
68
|
-
# # okay with `puts` listed in `
|
68
|
+
# # okay with `puts` listed in `AllowedMethods`
|
69
69
|
# puts 'test'
|
70
70
|
#
|
71
71
|
# # okay with `^assert` listed in `AllowedPatterns`
|
@@ -197,7 +197,7 @@ module RuboCop
|
|
197
197
|
require_relative 'method_call_with_args_parentheses/require_parentheses'
|
198
198
|
|
199
199
|
include ConfigurableEnforcedStyle
|
200
|
-
include
|
200
|
+
include AllowedMethods
|
201
201
|
include AllowedPattern
|
202
202
|
include RequireParentheses
|
203
203
|
include OmitParentheses
|
@@ -5,8 +5,8 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for unwanted parentheses in parameterless method calls.
|
7
7
|
#
|
8
|
-
# This cop can be customized
|
9
|
-
# By default, there are no methods to
|
8
|
+
# This cop can be customized allowed methods with `AllowedMethods`.
|
9
|
+
# By default, there are no methods to allowed.
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# # bad
|
@@ -15,16 +15,17 @@ module RuboCop
|
|
15
15
|
# # good
|
16
16
|
# object.some_method
|
17
17
|
#
|
18
|
-
# @example
|
18
|
+
# @example AllowedMethods: [] (default)
|
19
19
|
# # bad
|
20
20
|
# object.foo()
|
21
21
|
#
|
22
|
-
# @example
|
22
|
+
# @example AllowedMethods: [foo]
|
23
23
|
# # good
|
24
24
|
# object.foo()
|
25
25
|
#
|
26
26
|
class MethodCallWithoutArgsParentheses < Base
|
27
|
-
include
|
27
|
+
include AllowedMethods
|
28
|
+
include AllowedPattern
|
28
29
|
extend AutoCorrector
|
29
30
|
|
30
31
|
MSG = 'Do not use parentheses for method calls with no arguments.'
|
@@ -33,7 +34,7 @@ module RuboCop
|
|
33
34
|
return unless !node.arguments? && node.parenthesized?
|
34
35
|
return if ineligible_node?(node)
|
35
36
|
return if default_argument?(node)
|
36
|
-
return if
|
37
|
+
return if allowed_method_name?(node.method_name)
|
37
38
|
return if same_name_assignment?(node)
|
38
39
|
|
39
40
|
register_offense(node)
|
@@ -56,6 +57,10 @@ module RuboCop
|
|
56
57
|
node.parent&.optarg_type?
|
57
58
|
end
|
58
59
|
|
60
|
+
def allowed_method_name?(name)
|
61
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
62
|
+
end
|
63
|
+
|
59
64
|
def same_name_assignment?(node)
|
60
65
|
any_assignment?(node) do |asgn_node|
|
61
66
|
next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
|
@@ -8,14 +8,14 @@ module RuboCop
|
|
8
8
|
# These can be replaced by their respective predicate methods.
|
9
9
|
# This cop can also be configured to do the reverse.
|
10
10
|
#
|
11
|
-
# This cop can be customized
|
12
|
-
# By default, there are no methods to
|
11
|
+
# This cop can be customized allowed methods with `AllowedMethods`.
|
12
|
+
# By default, there are no methods to allowed.
|
13
13
|
#
|
14
14
|
# This cop disregards `#nonzero?` as its value is truthy or falsey,
|
15
15
|
# but not `true` and `false`, and thus not always interchangeable with
|
16
16
|
# `!= 0`.
|
17
17
|
#
|
18
|
-
# This cop
|
18
|
+
# This cop allows comparisons to global variables, since they are often
|
19
19
|
# populated with objects which can be compared with integers, but are
|
20
20
|
# not themselves `Integer` polymorphic.
|
21
21
|
#
|
@@ -46,13 +46,13 @@ module RuboCop
|
|
46
46
|
# 0 > foo
|
47
47
|
# bar.baz > 0
|
48
48
|
#
|
49
|
-
# @example
|
49
|
+
# @example AllowedMethods: [] (default) with EnforcedStyle: predicate
|
50
50
|
# # bad
|
51
51
|
# foo == 0
|
52
52
|
# 0 > foo
|
53
53
|
# bar.baz > 0
|
54
54
|
#
|
55
|
-
# @example
|
55
|
+
# @example AllowedMethods: [==] with EnforcedStyle: predicate
|
56
56
|
# # good
|
57
57
|
# foo == 0
|
58
58
|
#
|
@@ -60,9 +60,25 @@ module RuboCop
|
|
60
60
|
# 0 > foo
|
61
61
|
# bar.baz > 0
|
62
62
|
#
|
63
|
+
# @example AllowedPatterns: [] (default) with EnforcedStyle: comparison
|
64
|
+
# # bad
|
65
|
+
# foo.zero?
|
66
|
+
# foo.negative?
|
67
|
+
# bar.baz.positive?
|
68
|
+
#
|
69
|
+
# @example AllowedPatterns: [/zero/] with EnforcedStyle: predicate
|
70
|
+
# # good
|
71
|
+
# # bad
|
72
|
+
# foo.zero?
|
73
|
+
#
|
74
|
+
# # bad
|
75
|
+
# foo.negative?
|
76
|
+
# bar.baz.positive?
|
77
|
+
#
|
63
78
|
class NumericPredicate < Base
|
64
79
|
include ConfigurableEnforcedStyle
|
65
|
-
include
|
80
|
+
include AllowedMethods
|
81
|
+
include AllowedPattern
|
66
82
|
extend AutoCorrector
|
67
83
|
|
68
84
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
@@ -75,9 +91,9 @@ module RuboCop
|
|
75
91
|
numeric, replacement = check(node)
|
76
92
|
return unless numeric
|
77
93
|
|
78
|
-
return if
|
94
|
+
return if allowed_method_name?(node.method_name) ||
|
79
95
|
node.each_ancestor(:send, :block).any? do |ancestor|
|
80
|
-
|
96
|
+
allowed_method_name?(ancestor.method_name)
|
81
97
|
end
|
82
98
|
|
83
99
|
message = format(MSG, prefer: replacement, current: node.source)
|
@@ -88,6 +104,10 @@ module RuboCop
|
|
88
104
|
|
89
105
|
private
|
90
106
|
|
107
|
+
def allowed_method_name?(name)
|
108
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
109
|
+
end
|
110
|
+
|
91
111
|
def check(node)
|
92
112
|
numeric, operator =
|
93
113
|
if style == :predicate
|
@@ -154,16 +154,22 @@ module RuboCop
|
|
154
154
|
if_branch.method?(else_branch.method_name) && if_branch.receiver == else_branch.receiver
|
155
155
|
end
|
156
156
|
|
157
|
-
def if_source(if_branch)
|
157
|
+
def if_source(if_branch, arithmetic_operation)
|
158
158
|
if branches_have_method?(if_branch.parent) && if_branch.parenthesized?
|
159
159
|
if_branch.source.delete_suffix(')')
|
160
|
+
elsif arithmetic_operation
|
161
|
+
argument_source = if_branch.first_argument.source
|
162
|
+
|
163
|
+
"#{if_branch.receiver.source} #{if_branch.method_name} (#{argument_source}"
|
160
164
|
else
|
161
165
|
if_branch.source
|
162
166
|
end
|
163
167
|
end
|
164
168
|
|
165
|
-
def else_source(else_branch)
|
166
|
-
if
|
169
|
+
def else_source(else_branch, arithmetic_operation) # rubocop:disable Metrics/AbcSize
|
170
|
+
if arithmetic_operation
|
171
|
+
"#{else_branch.first_argument.source})"
|
172
|
+
elsif branches_have_method?(else_branch.parent)
|
167
173
|
else_source_if_has_method(else_branch)
|
168
174
|
elsif require_parentheses?(else_branch)
|
169
175
|
"(#{else_branch.source})"
|
@@ -198,7 +204,12 @@ module RuboCop
|
|
198
204
|
|
199
205
|
def make_ternary_form(node)
|
200
206
|
_condition, if_branch, else_branch = *node
|
201
|
-
|
207
|
+
arithmetic_operation = use_arithmetic_operation?(if_branch)
|
208
|
+
|
209
|
+
ternary_form = [
|
210
|
+
if_source(if_branch, arithmetic_operation),
|
211
|
+
else_source(else_branch, arithmetic_operation)
|
212
|
+
].join(' || ')
|
202
213
|
ternary_form += ')' if branches_have_method?(node) && if_branch.parenthesized?
|
203
214
|
|
204
215
|
if node.parent&.send_type?
|
@@ -227,6 +238,10 @@ module RuboCop
|
|
227
238
|
node.hash_type? && !node.braces?
|
228
239
|
end
|
229
240
|
|
241
|
+
def use_arithmetic_operation?(node)
|
242
|
+
node.respond_to?(:arithmetic_operation?) && node.arithmetic_operation?
|
243
|
+
end
|
244
|
+
|
230
245
|
def without_argument_parentheses_method?(node)
|
231
246
|
node.send_type? && !node.arguments.empty? &&
|
232
247
|
!node.parenthesized? && !node.operator_method? && !node.assignment_method?
|
@@ -123,13 +123,8 @@ module RuboCop
|
|
123
123
|
|
124
124
|
def register_offense(node, sort_node, sorter, accessor)
|
125
125
|
message = message(node, sorter, accessor)
|
126
|
-
|
127
126
|
add_offense(offense_range(sort_node, node), message: message) do |corrector|
|
128
|
-
|
129
|
-
corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
|
130
|
-
|
131
|
-
# Replace "sort" or "sort_by" with the appropriate min/max method.
|
132
|
-
corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
|
127
|
+
autocorrect(corrector, node, sort_node, sorter, accessor)
|
133
128
|
end
|
134
129
|
end
|
135
130
|
|
@@ -149,6 +144,20 @@ module RuboCop
|
|
149
144
|
accessor_source: accessor_source)
|
150
145
|
end
|
151
146
|
|
147
|
+
def autocorrect(corrector, node, sort_node, sorter, accessor)
|
148
|
+
# Remove accessor, e.g. `first` or `[-1]`.
|
149
|
+
corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
|
150
|
+
# Replace "sort" or "sort_by" with the appropriate min/max method.
|
151
|
+
corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
|
152
|
+
# Replace to avoid syntax errors when followed by a logical operator.
|
153
|
+
replace_with_logical_operator(corrector, node) if with_logical_operator?(node)
|
154
|
+
end
|
155
|
+
|
156
|
+
def replace_with_logical_operator(corrector, node)
|
157
|
+
corrector.insert_after(node.child_nodes.first, " #{node.parent.loc.operator.source}")
|
158
|
+
corrector.remove(node.parent.loc.operator)
|
159
|
+
end
|
160
|
+
|
152
161
|
def suggestion(sorter, accessor, arg)
|
153
162
|
base(accessor, arg) + suffix(sorter)
|
154
163
|
end
|
@@ -187,6 +196,12 @@ module RuboCop
|
|
187
196
|
node.loc.selector.begin_pos
|
188
197
|
end
|
189
198
|
end
|
199
|
+
|
200
|
+
def with_logical_operator?(node)
|
201
|
+
return unless (parent = node.parent)
|
202
|
+
|
203
|
+
parent.or_type? || parent.and_type?
|
204
|
+
end
|
190
205
|
end
|
191
206
|
end
|
192
207
|
end
|
@@ -7,13 +7,13 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# If you prefer a style that allows block for method with arguments,
|
9
9
|
# please set `true` to `AllowMethodsWithArguments`.
|
10
|
-
# respond_to , and `define_method?` methods are
|
11
|
-
# These are customizable with `
|
10
|
+
# respond_to , and `define_method?` methods are allowed by default.
|
11
|
+
# These are customizable with `AllowedMethods` option.
|
12
12
|
#
|
13
13
|
# @safety
|
14
14
|
# This cop is unsafe because `proc`s and blocks work differently
|
15
15
|
# when additional arguments are passed in. A block will silently
|
16
|
-
#
|
16
|
+
# allow additional arguments, but a `proc` will raise
|
17
17
|
# an `ArgumentError`.
|
18
18
|
#
|
19
19
|
# For example:
|
@@ -71,15 +71,25 @@ module RuboCop
|
|
71
71
|
# # some comment
|
72
72
|
# end
|
73
73
|
#
|
74
|
-
# @example
|
74
|
+
# @example AllowedMethods: [respond_to, define_method] (default)
|
75
75
|
# # good
|
76
76
|
# respond_to { |foo| foo.bar }
|
77
77
|
# define_method(:foo) { |foo| foo.bar }
|
78
78
|
#
|
79
|
+
#
|
80
|
+
# @example AllowedPatterns: [] (default)
|
81
|
+
# # bad
|
82
|
+
# something.map { |s| s.upcase }
|
83
|
+
#
|
84
|
+
# @example AllowedPatterns: [/map/] (default)
|
85
|
+
# # good
|
86
|
+
# something.map { |s| s.upcase }
|
87
|
+
#
|
79
88
|
class SymbolProc < Base
|
80
89
|
include CommentsHelp
|
81
90
|
include RangeHelp
|
82
|
-
include
|
91
|
+
include AllowedMethods
|
92
|
+
include AllowedPattern
|
83
93
|
extend AutoCorrector
|
84
94
|
|
85
95
|
MSG = 'Pass `&:%<method>s` as an argument to `%<block_method>s` instead of a block.'
|
@@ -103,15 +113,16 @@ module RuboCop
|
|
103
113
|
[Layout::SpaceBeforeBlockBraces]
|
104
114
|
end
|
105
115
|
|
106
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
116
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
107
117
|
def on_block(node)
|
108
118
|
symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
|
109
119
|
# TODO: Rails-specific handling that we should probably make
|
110
120
|
# configurable - https://github.com/rubocop/rubocop/issues/1485
|
111
|
-
# we should
|
121
|
+
# we should allow lambdas & procs
|
112
122
|
return if proc_node?(dispatch_node)
|
123
|
+
return if unsafe_hash_usage?(dispatch_node)
|
113
124
|
return if %i[lambda proc].include?(dispatch_node.method_name)
|
114
|
-
return if
|
125
|
+
return if allowed_method_name?(dispatch_node.method_name)
|
115
126
|
return if allow_if_method_has_argument?(node.send_node)
|
116
127
|
return if node.block_type? && destructuring_block_argument?(arguments_node)
|
117
128
|
return if allow_comments? && contains_comments?(node)
|
@@ -119,7 +130,7 @@ module RuboCop
|
|
119
130
|
register_offense(node, method_name, dispatch_node.method_name)
|
120
131
|
end
|
121
132
|
end
|
122
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
133
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
123
134
|
alias on_numblock on_block
|
124
135
|
|
125
136
|
def destructuring_block_argument?(argument_node)
|
@@ -128,6 +139,15 @@ module RuboCop
|
|
128
139
|
|
129
140
|
private
|
130
141
|
|
142
|
+
# See: https://github.com/rubocop/rubocop/issues/10864
|
143
|
+
def unsafe_hash_usage?(node)
|
144
|
+
node.receiver&.hash_type? && %i[reject select].include?(node.method_name)
|
145
|
+
end
|
146
|
+
|
147
|
+
def allowed_method_name?(name)
|
148
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
149
|
+
end
|
150
|
+
|
131
151
|
def register_offense(node, method_name, block_method_name)
|
132
152
|
block_start = node.loc.begin.begin_pos
|
133
153
|
block_end = node.loc.end.end_pos
|
data/lib/rubocop/result_cache.rb
CHANGED
@@ -4,6 +4,7 @@ require 'digest/sha1'
|
|
4
4
|
require 'find'
|
5
5
|
require 'etc'
|
6
6
|
require 'zlib'
|
7
|
+
require_relative 'cache_config'
|
7
8
|
|
8
9
|
module RuboCop
|
9
10
|
# Provides functionality for caching RuboCop runs.
|
@@ -13,6 +14,12 @@ module RuboCop
|
|
13
14
|
fix_layout autocorrect safe_autocorrect autocorrect_all
|
14
15
|
cache fail_fast stdin parallel].freeze
|
15
16
|
|
17
|
+
DL_EXTENSIONS = ::RbConfig::CONFIG
|
18
|
+
.values_at('DLEXT', 'DLEXT2')
|
19
|
+
.reject { |ext| !ext || ext.empty? }
|
20
|
+
.map { |ext| ".#{ext}" }
|
21
|
+
.freeze
|
22
|
+
|
16
23
|
# Remove old files so that the cache doesn't grow too big. When the
|
17
24
|
# threshold MaxFilesInCache has been exceeded, the oldest 50% of all the
|
18
25
|
# files in the cache are removed. The reason for removing so much is that
|
@@ -67,24 +74,9 @@ module RuboCop
|
|
67
74
|
end
|
68
75
|
|
69
76
|
def self.cache_root(config_store)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# Include user ID in the path to make sure the user has write
|
74
|
-
# access.
|
75
|
-
File.join(ENV.fetch('XDG_CACHE_HOME'), Process.uid.to_s)
|
76
|
-
else
|
77
|
-
# On FreeBSD, the /home path is a symbolic link to /usr/home
|
78
|
-
# and the $HOME environment variable returns the /home path.
|
79
|
-
#
|
80
|
-
# As $HOME is a built-in environment variable, FreeBSD users
|
81
|
-
# always get a warning message.
|
82
|
-
#
|
83
|
-
# To avoid raising warn log messages on FreeBSD, we retrieve
|
84
|
-
# the real path of the home folder.
|
85
|
-
File.join(File.realpath(Dir.home), '.cache')
|
86
|
-
end
|
87
|
-
File.join(root, 'rubocop_cache')
|
77
|
+
CacheConfig.root_dir do
|
78
|
+
config_store.for_pwd.for_all_cops['CacheRootDirectory']
|
79
|
+
end
|
88
80
|
end
|
89
81
|
|
90
82
|
def self.allow_symlinks_in_cache_location?(config_store)
|
@@ -188,14 +180,24 @@ module RuboCop
|
|
188
180
|
.select { |path| File.file?(path) }
|
189
181
|
.sort!
|
190
182
|
.each do |path|
|
191
|
-
|
192
|
-
digest << Zlib.crc32(content).to_s # mtime not reliable
|
183
|
+
digest << digest(path)
|
193
184
|
end
|
194
185
|
digest << RuboCop::Version::STRING << RuboCop::AST::Version::STRING
|
195
186
|
digest.hexdigest
|
196
187
|
end
|
197
188
|
end
|
198
189
|
|
190
|
+
def digest(path)
|
191
|
+
content = if path.end_with?(*DL_EXTENSIONS)
|
192
|
+
# Shared libraries often contain timestamps of when
|
193
|
+
# they were compiled and other non-stable data.
|
194
|
+
File.basename(path)
|
195
|
+
else
|
196
|
+
File.binread(path) # mtime not reliable
|
197
|
+
end
|
198
|
+
Zlib.crc32(content).to_s
|
199
|
+
end
|
200
|
+
|
199
201
|
def rubocop_extra_features
|
200
202
|
lib_root = File.join(File.dirname(__FILE__), '..')
|
201
203
|
exe_root = File.join(lib_root, '..', 'exe')
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'pathname'
|
4
|
+
require_relative '../cache_config'
|
5
|
+
require_relative '../config_finder'
|
4
6
|
|
5
7
|
#
|
6
8
|
# This code is based on https://github.com/fohte/rubocop-daemon.
|
@@ -19,6 +21,8 @@ module RuboCop
|
|
19
21
|
GEMFILE_NAMES = %w[Gemfile gems.rb].freeze
|
20
22
|
|
21
23
|
class << self
|
24
|
+
attr_accessor :cache_root_path
|
25
|
+
|
22
26
|
# Searches for Gemfile or gems.rb in the current dir or any parent dirs
|
23
27
|
def project_dir
|
24
28
|
current_dir = Dir.pwd
|
@@ -38,12 +42,40 @@ module RuboCop
|
|
38
42
|
end
|
39
43
|
|
40
44
|
def dir
|
41
|
-
cache_path = File.expand_path('~/.cache/rubocop_cache/server')
|
42
45
|
Pathname.new(File.join(cache_path, project_dir_cache_key)).tap do |d|
|
43
46
|
d.mkpath unless d.exist?
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
50
|
+
def cache_path
|
51
|
+
cache_root_dir = if cache_root_path
|
52
|
+
File.join(cache_root_path, 'rubocop_cache')
|
53
|
+
else
|
54
|
+
cache_root_dir_from_config
|
55
|
+
end
|
56
|
+
|
57
|
+
File.expand_path(File.join(cache_root_dir, 'server'))
|
58
|
+
end
|
59
|
+
|
60
|
+
def cache_root_dir_from_config
|
61
|
+
CacheConfig.root_dir do
|
62
|
+
# `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
|
63
|
+
# so that only the necessary `CacheRootDirectory` can be obtained.
|
64
|
+
require 'yaml'
|
65
|
+
|
66
|
+
config_path = ConfigFinder.find_config_path(Dir.pwd)
|
67
|
+
|
68
|
+
# Ruby 3.1+
|
69
|
+
config_yaml = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('4.0.0')
|
70
|
+
YAML.safe_load_file(config_path, permitted_classes: [Regexp, Symbol])
|
71
|
+
else
|
72
|
+
YAML.load_file(config_path)
|
73
|
+
end
|
74
|
+
|
75
|
+
config_yaml.dig('AllCops', 'CacheRootDirectory')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
47
79
|
def port_path
|
48
80
|
dir.join('port')
|
49
81
|
end
|
data/lib/rubocop/server/cli.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'optparse'
|
4
3
|
require 'rainbow'
|
5
4
|
|
6
5
|
#
|
@@ -30,6 +29,7 @@ module RuboCop
|
|
30
29
|
@exit = false
|
31
30
|
end
|
32
31
|
|
32
|
+
# rubocop:disable Metrics/MethodLength
|
33
33
|
def run(argv = ARGV)
|
34
34
|
unless Server.support_server?
|
35
35
|
return error('RuboCop server is not supported by this Ruby.') if use_server_option?(argv)
|
@@ -37,6 +37,7 @@ module RuboCop
|
|
37
37
|
return STATUS_SUCCESS
|
38
38
|
end
|
39
39
|
|
40
|
+
Cache.cache_root_path = fetch_cache_root_path_from(argv)
|
40
41
|
deleted_server_arguments = delete_server_argument_from(argv)
|
41
42
|
|
42
43
|
if deleted_server_arguments.size >= 2
|
@@ -45,7 +46,7 @@ module RuboCop
|
|
45
46
|
|
46
47
|
server_command = deleted_server_arguments.first
|
47
48
|
|
48
|
-
if EXCLUSIVE_OPTIONS.include?(server_command) && argv.count
|
49
|
+
if EXCLUSIVE_OPTIONS.include?(server_command) && argv.count > allowed_option_count
|
49
50
|
return error("#{server_command} cannot be combined with other options.")
|
50
51
|
end
|
51
52
|
|
@@ -53,6 +54,7 @@ module RuboCop
|
|
53
54
|
|
54
55
|
STATUS_SUCCESS
|
55
56
|
end
|
57
|
+
# rubocop:enable Metrics/MethodLength
|
56
58
|
|
57
59
|
def exit?
|
58
60
|
@exit
|
@@ -83,6 +85,17 @@ module RuboCop
|
|
83
85
|
end
|
84
86
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength:
|
85
87
|
|
88
|
+
def fetch_cache_root_path_from(arguments)
|
89
|
+
cache_root = arguments.detect { |argument| argument.start_with?('--cache-root') }
|
90
|
+
return unless cache_root
|
91
|
+
|
92
|
+
if cache_root.start_with?('--cache-root=')
|
93
|
+
cache_root.split('=')[1]
|
94
|
+
else
|
95
|
+
arguments[arguments.index(cache_root) + 1]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
86
99
|
def delete_server_argument_from(all_arguments)
|
87
100
|
SERVER_OPTIONS.each_with_object([]) do |server_option, server_arguments|
|
88
101
|
server_arguments << all_arguments.delete(server_option)
|
@@ -93,6 +106,10 @@ module RuboCop
|
|
93
106
|
(argv & SERVER_OPTIONS).any?
|
94
107
|
end
|
95
108
|
|
109
|
+
def allowed_option_count
|
110
|
+
Cache.cache_root_path ? 2 : 1
|
111
|
+
end
|
112
|
+
|
96
113
|
def error(message)
|
97
114
|
@exit = true
|
98
115
|
warn Rainbow(message).red
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -86,7 +86,6 @@ require_relative 'rubocop/cop/mixin/gem_declaration'
|
|
86
86
|
require_relative 'rubocop/cop/mixin/gemspec_help'
|
87
87
|
require_relative 'rubocop/cop/mixin/hash_alignment_styles'
|
88
88
|
require_relative 'rubocop/cop/mixin/hash_transform_method'
|
89
|
-
require_relative 'rubocop/cop/mixin/ignored_methods'
|
90
89
|
require_relative 'rubocop/cop/mixin/integer_node'
|
91
90
|
require_relative 'rubocop/cop/mixin/interpolation'
|
92
91
|
require_relative 'rubocop/cop/mixin/line_length_help'
|
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.
|
4
|
+
version: 1.33.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-08-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -208,6 +208,7 @@ files:
|
|
208
208
|
- exe/rubocop
|
209
209
|
- lib/rubocop.rb
|
210
210
|
- lib/rubocop/ast_aliases.rb
|
211
|
+
- lib/rubocop/cache_config.rb
|
211
212
|
- lib/rubocop/cached_data.rb
|
212
213
|
- lib/rubocop/cli.rb
|
213
214
|
- lib/rubocop/cli/command.rb
|
@@ -222,6 +223,7 @@ files:
|
|
222
223
|
- lib/rubocop/cli/environment.rb
|
223
224
|
- lib/rubocop/comment_config.rb
|
224
225
|
- lib/rubocop/config.rb
|
226
|
+
- lib/rubocop/config_finder.rb
|
225
227
|
- lib/rubocop/config_loader.rb
|
226
228
|
- lib/rubocop/config_loader_resolver.rb
|
227
229
|
- lib/rubocop/config_obsoletion.rb
|
@@ -581,7 +583,6 @@ files:
|
|
581
583
|
- lib/rubocop/cop/mixin/hash_shorthand_syntax.rb
|
582
584
|
- lib/rubocop/cop/mixin/hash_transform_method.rb
|
583
585
|
- lib/rubocop/cop/mixin/heredoc.rb
|
584
|
-
- lib/rubocop/cop/mixin/ignored_methods.rb
|
585
586
|
- lib/rubocop/cop/mixin/integer_node.rb
|
586
587
|
- lib/rubocop/cop/mixin/interpolation.rb
|
587
588
|
- lib/rubocop/cop/mixin/line_length_help.rb
|
@@ -971,7 +972,7 @@ metadata:
|
|
971
972
|
homepage_uri: https://rubocop.org/
|
972
973
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
973
974
|
source_code_uri: https://github.com/rubocop/rubocop/
|
974
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
975
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.33/
|
975
976
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
976
977
|
rubygems_mfa_required: 'true'
|
977
978
|
post_install_message:
|