rubocop 1.32.0 → 1.35.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 +4 -4
- data/README.md +2 -2
- data/config/default.yml +73 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +12 -40
- data/lib/rubocop/config_loader_resolver.rb +1 -5
- 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/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
- data/lib/rubocop/cop/layout/line_length.rb +4 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
- data/lib/rubocop/cop/legacy/corrector.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +26 -16
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +65 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
- data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
- data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +7 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -4
- data/lib/rubocop/cop/lint/void.rb +2 -0
- 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/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +76 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +4 -5
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
- 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/class_methods_definitions.rb +2 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
- data/lib/rubocop/cop/style/double_negation.rb +2 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +39 -8
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/guard_clause.rb +27 -16
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
- data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
- 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/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +3 -5
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/object_then.rb +2 -0
- data/lib/rubocop/cop/style/proc.rb +4 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -22
- data/lib/rubocop/cop/style/redundant_self.rb +2 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +34 -9
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/ext/range.rb +15 -0
- data/lib/rubocop/feature_loader.rb +94 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +3 -3
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/server/cache.rb +36 -1
- data/lib/rubocop/server/cli.rb +19 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -3
- metadata +15 -9
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -148,7 +148,18 @@ module RuboCop
|
|
148
148
|
)
|
149
149
|
corrector.replace(range, and_operator)
|
150
150
|
corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
|
151
|
-
|
151
|
+
|
152
|
+
wrap_condition(corrector, if_branch.condition)
|
153
|
+
end
|
154
|
+
|
155
|
+
def wrap_condition(corrector, condition)
|
156
|
+
# Handle `send` and `block` nodes that need to be wrapped in parens
|
157
|
+
# FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
|
158
|
+
# but wrapping the argument list would be a more ergonomic correction.
|
159
|
+
node_to_check = condition&.block_type? ? condition.send_node : condition
|
160
|
+
return unless wrap_condition?(node_to_check)
|
161
|
+
|
162
|
+
corrector.wrap(condition, '(', ')')
|
152
163
|
end
|
153
164
|
|
154
165
|
def correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
|
@@ -162,8 +173,6 @@ module RuboCop
|
|
162
173
|
end
|
163
174
|
|
164
175
|
def correct_for_comment(corrector, node, if_branch)
|
165
|
-
return if config.for_cop('Style/IfUnlessModifier')['Enabled']
|
166
|
-
|
167
176
|
comments = processed_source.ast_with_comments[if_branch]
|
168
177
|
comment_text = comments.map(&:text).join("\n") << "\n"
|
169
178
|
|
@@ -207,7 +216,7 @@ module RuboCop
|
|
207
216
|
end
|
208
217
|
|
209
218
|
def require_parentheses?(condition)
|
210
|
-
condition.
|
219
|
+
condition.call_type? && !condition.arguments.empty? && !condition.parenthesized? &&
|
211
220
|
!condition.comparison_method?
|
212
221
|
end
|
213
222
|
|
@@ -219,7 +228,7 @@ module RuboCop
|
|
219
228
|
|
220
229
|
def wrap_condition?(node)
|
221
230
|
node.and_type? || node.or_type? ||
|
222
|
-
(node.
|
231
|
+
(node.call_type? && node.arguments.any? && !node.parenthesized?)
|
223
232
|
end
|
224
233
|
|
225
234
|
def replace_condition(condition)
|
@@ -69,7 +69,7 @@ module RuboCop
|
|
69
69
|
if c.dsym_type?
|
70
70
|
string_literal = to_string_literal(c.source)
|
71
71
|
|
72
|
-
":#{
|
72
|
+
":#{trim_string_interpolation_escape_character(string_literal)}"
|
73
73
|
else
|
74
74
|
to_symbol_literal(c.value.to_s)
|
75
75
|
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,17 @@ 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)
|
124
|
+
return if unsafe_array_usage?(dispatch_node)
|
113
125
|
return if %i[lambda proc].include?(dispatch_node.method_name)
|
114
|
-
return if
|
126
|
+
return if allowed_method_name?(dispatch_node.method_name)
|
115
127
|
return if allow_if_method_has_argument?(node.send_node)
|
116
128
|
return if node.block_type? && destructuring_block_argument?(arguments_node)
|
117
129
|
return if allow_comments? && contains_comments?(node)
|
@@ -119,7 +131,7 @@ module RuboCop
|
|
119
131
|
register_offense(node, method_name, dispatch_node.method_name)
|
120
132
|
end
|
121
133
|
end
|
122
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
134
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
123
135
|
alias on_numblock on_block
|
124
136
|
|
125
137
|
def destructuring_block_argument?(argument_node)
|
@@ -128,6 +140,19 @@ module RuboCop
|
|
128
140
|
|
129
141
|
private
|
130
142
|
|
143
|
+
# See: https://github.com/rubocop/rubocop/issues/10864
|
144
|
+
def unsafe_hash_usage?(node)
|
145
|
+
node.receiver&.hash_type? && %i[reject select].include?(node.method_name)
|
146
|
+
end
|
147
|
+
|
148
|
+
def unsafe_array_usage?(node)
|
149
|
+
node.receiver&.array_type? && %i[min max].include?(node.method_name)
|
150
|
+
end
|
151
|
+
|
152
|
+
def allowed_method_name?(name)
|
153
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
154
|
+
end
|
155
|
+
|
131
156
|
def register_offense(node, method_name, block_method_name)
|
132
157
|
block_start = node.loc.begin.begin_pos
|
133
158
|
block_end = node.loc.end.end_pos
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
71
71
|
|
72
72
|
return if only_closing_parenthesis_is_last_line?(condition)
|
73
73
|
return if condition_as_parenthesized_one_line_pattern_matching?(condition)
|
74
|
-
return unless node.ternary? &&
|
74
|
+
return unless node.ternary? && offense?(node)
|
75
75
|
|
76
76
|
message = message(node)
|
77
77
|
|
@@ -166,22 +166,10 @@ module RuboCop
|
|
166
166
|
style == :require_parentheses_when_complex
|
167
167
|
end
|
168
168
|
|
169
|
-
def redundant_parentheses_enabled?
|
170
|
-
@config.for_cop('Style/RedundantParentheses').fetch('Enabled')
|
171
|
-
end
|
172
|
-
|
173
169
|
def parenthesized?(node)
|
174
170
|
node.begin_type?
|
175
171
|
end
|
176
172
|
|
177
|
-
# When this cop is configured to enforce parentheses and the
|
178
|
-
# `RedundantParentheses` cop is enabled, it will cause an infinite loop
|
179
|
-
# as they compete to add and remove the parentheses respectively.
|
180
|
-
def infinite_loop?
|
181
|
-
(require_parentheses? || require_parentheses_when_complex?) &&
|
182
|
-
redundant_parentheses_enabled?
|
183
|
-
end
|
184
|
-
|
185
173
|
def unsafe_autocorrect?(condition)
|
186
174
|
condition.children.any? do |child|
|
187
175
|
unparenthesized_method_call?(child) || below_ternary_precedence?(child)
|
@@ -63,6 +63,8 @@ module RuboCop
|
|
63
63
|
add_offense(node)
|
64
64
|
end
|
65
65
|
|
66
|
+
alias on_numblock on_block
|
67
|
+
|
66
68
|
private
|
67
69
|
|
68
70
|
def top_level_method_definition?(node)
|
@@ -75,7 +77,7 @@ module RuboCop
|
|
75
77
|
|
76
78
|
# @!method define_method_block?(node)
|
77
79
|
def_node_matcher :define_method_block?, <<~PATTERN
|
78
|
-
(block (send _ {:define_method} _) ...)
|
80
|
+
({block numblock} (send _ {:define_method} _) ...)
|
79
81
|
PATTERN
|
80
82
|
end
|
81
83
|
end
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
|
65
65
|
MSG = 'Useless trailing comma present in block arguments.'
|
66
66
|
|
67
|
-
def on_block(node)
|
67
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
68
68
|
# lambda literal (`->`) never has block arguments.
|
69
69
|
return if node.send_node.lambda_literal?
|
70
70
|
return unless useless_trailing_comma?(node)
|
@@ -87,7 +87,7 @@ module RuboCop
|
|
87
87
|
if word.dstr_type?
|
88
88
|
string_literal = to_string_literal(word.source)
|
89
89
|
|
90
|
-
|
90
|
+
trim_string_interpolation_escape_character(string_literal)
|
91
91
|
else
|
92
92
|
to_string_literal(word.children[0])
|
93
93
|
end
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Ext
|
5
|
+
# Extensions to Parser::Source::Range
|
6
|
+
module Range
|
7
|
+
# Adds `Range#single_line?` to parallel `Node#single_line?`
|
8
|
+
def single_line?
|
9
|
+
first_line == last_line
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Parser::Source::Range.include RuboCop::Ext::Range
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# This class handles loading files (a.k.a. features in Ruby) specified
|
5
|
+
# by `--require` command line option and `require` directive in the config.
|
6
|
+
#
|
7
|
+
# Normally, the given string is directly passed to `require`. If a string
|
8
|
+
# beginning with `.` is given, it is assumed to be relative to the given
|
9
|
+
# directory.
|
10
|
+
#
|
11
|
+
# If a string containing `-` is given, it will be used as is, but if we
|
12
|
+
# cannot find the file to load, we will replace `-` with `/` and try it
|
13
|
+
# again as when Bundler loads gems.
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
class FeatureLoader
|
17
|
+
class << self
|
18
|
+
# @param [String] config_directory_path
|
19
|
+
# @param [String] feature
|
20
|
+
def load(config_directory_path:, feature:)
|
21
|
+
new(config_directory_path: config_directory_path, feature: feature).load
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String] config_directory_path
|
26
|
+
# @param [String] feature
|
27
|
+
def initialize(config_directory_path:, feature:)
|
28
|
+
@config_directory_path = config_directory_path
|
29
|
+
@feature = feature
|
30
|
+
end
|
31
|
+
|
32
|
+
def load
|
33
|
+
# Don't use `::Kernel.require(target)` to prevent the following error:
|
34
|
+
# https://github.com/rubocop/rubocop/issues/10893
|
35
|
+
require(target)
|
36
|
+
rescue ::LoadError => e
|
37
|
+
raise if e.path != target
|
38
|
+
|
39
|
+
begin
|
40
|
+
# Don't use `::Kernel.require(target)` to prevent the following error:
|
41
|
+
# https://github.com/rubocop/rubocop/issues/10893
|
42
|
+
require(namespaced_target)
|
43
|
+
rescue ::LoadError => error_for_namespaced_target
|
44
|
+
# NOTE: This wrap is necessary due to JRuby 9.3.4.0 incompatibility:
|
45
|
+
# https://github.com/jruby/jruby/issues/7316
|
46
|
+
raise LoadError, e if error_for_namespaced_target.path == namespaced_target
|
47
|
+
|
48
|
+
raise error_for_namespaced_target
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# @return [String]
|
55
|
+
def namespaced_feature
|
56
|
+
@feature.tr('-', '/')
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [String]
|
60
|
+
def namespaced_target
|
61
|
+
if relative?
|
62
|
+
relative(namespaced_feature)
|
63
|
+
else
|
64
|
+
namespaced_feature
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param [String]
|
69
|
+
# @return [String]
|
70
|
+
def relative(feature)
|
71
|
+
::File.join(@config_directory_path, feature)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Boolean]
|
75
|
+
def relative?
|
76
|
+
@feature.start_with?('.')
|
77
|
+
end
|
78
|
+
|
79
|
+
# @param [LoadError] error
|
80
|
+
# @return [Boolean]
|
81
|
+
def seems_cannot_load_such_file_error?(error)
|
82
|
+
error.path == target
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [String]
|
86
|
+
def target
|
87
|
+
if relative?
|
88
|
+
relative(@feature)
|
89
|
+
else
|
90
|
+
@feature
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -93,12 +93,12 @@ module RuboCop
|
|
93
93
|
|
94
94
|
def highlighted_source_line(offense)
|
95
95
|
source_before_highlight(offense) +
|
96
|
-
|
96
|
+
highlight_source_tag(offense) +
|
97
97
|
source_after_highlight(offense) +
|
98
98
|
possible_ellipses(offense.location)
|
99
99
|
end
|
100
100
|
|
101
|
-
def
|
101
|
+
def highlight_source_tag(offense)
|
102
102
|
"<span class=\"highlight #{offense.severity}\">" \
|
103
103
|
"#{escape(offense.highlighted_area.source)}" \
|
104
104
|
'</span>'
|
@@ -115,7 +115,7 @@ module RuboCop
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def possible_ellipses(location)
|
118
|
-
location.
|
118
|
+
location.single_line? ? '' : " #{ELLIPSES}"
|
119
119
|
end
|
120
120
|
|
121
121
|
def escape(string)
|
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,43 @@ 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
|
+
config_path = ConfigFinder.find_config_path(Dir.pwd)
|
66
|
+
|
67
|
+
require 'erb'
|
68
|
+
file_contents = File.read(config_path)
|
69
|
+
yaml_code = ERB.new(file_contents).result
|
70
|
+
|
71
|
+
config_yaml = YAML.safe_load(yaml_code, permitted_classes: [Regexp, Symbol])
|
72
|
+
|
73
|
+
# For compatibility with Ruby 3.0 or lower.
|
74
|
+
if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
|
75
|
+
config_yaml == false ? nil : config_yaml
|
76
|
+
end
|
77
|
+
|
78
|
+
config_yaml&.dig('AllCops', 'CacheRootDirectory')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
47
82
|
def port_path
|
48
83
|
dir.join('port')
|
49
84
|
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
@@ -16,6 +16,7 @@ require 'rubocop-ast'
|
|
16
16
|
require_relative 'rubocop/ast_aliases'
|
17
17
|
require_relative 'rubocop/ext/regexp_node'
|
18
18
|
require_relative 'rubocop/ext/regexp_parser'
|
19
|
+
require_relative 'rubocop/ext/range'
|
19
20
|
|
20
21
|
require_relative 'rubocop/core_ext/string'
|
21
22
|
require_relative 'rubocop/ext/processed_source'
|
@@ -47,6 +48,7 @@ require_relative 'rubocop/cop/severity'
|
|
47
48
|
require_relative 'rubocop/cop/generator'
|
48
49
|
require_relative 'rubocop/cop/generator/configuration_injector'
|
49
50
|
require_relative 'rubocop/cop/generator/require_file_injector'
|
51
|
+
require_relative 'rubocop/magic_comment'
|
50
52
|
|
51
53
|
require_relative 'rubocop/cop/variable_force'
|
52
54
|
require_relative 'rubocop/cop/variable_force/branch'
|
@@ -86,7 +88,6 @@ require_relative 'rubocop/cop/mixin/gem_declaration'
|
|
86
88
|
require_relative 'rubocop/cop/mixin/gemspec_help'
|
87
89
|
require_relative 'rubocop/cop/mixin/hash_alignment_styles'
|
88
90
|
require_relative 'rubocop/cop/mixin/hash_transform_method'
|
89
|
-
require_relative 'rubocop/cop/mixin/ignored_methods'
|
90
91
|
require_relative 'rubocop/cop/mixin/integer_node'
|
91
92
|
require_relative 'rubocop/cop/mixin/interpolation'
|
92
93
|
require_relative 'rubocop/cop/mixin/line_length_help'
|
@@ -529,6 +530,7 @@ require_relative 'rubocop/cop/style/keyword_parameters_order'
|
|
529
530
|
require_relative 'rubocop/cop/style/lambda'
|
530
531
|
require_relative 'rubocop/cop/style/lambda_call'
|
531
532
|
require_relative 'rubocop/cop/style/line_end_concatenation'
|
533
|
+
require_relative 'rubocop/cop/style/magic_comment_format'
|
532
534
|
require_relative 'rubocop/cop/style/map_to_hash'
|
533
535
|
require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
|
534
536
|
require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
|
@@ -690,18 +692,18 @@ require_relative 'rubocop/config_obsoletion/split_cop'
|
|
690
692
|
require_relative 'rubocop/config_obsoletion'
|
691
693
|
require_relative 'rubocop/config_store'
|
692
694
|
require_relative 'rubocop/config_validator'
|
695
|
+
require_relative 'rubocop/feature_loader'
|
693
696
|
require_relative 'rubocop/lockfile'
|
694
697
|
require_relative 'rubocop/target_finder'
|
695
698
|
require_relative 'rubocop/directive_comment'
|
696
699
|
require_relative 'rubocop/comment_config'
|
697
|
-
require_relative 'rubocop/magic_comment'
|
698
700
|
require_relative 'rubocop/result_cache'
|
699
701
|
require_relative 'rubocop/runner'
|
700
702
|
require_relative 'rubocop/cli'
|
701
703
|
require_relative 'rubocop/cli/command'
|
702
704
|
require_relative 'rubocop/cli/environment'
|
703
705
|
require_relative 'rubocop/cli/command/base'
|
704
|
-
require_relative 'rubocop/cli/command/
|
706
|
+
require_relative 'rubocop/cli/command/auto_generate_config'
|
705
707
|
require_relative 'rubocop/cli/command/execute_runner'
|
706
708
|
require_relative 'rubocop/cli/command/init_dotfile'
|
707
709
|
require_relative 'rubocop/cli/command/show_cops'
|