rubocop 1.43.0 → 1.45.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 +1 -1
- data/config/default.yml +64 -29
- data/lib/rubocop/cli.rb +54 -8
- data/lib/rubocop/config_loader.rb +12 -15
- data/lib/rubocop/config_loader_resolver.rb +3 -4
- data/lib/rubocop/cop/base.rb +27 -9
- data/lib/rubocop/cop/commissioner.rb +8 -2
- data/lib/rubocop/cop/cop.rb +23 -3
- data/lib/rubocop/cop/corrector.rb +10 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -6
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -1
- data/lib/rubocop/cop/layout/class_structure.rb +2 -16
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +6 -9
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
- data/lib/rubocop/cop/lint/debugger.rb +8 -27
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
- data/lib/rubocop/cop/lint/else_layout.rb +2 -6
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +15 -17
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -5
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +11 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -4
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -3
- data/lib/rubocop/cop/lint/useless_rescue.rb +15 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +9 -1
- data/lib/rubocop/cop/lint/void.rb +19 -10
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +2 -5
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -3
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +51 -25
- data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -0
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
- data/lib/rubocop/cop/registry.rb +12 -7
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -11
- data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +8 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +3 -10
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +0 -6
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/documentation_method.rb +6 -0
- data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +114 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +11 -5
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/min_max_comparison.rb +11 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -5
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +16 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +0 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +16 -10
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
- data/lib/rubocop/cop/style/require_order.rb +2 -9
- data/lib/rubocop/cop/style/self_assignment.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +24 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +12 -5
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
- data/lib/rubocop/cop/team.rb +19 -14
- data/lib/rubocop/cop/variable_force/scope.rb +3 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -1
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/formatter.rb +0 -1
- data/lib/rubocop/options.rb +22 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -4
- data/lib/rubocop/runner.rb +40 -4
- data/lib/rubocop/server/cache.rb +10 -3
- data/lib/rubocop/server/cli.rb +37 -18
- data/lib/rubocop/server/client_command/exec.rb +1 -1
- data/lib/rubocop/server/client_command/start.rb +6 -1
- data/lib/rubocop/server/core.rb +23 -8
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +4 -0
- metadata +11 -27
@@ -33,12 +33,14 @@ module RuboCop
|
|
33
33
|
# "bar" != foo
|
34
34
|
# 42 >= foo
|
35
35
|
# 10 < bar
|
36
|
+
# 99 == CONST
|
36
37
|
#
|
37
38
|
# # good
|
38
39
|
# foo == 99
|
39
40
|
# foo == "bar"
|
40
41
|
# foo <= 42
|
41
42
|
# bar > 10
|
43
|
+
# CONST == 99
|
42
44
|
# "#{interpolation}" == foo
|
43
45
|
# /#{interpolation}/ == foo
|
44
46
|
#
|
@@ -92,9 +94,10 @@ module RuboCop
|
|
92
94
|
def on_send(node)
|
93
95
|
return unless yoda_compatible_condition?(node)
|
94
96
|
return if (equality_only? && non_equality_operator?(node)) ||
|
95
|
-
file_constant_equal_program_name?(node)
|
97
|
+
file_constant_equal_program_name?(node) ||
|
98
|
+
valid_yoda?(node)
|
96
99
|
|
97
|
-
|
100
|
+
add_offense(node) do |corrector|
|
98
101
|
corrector.replace(actual_code_range(node), corrected_code(node))
|
99
102
|
end
|
100
103
|
end
|
@@ -119,11 +122,11 @@ module RuboCop
|
|
119
122
|
lhs = node.receiver
|
120
123
|
rhs = node.first_argument
|
121
124
|
|
122
|
-
return true if (lhs
|
123
|
-
(!lhs
|
125
|
+
return true if (constant_portion?(lhs) && constant_portion?(rhs)) ||
|
126
|
+
(!constant_portion?(lhs) && !constant_portion?(rhs)) ||
|
124
127
|
interpolation?(lhs)
|
125
128
|
|
126
|
-
enforce_yoda? ? lhs
|
129
|
+
enforce_yoda? ? constant_portion?(lhs) : constant_portion?(rhs)
|
127
130
|
end
|
128
131
|
|
129
132
|
def message(node)
|
@@ -137,6 +140,10 @@ module RuboCop
|
|
137
140
|
"#{rhs.source} #{reverse_comparison(node.method_name)} #{lhs.source}"
|
138
141
|
end
|
139
142
|
|
143
|
+
def constant_portion?(node)
|
144
|
+
node.literal? || node.const_type?
|
145
|
+
end
|
146
|
+
|
140
147
|
def actual_code_range(node)
|
141
148
|
range_between(node.loc.expression.begin_pos, node.loc.expression.end_pos)
|
142
149
|
end
|
@@ -24,12 +24,14 @@ module RuboCop
|
|
24
24
|
# 1 + x
|
25
25
|
# 10 * y
|
26
26
|
# 1 & z
|
27
|
+
# 1 + CONST
|
27
28
|
#
|
28
29
|
# # good
|
29
30
|
# 60 * 24
|
30
31
|
# x + 1
|
31
32
|
# y * 10
|
32
33
|
# z & 1
|
34
|
+
# CONST + 1
|
33
35
|
#
|
34
36
|
# # good
|
35
37
|
# 1 | x
|
@@ -50,8 +52,7 @@ module RuboCop
|
|
50
52
|
|
51
53
|
lhs = node.receiver
|
52
54
|
rhs = node.first_argument
|
53
|
-
return
|
54
|
-
|
55
|
+
return unless yoda_expression_constant?(lhs, rhs)
|
55
56
|
return if offended_ancestor?(node)
|
56
57
|
|
57
58
|
message = format(MSG, source: rhs.source)
|
@@ -64,6 +65,14 @@ module RuboCop
|
|
64
65
|
|
65
66
|
private
|
66
67
|
|
68
|
+
def yoda_expression_constant?(lhs, rhs)
|
69
|
+
constant_portion?(lhs) && !constant_portion?(rhs)
|
70
|
+
end
|
71
|
+
|
72
|
+
def constant_portion?(node)
|
73
|
+
node.numeric_type? || node.const_type?
|
74
|
+
end
|
75
|
+
|
67
76
|
def supported_operators
|
68
77
|
Array(cop_config['SupportedOperators'])
|
69
78
|
end
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -77,7 +77,7 @@ module RuboCop
|
|
77
77
|
end
|
78
78
|
|
79
79
|
# @return [Commissioner::InvestigationReport]
|
80
|
-
def investigate(processed_source)
|
80
|
+
def investigate(processed_source, offset: 0, original: processed_source)
|
81
81
|
be_ready
|
82
82
|
|
83
83
|
# The autocorrection process may have to be repeated multiple times
|
@@ -87,14 +87,15 @@ module RuboCop
|
|
87
87
|
on_duty = roundup_relevant_cops(processed_source.file_path)
|
88
88
|
|
89
89
|
autocorrect_cops, other_cops = on_duty.partition(&:autocorrect?)
|
90
|
+
report = investigate_partial(autocorrect_cops, processed_source,
|
91
|
+
offset: offset, original: original)
|
90
92
|
|
91
|
-
report
|
92
|
-
|
93
|
-
unless autocorrect(processed_source, report)
|
93
|
+
unless autocorrect(processed_source, report, offset: offset, original: original)
|
94
94
|
# If we corrected some errors, another round of inspection will be
|
95
95
|
# done, and any other offenses will be caught then, so only need
|
96
96
|
# to check other_cops if no correction was done
|
97
|
-
report = report.merge(investigate_partial(other_cops, processed_source
|
97
|
+
report = report.merge(investigate_partial(other_cops, processed_source,
|
98
|
+
offset: offset, original: original))
|
98
99
|
end
|
99
100
|
|
100
101
|
process_errors(processed_source.path, report.errors)
|
@@ -116,12 +117,12 @@ module RuboCop
|
|
116
117
|
|
117
118
|
private
|
118
119
|
|
119
|
-
def autocorrect(processed_source, report)
|
120
|
+
def autocorrect(processed_source, report, original:, offset:)
|
120
121
|
@updated_source_file = false
|
121
122
|
return unless autocorrect?
|
122
123
|
return if report.processed_source.parser_error
|
123
124
|
|
124
|
-
new_source = autocorrect_report(report)
|
125
|
+
new_source = autocorrect_report(report, original: original, offset: offset)
|
125
126
|
|
126
127
|
return unless new_source
|
127
128
|
|
@@ -149,9 +150,9 @@ module RuboCop
|
|
149
150
|
end
|
150
151
|
|
151
152
|
# @return [Commissioner::InvestigationReport]
|
152
|
-
def investigate_partial(cops, processed_source)
|
153
|
+
def investigate_partial(cops, processed_source, offset:, original:)
|
153
154
|
commissioner = Commissioner.new(cops, self.class.forces_for(cops), @options)
|
154
|
-
commissioner.investigate(processed_source)
|
155
|
+
commissioner.investigate(processed_source, offset: offset, original: original)
|
155
156
|
end
|
156
157
|
|
157
158
|
# @return [Array<cop>]
|
@@ -175,18 +176,22 @@ module RuboCop
|
|
175
176
|
cop.class.support_target_rails_version?(cop.target_rails_version)
|
176
177
|
end
|
177
178
|
|
178
|
-
def autocorrect_report(report)
|
179
|
-
corrector = collate_corrections(report)
|
179
|
+
def autocorrect_report(report, offset:, original:)
|
180
|
+
corrector = collate_corrections(report, offset: offset, original: original)
|
180
181
|
|
181
182
|
corrector.rewrite unless corrector.empty?
|
182
183
|
end
|
183
184
|
|
184
|
-
def collate_corrections(report)
|
185
|
-
corrector = Corrector.new(
|
185
|
+
def collate_corrections(report, offset:, original:)
|
186
|
+
corrector = Corrector.new(original)
|
186
187
|
|
187
188
|
each_corrector(report) do |to_merge|
|
188
189
|
suppress_clobbering do
|
189
|
-
|
190
|
+
if offset.positive?
|
191
|
+
corrector.import!(to_merge, offset: offset)
|
192
|
+
else
|
193
|
+
corrector.merge!(to_merge)
|
194
|
+
end
|
190
195
|
end
|
191
196
|
end
|
192
197
|
|
@@ -45,9 +45,9 @@ module RuboCop
|
|
45
45
|
node
|
46
46
|
else
|
47
47
|
child_index = case node.type
|
48
|
-
when :module, :sclass
|
49
|
-
when :def, :class, :block then 2
|
50
|
-
when :defs
|
48
|
+
when :module, :sclass then 1
|
49
|
+
when :def, :class, :block, :numblock then 2
|
50
|
+
when :defs then 3
|
51
51
|
end
|
52
52
|
|
53
53
|
node.children[child_index]
|
@@ -97,8 +97,10 @@ module RuboCop
|
|
97
97
|
scope_stack.reverse_each do |scope|
|
98
98
|
variable = scope.variables[name]
|
99
99
|
return variable if variable
|
100
|
+
|
100
101
|
# Only block scope allows referencing outer scope variables.
|
101
|
-
|
102
|
+
node = scope.node
|
103
|
+
return nil unless node.block_type? || node.numblock_type?
|
102
104
|
end
|
103
105
|
|
104
106
|
nil
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
|
51
51
|
ZERO_ARITY_SUPER_TYPE = :zsuper
|
52
52
|
|
53
|
-
TWISTED_SCOPE_TYPES = %i[block class sclass defs module].freeze
|
53
|
+
TWISTED_SCOPE_TYPES = %i[block numblock class sclass defs module].freeze
|
54
54
|
SCOPE_TYPES = (TWISTED_SCOPE_TYPES + [:def]).freeze
|
55
55
|
|
56
56
|
SEND_TYPE = :send
|
data/lib/rubocop/formatter.rb
CHANGED
data/lib/rubocop/options.rb
CHANGED
@@ -61,6 +61,9 @@ module RuboCop
|
|
61
61
|
add_config_generation_options(opts)
|
62
62
|
add_additional_modes(opts)
|
63
63
|
add_general_options(opts)
|
64
|
+
|
65
|
+
# `stackprof` is not supported on JRuby and Windows.
|
66
|
+
add_profile_options(opts) if RUBY_ENGINE == 'ruby' && !Platform.windows?
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
@@ -206,6 +209,7 @@ module RuboCop
|
|
206
209
|
option(opts, '--start-server')
|
207
210
|
option(opts, '--stop-server')
|
208
211
|
option(opts, '--server-status')
|
212
|
+
option(opts, '--no-detach')
|
209
213
|
end
|
210
214
|
end
|
211
215
|
|
@@ -233,6 +237,16 @@ module RuboCop
|
|
233
237
|
end
|
234
238
|
end
|
235
239
|
|
240
|
+
def add_profile_options(opts)
|
241
|
+
section(opts, 'Profiling Options') do
|
242
|
+
option(opts, '--profile') do
|
243
|
+
@options[:profile] = true
|
244
|
+
@options[:cache] = 'false' unless @options.key?(:cache)
|
245
|
+
end
|
246
|
+
option(opts, '--memory')
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
236
250
|
def handle_deprecated_option(old_option, new_option)
|
237
251
|
warn rainbow.wrap("#{old_option} is deprecated; use #{new_option} instead.").yellow
|
238
252
|
@options[long_opt_symbol([new_option])] = @options.delete(long_opt_symbol([old_option]))
|
@@ -424,6 +438,8 @@ module RuboCop
|
|
424
438
|
def invalid_arguments_for_parallel
|
425
439
|
[('--auto-gen-config' if @options.key?(:auto_gen_config)),
|
426
440
|
('-F/--fail-fast' if @options.key?(:fail_fast)),
|
441
|
+
('--profile' if @options[:profile]),
|
442
|
+
('--memory' if @options[:memory]),
|
427
443
|
('--cache false' if @options > { cache: 'false' })].compact
|
428
444
|
end
|
429
445
|
|
@@ -465,6 +481,7 @@ module RuboCop
|
|
465
481
|
|
466
482
|
# This module contains help texts for command line options.
|
467
483
|
# @api private
|
484
|
+
# rubocop:disable Metrics/ModuleLength
|
468
485
|
module OptionsHelp
|
469
486
|
MAX_EXCL = RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS.to_s
|
470
487
|
FORMATTER_OPTION_LIST = RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys
|
@@ -599,9 +616,13 @@ module RuboCop
|
|
599
616
|
start_server: 'Start server process.',
|
600
617
|
stop_server: 'Stop server process.',
|
601
618
|
server_status: 'Show server status.',
|
619
|
+
no_detach: 'Run the server process in the foreground.',
|
602
620
|
raise_cop_error: ['Raise cop-related errors with cause and location.',
|
603
621
|
'This is used to prevent cops from failing silently.',
|
604
|
-
'Default is false.']
|
622
|
+
'Default is false.'],
|
623
|
+
profile: 'Profile rubocop',
|
624
|
+
memory: 'Profile rubocop memory usage'
|
605
625
|
}.freeze
|
606
626
|
end
|
627
|
+
# rubocop:enable Metrics/ModuleLength
|
607
628
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# This mixin makes it easier to specify strict offense expectations
|
8
8
|
# in a declarative and visual fashion. Just type out the code that
|
9
|
-
# should generate
|
9
|
+
# should generate an offense, annotate code by writing '^'s
|
10
10
|
# underneath each character that should be highlighted, and follow
|
11
11
|
# the carets with a string (separated by a space) that is the
|
12
12
|
# message of the offense. You can include multiple offenses in
|
@@ -126,7 +126,7 @@ module RuboCop
|
|
126
126
|
@offenses
|
127
127
|
end
|
128
128
|
|
129
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
129
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
130
130
|
def expect_correction(correction, loop: true, source: nil)
|
131
131
|
if source
|
132
132
|
expected_annotations = parse_annotations(source, raise_error: false)
|
@@ -138,6 +138,8 @@ module RuboCop
|
|
138
138
|
|
139
139
|
source = @processed_source.raw_source
|
140
140
|
|
141
|
+
raise 'Use `expect_no_corrections` if the code will not change' if correction == source
|
142
|
+
|
141
143
|
iteration = 0
|
142
144
|
new_source = loop do
|
143
145
|
iteration += 1
|
@@ -157,11 +159,11 @@ module RuboCop
|
|
157
159
|
_investigate(cop, @processed_source)
|
158
160
|
end
|
159
161
|
|
160
|
-
raise '
|
162
|
+
raise 'Expected correction but no corrections were made' if new_source == source
|
161
163
|
|
162
164
|
expect(new_source).to eq(correction)
|
163
165
|
end
|
164
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
166
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
165
167
|
|
166
168
|
def expect_no_corrections
|
167
169
|
raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
|
data/lib/rubocop/runner.rb
CHANGED
@@ -24,6 +24,27 @@ module RuboCop
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
class << self
|
28
|
+
# @return [Array<#call>]
|
29
|
+
def ruby_extractors
|
30
|
+
@ruby_extractors ||= [default_ruby_extractor]
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# @return [#call]
|
36
|
+
def default_ruby_extractor
|
37
|
+
lambda do |processed_source|
|
38
|
+
[
|
39
|
+
{
|
40
|
+
offset: 0,
|
41
|
+
processed_source: processed_source
|
42
|
+
}
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
27
48
|
# @api private
|
28
49
|
MAX_ITERATIONS = 200
|
29
50
|
|
@@ -319,10 +340,25 @@ module RuboCop
|
|
319
340
|
end
|
320
341
|
|
321
342
|
def inspect_file(processed_source, team = mobilize_team(processed_source))
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
343
|
+
extracted_ruby_sources = extract_ruby_sources(processed_source)
|
344
|
+
offenses = extracted_ruby_sources.flat_map do |extracted_ruby_source|
|
345
|
+
report = team.investigate(
|
346
|
+
extracted_ruby_source[:processed_source],
|
347
|
+
offset: extracted_ruby_source[:offset],
|
348
|
+
original: processed_source
|
349
|
+
)
|
350
|
+
@errors.concat(team.errors)
|
351
|
+
@warnings.concat(team.warnings)
|
352
|
+
report.offenses
|
353
|
+
end
|
354
|
+
[offenses, team.updated_source_file?]
|
355
|
+
end
|
356
|
+
|
357
|
+
def extract_ruby_sources(processed_source)
|
358
|
+
self.class.ruby_extractors.find do |ruby_extractor|
|
359
|
+
result = ruby_extractor.call(processed_source)
|
360
|
+
break result if result
|
361
|
+
end
|
326
362
|
end
|
327
363
|
|
328
364
|
def mobilize_team(processed_source)
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -57,18 +57,24 @@ module RuboCop
|
|
57
57
|
File.expand_path(File.join(cache_root_dir, 'server'))
|
58
58
|
end
|
59
59
|
|
60
|
+
# rubocop:disable Metrics/MethodLength
|
60
61
|
def cache_root_dir_from_config
|
61
62
|
CacheConfig.root_dir do
|
62
63
|
# `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
|
63
64
|
# so that only the necessary `CacheRootDirectory` can be obtained.
|
64
|
-
require 'yaml'
|
65
65
|
config_path = ConfigFinder.find_config_path(Dir.pwd)
|
66
|
+
file_contents = File.read(config_path)
|
67
|
+
|
68
|
+
# Returns early if `CacheRootDirectory` is not used before requiring `erb` or `yaml`.
|
69
|
+
next unless file_contents.include?('CacheRootDirectory')
|
66
70
|
|
67
71
|
require 'erb'
|
68
|
-
file_contents = File.read(config_path)
|
69
72
|
yaml_code = ERB.new(file_contents).result
|
70
73
|
|
71
|
-
|
74
|
+
require 'yaml'
|
75
|
+
config_yaml = YAML.safe_load(
|
76
|
+
yaml_code, permitted_classes: [Regexp, Symbol], aliases: true
|
77
|
+
)
|
72
78
|
|
73
79
|
# For compatibility with Ruby 3.0 or lower.
|
74
80
|
if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
|
@@ -78,6 +84,7 @@ module RuboCop
|
|
78
84
|
config_yaml&.dig('AllCops', 'CacheRootDirectory')
|
79
85
|
end
|
80
86
|
end
|
87
|
+
# rubocop:enable Metrics/MethodLength
|
81
88
|
|
82
89
|
def port_path
|
83
90
|
dir.join('port')
|
data/lib/rubocop/server/cli.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rainbow'
|
4
3
|
require_relative '../arguments_env'
|
5
4
|
require_relative '../arguments_file'
|
6
5
|
|
@@ -23,15 +22,21 @@ module RuboCop
|
|
23
22
|
STATUS_ERROR = 2
|
24
23
|
|
25
24
|
SERVER_OPTIONS = %w[
|
26
|
-
--server
|
25
|
+
--server
|
26
|
+
--no-server
|
27
|
+
--server-status
|
28
|
+
--restart-server
|
29
|
+
--start-server
|
30
|
+
--stop-server
|
31
|
+
--no-detach
|
27
32
|
].freeze
|
28
33
|
EXCLUSIVE_OPTIONS = (SERVER_OPTIONS - %w[--server --no-server]).freeze
|
34
|
+
NO_DETACH_OPTIONS = %w[--server --start-server --restart-server].freeze
|
29
35
|
|
30
36
|
def initialize
|
31
37
|
@exit = false
|
32
38
|
end
|
33
39
|
|
34
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
35
40
|
def run(argv = ARGV)
|
36
41
|
unless Server.support_server?
|
37
42
|
return error('RuboCop server is not supported by this Ruby.') if use_server_option?(argv)
|
@@ -40,16 +45,34 @@ module RuboCop
|
|
40
45
|
end
|
41
46
|
|
42
47
|
Cache.cache_root_path = fetch_cache_root_path_from(argv)
|
43
|
-
deleted_server_arguments = delete_server_argument_from(argv)
|
44
48
|
|
45
|
-
|
46
|
-
|
49
|
+
process_arguments(argv)
|
50
|
+
end
|
51
|
+
|
52
|
+
def exit?
|
53
|
+
@exit
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
59
|
+
def process_arguments(argv)
|
60
|
+
server_arguments = delete_server_argument_from(argv)
|
61
|
+
|
62
|
+
detach = !server_arguments.delete('--no-detach')
|
63
|
+
|
64
|
+
if server_arguments.size >= 2
|
65
|
+
return error("#{server_arguments.join(', ')} cannot be specified together.")
|
47
66
|
end
|
48
67
|
|
49
|
-
server_command =
|
68
|
+
server_command = server_arguments.first
|
69
|
+
|
70
|
+
unless detach || NO_DETACH_OPTIONS.include?(server_command)
|
71
|
+
return error("#{server_command} cannot be combined with --no-detach.")
|
72
|
+
end
|
50
73
|
|
51
74
|
if EXCLUSIVE_OPTIONS.include?(server_command) && argv.count > allowed_option_count
|
52
|
-
return error("#{server_command} cannot be combined with
|
75
|
+
return error("#{server_command} cannot be combined with #{argv[0]}.")
|
53
76
|
end
|
54
77
|
|
55
78
|
if server_command.nil?
|
@@ -57,23 +80,17 @@ module RuboCop
|
|
57
80
|
ArgumentsFile.read_as_arguments.delete('--server')
|
58
81
|
end
|
59
82
|
|
60
|
-
run_command(server_command)
|
83
|
+
run_command(server_command, detach: detach)
|
61
84
|
|
62
85
|
STATUS_SUCCESS
|
63
86
|
end
|
64
87
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
65
88
|
|
66
|
-
def exit?
|
67
|
-
@exit
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
89
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength:
|
73
|
-
def run_command(server_command)
|
90
|
+
def run_command(server_command, detach:)
|
74
91
|
case server_command
|
75
92
|
when '--server'
|
76
|
-
Server::ClientCommand::Start.new.run unless Server.running?
|
93
|
+
Server::ClientCommand::Start.new(detach: detach).run unless Server.running?
|
77
94
|
when '--no-server'
|
78
95
|
Server::ClientCommand::Stop.new.run if Server.running?
|
79
96
|
when '--restart-server'
|
@@ -81,7 +98,7 @@ module RuboCop
|
|
81
98
|
Server::ClientCommand::Restart.new.run
|
82
99
|
when '--start-server'
|
83
100
|
@exit = true
|
84
|
-
Server::ClientCommand::Start.new.run
|
101
|
+
Server::ClientCommand::Start.new(detach: detach).run
|
85
102
|
when '--stop-server'
|
86
103
|
@exit = true
|
87
104
|
Server::ClientCommand::Stop.new.run
|
@@ -118,6 +135,8 @@ module RuboCop
|
|
118
135
|
end
|
119
136
|
|
120
137
|
def error(message)
|
138
|
+
require 'rainbow'
|
139
|
+
|
121
140
|
@exit = true
|
122
141
|
warn Rainbow(message).red
|
123
142
|
|
@@ -15,6 +15,11 @@ module RuboCop
|
|
15
15
|
# This class is a client command to start server process.
|
16
16
|
# @api private
|
17
17
|
class Start < Base
|
18
|
+
def initialize(detach: true)
|
19
|
+
@detach = detach
|
20
|
+
super()
|
21
|
+
end
|
22
|
+
|
18
23
|
def run
|
19
24
|
if Server.running?
|
20
25
|
warn "RuboCop server (#{Cache.pid_path.read}) is already running."
|
@@ -34,7 +39,7 @@ module RuboCop
|
|
34
39
|
host = ENV.fetch('RUBOCOP_SERVER_HOST', '127.0.0.1')
|
35
40
|
port = ENV.fetch('RUBOCOP_SERVER_PORT', 0)
|
36
41
|
|
37
|
-
Server::Core.new.start(host, port)
|
42
|
+
Server::Core.new.start(host, port, detach: @detach)
|
38
43
|
end
|
39
44
|
end
|
40
45
|
end
|
data/lib/rubocop/server/core.rb
CHANGED
@@ -27,31 +27,46 @@ module RuboCop
|
|
27
27
|
self.class.token
|
28
28
|
end
|
29
29
|
|
30
|
-
def start(host, port)
|
30
|
+
def start(host, port, detach: true)
|
31
31
|
$PROGRAM_NAME = "rubocop --server #{Cache.project_dir}"
|
32
32
|
|
33
|
-
|
33
|
+
require_relative '../../rubocop'
|
34
34
|
start_server(host, port)
|
35
35
|
|
36
|
-
|
36
|
+
return unless server_mode?
|
37
|
+
|
38
|
+
detach ? detach_server : run_server
|
37
39
|
end
|
38
40
|
|
39
41
|
private
|
40
42
|
|
41
|
-
def
|
42
|
-
|
43
|
+
def detach_server
|
44
|
+
write_port_and_token_files
|
43
45
|
|
44
46
|
pid = fork do
|
45
47
|
Process.daemon(true)
|
46
48
|
$stderr.reopen(Cache.stderr_path, 'w')
|
47
|
-
|
48
|
-
read_socket(@server.accept) until @server.closed?
|
49
|
-
end
|
49
|
+
process_input
|
50
50
|
end
|
51
51
|
|
52
52
|
Process.waitpid(pid)
|
53
53
|
end
|
54
54
|
|
55
|
+
def write_port_and_token_files
|
56
|
+
Cache.write_port_and_token_files(port: @server.addr[1], token: token)
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_input
|
60
|
+
Cache.write_pid_file do
|
61
|
+
read_socket(@server.accept) until @server.closed?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def run_server
|
66
|
+
write_port_and_token_files
|
67
|
+
process_input
|
68
|
+
end
|
69
|
+
|
55
70
|
def server_mode?
|
56
71
|
true
|
57
72
|
end
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -166,6 +166,7 @@ require_relative 'rubocop/cop/bundler/ordered_gems'
|
|
166
166
|
|
167
167
|
require_relative 'rubocop/cop/gemspec/dependency_version'
|
168
168
|
require_relative 'rubocop/cop/gemspec/deprecated_attribute_assignment'
|
169
|
+
require_relative 'rubocop/cop/gemspec/development_dependencies'
|
169
170
|
require_relative 'rubocop/cop/gemspec/duplicated_assignment'
|
170
171
|
require_relative 'rubocop/cop/gemspec/ordered_dependencies'
|
171
172
|
require_relative 'rubocop/cop/gemspec/require_mfa'
|
@@ -471,6 +472,7 @@ require_relative 'rubocop/cop/style/combinable_loops'
|
|
471
472
|
require_relative 'rubocop/cop/style/command_literal'
|
472
473
|
require_relative 'rubocop/cop/style/comment_annotation'
|
473
474
|
require_relative 'rubocop/cop/style/commented_keyword'
|
475
|
+
require_relative 'rubocop/cop/style/comparable_clamp'
|
474
476
|
require_relative 'rubocop/cop/style/concat_array_literals'
|
475
477
|
require_relative 'rubocop/cop/style/conditional_assignment'
|
476
478
|
require_relative 'rubocop/cop/style/constant_visibility'
|
@@ -532,6 +534,7 @@ require_relative 'rubocop/cop/style/in_pattern_then'
|
|
532
534
|
require_relative 'rubocop/cop/style/infinite_loop'
|
533
535
|
require_relative 'rubocop/cop/style/inverse_methods'
|
534
536
|
require_relative 'rubocop/cop/style/inline_comment'
|
537
|
+
require_relative 'rubocop/cop/style/invertible_unless_condition'
|
535
538
|
require_relative 'rubocop/cop/style/ip_addresses'
|
536
539
|
require_relative 'rubocop/cop/style/keyword_parameters_order'
|
537
540
|
require_relative 'rubocop/cop/style/lambda'
|
@@ -553,6 +556,7 @@ require_relative 'rubocop/cop/style/redundant_double_splat_hash_braces'
|
|
553
556
|
require_relative 'rubocop/cop/style/redundant_each'
|
554
557
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
555
558
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
559
|
+
require_relative 'rubocop/cop/style/redundant_heredoc_delimiter_quotes'
|
556
560
|
require_relative 'rubocop/cop/style/redundant_initialize'
|
557
561
|
require_relative 'rubocop/cop/style/redundant_self_assignment'
|
558
562
|
require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
|