rubocop 1.91.0 → 1.92.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 +1 -1
- data/config/default.yml +3 -1
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +35 -13
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +2 -2
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/show_cops.rb +6 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +6 -4
- data/lib/rubocop/cli.rb +3 -2
- data/lib/rubocop/comment_config.rb +17 -8
- data/lib/rubocop/config_loader.rb +6 -3
- data/lib/rubocop/config_loader_resolver.rb +37 -12
- data/lib/rubocop/config_obsoletion/removed_cop.rb +1 -1
- data/lib/rubocop/config_validator.rb +11 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/base.rb +42 -21
- data/lib/rubocop/cop/bundler/gem_comment.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +0 -8
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +23 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +0 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -5
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/layout/block_alignment.rb +27 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/class_structure.rb +9 -1
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +16 -10
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -3
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -0
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +52 -18
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +12 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +8 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +7 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +14 -0
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +22 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +6 -11
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +15 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +63 -19
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +71 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +18 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +14 -7
- data/lib/rubocop/cop/lint/void.rb +8 -1
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/mixin/alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +17 -14
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -1
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +26 -2
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +17 -2
- data/lib/rubocop/cop/mixin/project_index_help.rb +15 -0
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +13 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +22 -2
- data/lib/rubocop/cop/mixin.rb +2 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_prefix.rb +7 -22
- data/lib/rubocop/cop/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -0
- data/lib/rubocop/cop/style/alias.rb +18 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +4 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +4 -1
- data/lib/rubocop/cop/style/attr.rb +3 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +6 -4
- data/lib/rubocop/cop/style/block_delimiters.rb +29 -3
- data/lib/rubocop/cop/style/case_like_if.rb +6 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +54 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +8 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +85 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +46 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +65 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +67 -6
- data/lib/rubocop/cop/style/exact_regexp_match.rb +45 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/float_division.rb +22 -2
- data/lib/rubocop/cop/style/for.rb +40 -2
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +9 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +32 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +16 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +21 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +19 -20
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +47 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +32 -3
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +18 -0
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +45 -10
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -3
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -5
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +28 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +2 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +9 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +27 -8
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +16 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
- data/lib/rubocop/cop/style/not.rb +10 -5
- data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +13 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +20 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +30 -13
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -0
- data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +10 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +20 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +9 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -9
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/sample.rb +9 -8
- data/lib/rubocop/cop/style/self_assignment.rb +12 -15
- data/lib/rubocop/cop/style/semicolon.rb +16 -5
- data/lib/rubocop/cop/style/single_line_methods.rb +16 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +9 -3
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +23 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -19
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -9
- data/lib/rubocop/cop/style/yoda_expression.rb +10 -1
- data/lib/rubocop/cop/team.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/formatter_set.rb +4 -0
- data/lib/rubocop/formatter/json_formatter.rb +71 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +3 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +12 -7
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/lsp/runtime.rb +47 -11
- data/lib/rubocop/lsp/stdin_runner.rb +11 -5
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +184 -76
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +45 -10
- data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
- data/lib/rubocop/remote_config.rb +4 -1
- data/lib/rubocop/result_cache.rb +20 -13
- data/lib/rubocop/runner.rb +109 -41
- data/lib/rubocop/server/cache.rb +2 -2
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +16 -5
data/lib/rubocop/runner.rb
CHANGED
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
|
53
53
|
Lint/RedundantCopDisableDirective RedundantCopDisableDirective Lint
|
|
54
54
|
].freeze
|
|
55
55
|
|
|
56
|
-
attr_reader :errors, :warnings
|
|
56
|
+
attr_reader :errors, :warnings
|
|
57
57
|
attr_writer :aborting
|
|
58
58
|
|
|
59
59
|
def initialize(options, config_store)
|
|
@@ -63,10 +63,20 @@ module RuboCop
|
|
|
63
63
|
@warnings = []
|
|
64
64
|
@aborting = false
|
|
65
65
|
@inspected_files = []
|
|
66
|
-
@
|
|
66
|
+
@diff_sources = {}
|
|
67
67
|
@report_queue = {}
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# The `--diff` patches, one per file, from the source on disk (or stdin) to
|
|
71
|
+
# the source once every correction, redundant directive removal included,
|
|
72
|
+
# has been applied.
|
|
73
|
+
def diffs
|
|
74
|
+
@diffs ||= @diff_sources.filter_map do |file, (original_source, corrected_source)|
|
|
75
|
+
diff = UnifiedDiff.new(PathUtil.smart_path(file), original_source, corrected_source).to_s
|
|
76
|
+
diff unless diff.empty?
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
70
80
|
def run(paths)
|
|
71
81
|
@inspection_team_by_config = {}.compare_by_identity
|
|
72
82
|
|
|
@@ -101,9 +111,7 @@ module RuboCop
|
|
|
101
111
|
def only_changed(target_files)
|
|
102
112
|
return target_files unless @options[:changed]
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
target_files.select { |file| changed.include?(file) }.freeze
|
|
114
|
+
ChangedFiles.new(@options[:changed]).filter(target_files).freeze
|
|
107
115
|
end
|
|
108
116
|
|
|
109
117
|
def find_target_files(paths)
|
|
@@ -158,11 +166,12 @@ module RuboCop
|
|
|
158
166
|
|
|
159
167
|
def inspect_files(files) # rubocop:disable Metrics/AbcSize
|
|
160
168
|
formatter_set.started(files)
|
|
169
|
+
formatters_started = true
|
|
161
170
|
file_iterator(files) do |file|
|
|
162
|
-
offenses = process_file(file)
|
|
171
|
+
offenses, problems = collect_problems { process_file(file) }
|
|
163
172
|
succeeded = offenses.none? { |o| considered_failure?(o) && offense_displayed?(o) }
|
|
164
173
|
|
|
165
|
-
[offenses, succeeded]
|
|
174
|
+
[offenses, succeeded, problems]
|
|
166
175
|
end
|
|
167
176
|
ensure
|
|
168
177
|
# OPTIMIZE: Calling `ResultCache.cleanup` takes time. This optimization
|
|
@@ -171,17 +180,18 @@ module RuboCop
|
|
|
171
180
|
if files.size > 1 && cached_run?
|
|
172
181
|
ResultCache.cleanup(@config_store, @options[:debug], @options[:cache_root])
|
|
173
182
|
end
|
|
174
|
-
formatter_set.finished(@inspected_files.freeze)
|
|
183
|
+
formatter_set.finished(@inspected_files.freeze) if formatters_started
|
|
175
184
|
formatter_set.close_output_files
|
|
185
|
+
warn_about_elided_offenses
|
|
176
186
|
end
|
|
177
187
|
|
|
178
188
|
def file_iterator(files, &block)
|
|
179
189
|
all_passed = true
|
|
180
190
|
|
|
181
191
|
on_start = ->(file, _index) { file_started(file) }
|
|
182
|
-
on_finish = lambda do |file, index, (offenses, passed)|
|
|
192
|
+
on_finish = lambda do |file, index, (offenses, passed, problems)|
|
|
183
193
|
all_passed &&= passed
|
|
184
|
-
finished_report(file, index, offenses)
|
|
194
|
+
finished_report(file, index, offenses, problems)
|
|
185
195
|
end
|
|
186
196
|
|
|
187
197
|
if run_in_parallel?(files)
|
|
@@ -195,8 +205,8 @@ module RuboCop
|
|
|
195
205
|
all_passed
|
|
196
206
|
end
|
|
197
207
|
|
|
198
|
-
def finished_report(file, index, offenses)
|
|
199
|
-
@report_queue[index] = [file, offenses]
|
|
208
|
+
def finished_report(file, index, offenses, problems)
|
|
209
|
+
@report_queue[index] = [file, offenses, problems]
|
|
200
210
|
@next_index_to_report ||= 0
|
|
201
211
|
while @report_queue.key?(@next_index_to_report)
|
|
202
212
|
process_report_queue_entry(@next_index_to_report)
|
|
@@ -205,7 +215,10 @@ module RuboCop
|
|
|
205
215
|
end
|
|
206
216
|
|
|
207
217
|
def process_report_queue_entry(index)
|
|
208
|
-
file, offenses = @report_queue.delete(index)
|
|
218
|
+
file, offenses, (errors, warnings) = @report_queue.delete(index)
|
|
219
|
+
@errors.concat(errors)
|
|
220
|
+
@warnings.concat(warnings)
|
|
221
|
+
file_problems(file, errors, warnings) unless errors.empty? && warnings.empty?
|
|
209
222
|
file_finished(file, offenses)
|
|
210
223
|
end
|
|
211
224
|
|
|
@@ -269,6 +282,21 @@ module RuboCop
|
|
|
269
282
|
paths.each { |path| puts PathUtil.relative_path(path) }
|
|
270
283
|
end
|
|
271
284
|
|
|
285
|
+
# Keeps the errors and warnings a file causes apart from the rest of the
|
|
286
|
+
# run's. A parallel worker inspects files in a copy of the runner that is
|
|
287
|
+
# thrown away, so they have to travel back with the file's offenses.
|
|
288
|
+
def collect_problems
|
|
289
|
+
errors = @errors
|
|
290
|
+
warnings = @warnings
|
|
291
|
+
@errors = []
|
|
292
|
+
@warnings = []
|
|
293
|
+
|
|
294
|
+
[yield, [@errors, @warnings]]
|
|
295
|
+
ensure
|
|
296
|
+
@errors = errors
|
|
297
|
+
@warnings = warnings
|
|
298
|
+
end
|
|
299
|
+
|
|
272
300
|
def process_file(file)
|
|
273
301
|
file_offenses(file)
|
|
274
302
|
rescue InfiniteCorrectionLoop => e
|
|
@@ -321,9 +349,11 @@ module RuboCop
|
|
|
321
349
|
if redundant_updated
|
|
322
350
|
# Do one extra inspection loop if any redundant disables were
|
|
323
351
|
# removed. This is done in order to find rubocop:enable directives that
|
|
324
|
-
# have now become useless.
|
|
325
|
-
|
|
326
|
-
|
|
352
|
+
# have now become useless. It finds the offenses that are left again,
|
|
353
|
+
# located in the corrected source, so only the corrected ones are kept
|
|
354
|
+
# from before, as `inspect_and_correct` does.
|
|
355
|
+
_source, new_offenses = do_inspection_loop(file, team.updated_source)
|
|
356
|
+
offenses = offenses.select(&:corrected?) | new_offenses
|
|
327
357
|
end
|
|
328
358
|
end
|
|
329
359
|
offenses
|
|
@@ -336,6 +366,8 @@ module RuboCop
|
|
|
336
366
|
team = Cop::Team.mobilize([Cop::Lint::RedundantCopDisableDirective], config, @options)
|
|
337
367
|
return if team.cops.empty?
|
|
338
368
|
|
|
369
|
+
team.defer_corrections = @options[:diff]
|
|
370
|
+
|
|
339
371
|
team.cops.first.offenses_to_check = offenses
|
|
340
372
|
yield team
|
|
341
373
|
end
|
|
@@ -369,6 +401,15 @@ module RuboCop
|
|
|
369
401
|
formatter_set.file_started(file, cli_options: @options, config_store: @config_store)
|
|
370
402
|
end
|
|
371
403
|
|
|
404
|
+
# Formatters get the messages without the colors added for the terminal.
|
|
405
|
+
def file_problems(file, errors, warnings)
|
|
406
|
+
formatter_set.file_problems(file, plain_messages(errors), plain_messages(warnings))
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
def plain_messages(problems)
|
|
410
|
+
problems.map { |problem| Rainbow::StringUtils.uncolor(problem.to_s) }
|
|
411
|
+
end
|
|
412
|
+
|
|
372
413
|
def file_finished(file, offenses)
|
|
373
414
|
@inspected_files << file
|
|
374
415
|
offenses = offenses_to_report(offenses)
|
|
@@ -387,15 +428,15 @@ module RuboCop
|
|
|
387
428
|
return unless cache
|
|
388
429
|
# Caching results when a cop has crashed would prevent the crash in the
|
|
389
430
|
# next run, since the cop would not be called then. We want crashes to
|
|
390
|
-
# show up the same in each run.
|
|
431
|
+
# show up the same in each run. Only this file's errors and warnings are
|
|
432
|
+
# visible here, see `collect_problems`.
|
|
391
433
|
return if errors.any? || warnings.any?
|
|
392
434
|
|
|
393
435
|
cache.save(offenses)
|
|
394
436
|
end
|
|
395
437
|
|
|
396
|
-
def do_inspection_loop(file)
|
|
397
|
-
|
|
398
|
-
processed_source = get_processed_source(file, @prism_result)
|
|
438
|
+
def do_inspection_loop(file, source = nil)
|
|
439
|
+
processed_source = initial_processed_source(file, source)
|
|
399
440
|
original_source = processed_source.raw_source
|
|
400
441
|
# This variable is 2d array used to track corrected offenses after each
|
|
401
442
|
# inspection iteration. This is used to output meaningful infinite loop
|
|
@@ -428,6 +469,15 @@ module RuboCop
|
|
|
428
469
|
finalize_corrections(file, original_source, corrected_source)
|
|
429
470
|
end
|
|
430
471
|
|
|
472
|
+
# `source` is the corrected source to continue from when the corrections
|
|
473
|
+
# are kept in memory rather than written to the file (`--diff`).
|
|
474
|
+
def initial_processed_source(file, source)
|
|
475
|
+
return get_processed_source(file, nil, source: source) if source
|
|
476
|
+
|
|
477
|
+
# We can reuse the prism result since the source did not change yet.
|
|
478
|
+
get_processed_source(file, @prism_result)
|
|
479
|
+
end
|
|
480
|
+
|
|
431
481
|
def inspect_and_correct(processed_source, offenses_by_iteration)
|
|
432
482
|
# The offenses that couldn't be corrected will be found again so we
|
|
433
483
|
# only keep the corrected ones in order to avoid duplicate reporting.
|
|
@@ -445,24 +495,26 @@ module RuboCop
|
|
|
445
495
|
if @options[:diff]
|
|
446
496
|
record_diff(file, original_source, corrected_source)
|
|
447
497
|
elsif corrected_source
|
|
448
|
-
|
|
498
|
+
Util.replace_file_contents(file, corrected_source)
|
|
449
499
|
end
|
|
450
500
|
end
|
|
451
501
|
|
|
452
502
|
# `--diff` reports what autocorrection would do instead of doing it. With
|
|
453
503
|
# `--stdin` the corrected source is handed back through the options rather
|
|
454
|
-
# than deferred, so that is where the new source comes from.
|
|
504
|
+
# than deferred, so that is where the new source comes from. A file can go
|
|
505
|
+
# through more than one inspection loop, so the diff runs from the source
|
|
506
|
+
# the first loop started with to the one the last loop ended with.
|
|
455
507
|
def record_diff(file, original_source, corrected_source)
|
|
456
|
-
|
|
457
|
-
return unless original_source && new_source
|
|
508
|
+
return unless original_source
|
|
458
509
|
|
|
510
|
+
new_source = @options[:stdin] || corrected_source
|
|
459
511
|
# The original source is the file as it is on disk, so the corrected one
|
|
460
512
|
# has to go through the same line ending conversion `File.write` would
|
|
461
513
|
# apply, or on Windows every single line reads as changed.
|
|
462
|
-
new_source = emulate_write_read_cycle(new_source)
|
|
514
|
+
new_source = new_source ? Util.emulate_write_read_cycle(new_source) : original_source
|
|
463
515
|
|
|
464
|
-
|
|
465
|
-
|
|
516
|
+
sources = (@diff_sources[file] ||= [original_source])
|
|
517
|
+
sources[1] = new_source
|
|
466
518
|
end
|
|
467
519
|
|
|
468
520
|
def inspect_iteration(processed_source)
|
|
@@ -472,17 +524,6 @@ module RuboCop
|
|
|
472
524
|
[team, offenses, updated_source_file]
|
|
473
525
|
end
|
|
474
526
|
|
|
475
|
-
# When corrections were written to disk and read back between iterations,
|
|
476
|
-
# the text-mode write converted LF to CRLF on Windows, and cops like
|
|
477
|
-
# `Layout/EndOfLine` rely on seeing the source as it would be on disk.
|
|
478
|
-
# Apply the same conversion to the in-memory source. The final `File.write`
|
|
479
|
-
# still performs it for the file itself.
|
|
480
|
-
def emulate_write_read_cycle(source)
|
|
481
|
-
return source unless Platform.windows?
|
|
482
|
-
|
|
483
|
-
source.encode(source.encoding, crlf_newline: true)
|
|
484
|
-
end
|
|
485
|
-
|
|
486
527
|
# Custom ruby extractors may derive their fragments from the file on
|
|
487
528
|
# disk rather than from the passed processed source, so corrections can
|
|
488
529
|
# only be kept in memory when the default extractor is used.
|
|
@@ -573,6 +614,12 @@ module RuboCop
|
|
|
573
614
|
end
|
|
574
615
|
end
|
|
575
616
|
|
|
617
|
+
# Lets a runner that is reused from run to run pick up a different `--only`
|
|
618
|
+
# or `--except`.
|
|
619
|
+
def forget_mobilized_cops
|
|
620
|
+
@mobilized_cop_classes = nil
|
|
621
|
+
end
|
|
622
|
+
|
|
576
623
|
def mobilize_cop_badge?(badge, config)
|
|
577
624
|
return false if badge.department == :Test
|
|
578
625
|
return false if badge.match_name?(@options[:except])
|
|
@@ -589,7 +636,7 @@ module RuboCop
|
|
|
589
636
|
%i[only except].each do |option|
|
|
590
637
|
next unless @options[option]
|
|
591
638
|
|
|
592
|
-
@options[option].map
|
|
639
|
+
@options[option] = @options[option].map do |cop_name|
|
|
593
640
|
Cop::Registry.qualified_cop_name(cop_name, "--#{option} option")
|
|
594
641
|
end
|
|
595
642
|
end
|
|
@@ -630,7 +677,28 @@ module RuboCop
|
|
|
630
677
|
end
|
|
631
678
|
|
|
632
679
|
def offenses_to_report(offenses)
|
|
633
|
-
offenses.select { |o| offense_displayed?(o) }
|
|
680
|
+
offenses = offenses.select { |o| offense_displayed?(o) }
|
|
681
|
+
offenses = offense_limit.filter(offenses) if offense_limit
|
|
682
|
+
offenses
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
# Files are reported in order, so which offenses survive the limit does not
|
|
686
|
+
# depend on how the run was parallelized.
|
|
687
|
+
def offense_limit
|
|
688
|
+
return @offense_limit if defined?(@offense_limit)
|
|
689
|
+
|
|
690
|
+
max = @options[:max_offenses_per_cop]
|
|
691
|
+
@offense_limit = (OffenseLimit.new(max.to_i) if max)
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
def warn_about_elided_offenses
|
|
695
|
+
elided = offense_limit&.elided_per_cop
|
|
696
|
+
return unless elided&.any?
|
|
697
|
+
|
|
698
|
+
warn Rainbow(
|
|
699
|
+
"#{elided.values.sum} more offenses were not reported because of " \
|
|
700
|
+
"--max-offenses-per-cop=#{offense_limit.max} (#{elided.keys.join(', ')})."
|
|
701
|
+
).yellow
|
|
634
702
|
end
|
|
635
703
|
|
|
636
704
|
def supports_safe_autocorrect?(offense)
|
|
@@ -662,7 +730,7 @@ module RuboCop
|
|
|
662
730
|
|
|
663
731
|
processed_source = if source
|
|
664
732
|
ProcessedSource.new(
|
|
665
|
-
emulate_write_read_cycle(source),
|
|
733
|
+
Util.emulate_write_read_cycle(source),
|
|
666
734
|
ruby_version,
|
|
667
735
|
file,
|
|
668
736
|
parser_engine: parser_engine
|
data/lib/rubocop/server/cache.rb
CHANGED
|
@@ -112,8 +112,8 @@ module RuboCop
|
|
|
112
112
|
|
|
113
113
|
def pid_running?
|
|
114
114
|
Process.kill(0, pid_path(create_dir: false).read.to_i) == 1
|
|
115
|
-
rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::
|
|
116
|
-
Errno::ENOTDIR
|
|
115
|
+
rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EPERM, Errno::EROFS,
|
|
116
|
+
Errno::ENAMETOOLONG, Errno::ENOTDIR
|
|
117
117
|
false
|
|
118
118
|
end
|
|
119
119
|
|
data/lib/rubocop/util.rb
CHANGED
|
@@ -12,5 +12,74 @@ module RuboCop
|
|
|
12
12
|
ensure
|
|
13
13
|
$VERBOSE = old_verbose
|
|
14
14
|
end
|
|
15
|
+
|
|
16
|
+
# The source as it reads back after `File.write`, which in text mode turns
|
|
17
|
+
# each LF into CRLF on Windows. Cops like `Layout/EndOfLine` have to see
|
|
18
|
+
# corrected code that way between correction passes, and so does anything
|
|
19
|
+
# that compares it with what a write leaves on disk. The final `File.write`
|
|
20
|
+
# still performs the conversion for the file itself.
|
|
21
|
+
def self.emulate_write_read_cycle(source)
|
|
22
|
+
return source unless Platform.windows?
|
|
23
|
+
|
|
24
|
+
source.encode(source.encoding, crlf_newline: true)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Replaces the contents of `path` without a window in which the file is truncated
|
|
28
|
+
# but not yet rewritten, so that an interrupted run or a full disk cannot lose
|
|
29
|
+
# the original: the new contents are written next to the file and renamed over it,
|
|
30
|
+
# like `ResultCache#save`. `File.write` is used for the temporary file so text-mode
|
|
31
|
+
# semantics (the CRLF conversion on Windows) stay identical to a direct write.
|
|
32
|
+
# Where the temporary file cannot be created or renamed for lack of permission,
|
|
33
|
+
# a direct write is used as before.
|
|
34
|
+
def self.replace_file_contents(path, contents)
|
|
35
|
+
# Write through symlinks so that the rename replaces the real file and
|
|
36
|
+
# the symlink survives.
|
|
37
|
+
path = File.realpath(path)
|
|
38
|
+
|
|
39
|
+
# Opening a read-only file fails without truncating it, keeping the behavior
|
|
40
|
+
# a direct write always had.
|
|
41
|
+
return File.write(path, contents) unless File.writable?(path)
|
|
42
|
+
|
|
43
|
+
temp_path = "#{path}.#{Process.pid}.#{rand(1_000_000_000)}.rubocop.tmp"
|
|
44
|
+
begin
|
|
45
|
+
replace_via_temporary_file(path, temp_path, contents)
|
|
46
|
+
ensure
|
|
47
|
+
FileUtils.rm_f(temp_path)
|
|
48
|
+
end
|
|
49
|
+
rescue Errno::ENOENT
|
|
50
|
+
# The file vanished mid-run or is a dangling symlink: recreate it the way
|
|
51
|
+
# a direct write always has.
|
|
52
|
+
File.write(path, contents)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.replace_via_temporary_file(path, temp_path, contents)
|
|
56
|
+
# The directory refuses new files even though the file itself is writable,
|
|
57
|
+
# so a direct write is the only option left.
|
|
58
|
+
return File.write(path, contents) unless write_temporary_file(temp_path, contents)
|
|
59
|
+
|
|
60
|
+
begin
|
|
61
|
+
# A fresh file would get umask-default permissions on rename;
|
|
62
|
+
# keep the original's.
|
|
63
|
+
File.chmod(File.stat(path).mode, temp_path)
|
|
64
|
+
File.rename(temp_path, path)
|
|
65
|
+
rescue SystemCallError
|
|
66
|
+
# The replacement was refused, e.g. the file is open in another process on Windows.
|
|
67
|
+
# The contents already fit on disk, so a direct write is safe once the temporary copy
|
|
68
|
+
# no longer takes up that space.
|
|
69
|
+
FileUtils.rm_f(temp_path)
|
|
70
|
+
File.write(path, contents)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
private_class_method :replace_via_temporary_file
|
|
74
|
+
|
|
75
|
+
# Space errors such as `ENOSPC` must propagate: a direct write would then
|
|
76
|
+
# truncate the file and fail, which is exactly the loss being avoided.
|
|
77
|
+
def self.write_temporary_file(temp_path, contents)
|
|
78
|
+
File.write(temp_path, contents)
|
|
79
|
+
true
|
|
80
|
+
rescue Errno::EACCES, Errno::EPERM
|
|
81
|
+
false
|
|
82
|
+
end
|
|
83
|
+
private_class_method :write_temporary_file
|
|
15
84
|
end
|
|
16
85
|
end
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
|
@@ -55,6 +55,8 @@ require_relative 'rubocop/cop/base'
|
|
|
55
55
|
require_relative 'rubocop/cop/cop'
|
|
56
56
|
require_relative 'rubocop/cop/commissioner'
|
|
57
57
|
require_relative 'rubocop/cop/documentation'
|
|
58
|
+
require_relative 'rubocop/cop/cop_documentation'
|
|
59
|
+
require_relative 'rubocop/cop/cop_explanation'
|
|
58
60
|
require_relative 'rubocop/cop/corrector'
|
|
59
61
|
require_relative 'rubocop/cop/correctors'
|
|
60
62
|
require_relative 'rubocop/cop/force'
|
|
@@ -117,12 +119,15 @@ require_relative 'rubocop/comment_config/disable_next'
|
|
|
117
119
|
require_relative 'rubocop/comment_config/push_pop'
|
|
118
120
|
require_relative 'rubocop/comment_config'
|
|
119
121
|
require_relative 'rubocop/result_cache'
|
|
122
|
+
require_relative 'rubocop/offense_limit'
|
|
120
123
|
require_relative 'rubocop/runner'
|
|
121
124
|
require_relative 'rubocop/cli'
|
|
122
125
|
require_relative 'rubocop/cli/command'
|
|
123
126
|
require_relative 'rubocop/cli/environment'
|
|
124
127
|
require_relative 'rubocop/cli/command/base'
|
|
125
128
|
require_relative 'rubocop/cli/command/auto_generate_config'
|
|
129
|
+
require_relative 'rubocop/cli/command/cop_names'
|
|
130
|
+
require_relative 'rubocop/cli/command/explain'
|
|
126
131
|
require_relative 'rubocop/cli/command/execute_runner'
|
|
127
132
|
require_relative 'rubocop/cli/command/init_dotfile'
|
|
128
133
|
require_relative 'rubocop/cli/command/lsp'
|
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.92.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bozhidar Batsov
|
|
@@ -107,7 +107,7 @@ dependencies:
|
|
|
107
107
|
requirements:
|
|
108
108
|
- - ">="
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 2.
|
|
110
|
+
version: 2.11.3
|
|
111
111
|
- - "<"
|
|
112
112
|
- !ruby/object:Gem::Version
|
|
113
113
|
version: '3.0'
|
|
@@ -117,7 +117,7 @@ dependencies:
|
|
|
117
117
|
requirements:
|
|
118
118
|
- - ">="
|
|
119
119
|
- !ruby/object:Gem::Version
|
|
120
|
-
version: 2.
|
|
120
|
+
version: 2.11.3
|
|
121
121
|
- - "<"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: '3.0'
|
|
@@ -206,7 +206,9 @@ files:
|
|
|
206
206
|
- lib/rubocop/cli/command.rb
|
|
207
207
|
- lib/rubocop/cli/command/auto_generate_config.rb
|
|
208
208
|
- lib/rubocop/cli/command/base.rb
|
|
209
|
+
- lib/rubocop/cli/command/cop_names.rb
|
|
209
210
|
- lib/rubocop/cli/command/execute_runner.rb
|
|
211
|
+
- lib/rubocop/cli/command/explain.rb
|
|
210
212
|
- lib/rubocop/cli/command/init_dotfile.rb
|
|
211
213
|
- lib/rubocop/cli/command/list_enabled_cops_for.rb
|
|
212
214
|
- lib/rubocop/cli/command/lsp.rb
|
|
@@ -250,6 +252,8 @@ files:
|
|
|
250
252
|
- lib/rubocop/cop/bundler/ordered_gems.rb
|
|
251
253
|
- lib/rubocop/cop/commissioner.rb
|
|
252
254
|
- lib/rubocop/cop/cop.rb
|
|
255
|
+
- lib/rubocop/cop/cop_documentation.rb
|
|
256
|
+
- lib/rubocop/cop/cop_explanation.rb
|
|
253
257
|
- lib/rubocop/cop/corrector.rb
|
|
254
258
|
- lib/rubocop/cop/correctors.rb
|
|
255
259
|
- lib/rubocop/cop/correctors/alignment_corrector.rb
|
|
@@ -643,6 +647,7 @@ files:
|
|
|
643
647
|
- lib/rubocop/cop/mixin/empty_lines_around_body.rb
|
|
644
648
|
- lib/rubocop/cop/mixin/empty_parameter.rb
|
|
645
649
|
- lib/rubocop/cop/mixin/end_keyword_alignment.rb
|
|
650
|
+
- lib/rubocop/cop/mixin/endless_method_body_help.rb
|
|
646
651
|
- lib/rubocop/cop/mixin/endless_method_rewriter.rb
|
|
647
652
|
- lib/rubocop/cop/mixin/enforce_superclass.rb
|
|
648
653
|
- lib/rubocop/cop/mixin/first_element_line_break.rb
|
|
@@ -675,6 +680,7 @@ files:
|
|
|
675
680
|
- lib/rubocop/cop/mixin/on_normal_if_unless.rb
|
|
676
681
|
- lib/rubocop/cop/mixin/ordered_gem_node.rb
|
|
677
682
|
- lib/rubocop/cop/mixin/parentheses.rb
|
|
683
|
+
- lib/rubocop/cop/mixin/pattern_matching_help.rb
|
|
678
684
|
- lib/rubocop/cop/mixin/percent_array.rb
|
|
679
685
|
- lib/rubocop/cop/mixin/percent_literal.rb
|
|
680
686
|
- lib/rubocop/cop/mixin/preceding_following_alignment.rb
|
|
@@ -1091,8 +1097,13 @@ files:
|
|
|
1091
1097
|
- lib/rubocop/lsp/severity.rb
|
|
1092
1098
|
- lib/rubocop/lsp/stdin_runner.rb
|
|
1093
1099
|
- lib/rubocop/magic_comment.rb
|
|
1100
|
+
- lib/rubocop/mcp/autocorrection_request.rb
|
|
1101
|
+
- lib/rubocop/mcp/explain_tool.rb
|
|
1102
|
+
- lib/rubocop/mcp/scope.rb
|
|
1094
1103
|
- lib/rubocop/mcp/server.rb
|
|
1104
|
+
- lib/rubocop/mcp/source_files.rb
|
|
1095
1105
|
- lib/rubocop/name_similarity.rb
|
|
1106
|
+
- lib/rubocop/offense_limit.rb
|
|
1096
1107
|
- lib/rubocop/options.rb
|
|
1097
1108
|
- lib/rubocop/path_util.rb
|
|
1098
1109
|
- lib/rubocop/pending_cops_reporter.rb
|
|
@@ -1146,9 +1157,9 @@ licenses:
|
|
|
1146
1157
|
- MIT
|
|
1147
1158
|
metadata:
|
|
1148
1159
|
homepage_uri: https://rubocop.org/
|
|
1149
|
-
changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.
|
|
1160
|
+
changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.92.0
|
|
1150
1161
|
source_code_uri: https://github.com/rubocop/rubocop/
|
|
1151
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
|
1162
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.92/
|
|
1152
1163
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
|
1153
1164
|
rubygems_mfa_required: 'true'
|
|
1154
1165
|
rdoc_options: []
|