rubocop 1.32.0 → 1.33.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 +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:
|