rubocop 1.89.0 → 1.91.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/config/default.yml +309 -14
- data/config/obsoletion.yml +9 -0
- data/exe/rubocop +1 -1
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/changed_files.rb +112 -0
- data/lib/rubocop/cli/command/execute_runner.rb +52 -1
- data/lib/rubocop/cli.rb +11 -7
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +50 -64
- data/lib/rubocop/config.rb +33 -5
- data/lib/rubocop/config_loader.rb +13 -6
- data/lib/rubocop/config_loader_resolver.rb +50 -9
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/removed_cop.rb +8 -0
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +19 -5
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -0
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +49 -5
- data/lib/rubocop/cop/corrector.rb +3 -3
- data/lib/rubocop/cop/correctors.rb +2 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/class_structure.rb +102 -26
- data/lib/rubocop/cop/layout/comment_indentation.rb +8 -5
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +21 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -4
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -5
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/line_length.rb +20 -3
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +14 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +12 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +17 -11
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +165 -15
- data/lib/rubocop/cop/lint/deprecated_reference.rb +11 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +113 -15
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +1 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -8
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -6
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +185 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +25 -12
- data/lib/rubocop/cop/lint/name_typo.rb +53 -6
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +17 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +122 -29
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +47 -7
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -4
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -2
- data/lib/rubocop/cop/lint/unused_private_method.rb +94 -17
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +36 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +61 -7
- data/lib/rubocop/cop/lint/void.rb +1 -2
- data/lib/rubocop/cop/lint.rb +3 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/migration/department_name.rb +1 -2
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +11 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +7 -4
- data/lib/rubocop/cop/mixin/hash_subset.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +7 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +62 -6
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/statement_modifier.rb +13 -7
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
- data/lib/rubocop/cop/mixin.rb +6 -2
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +16 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -4
- data/lib/rubocop/cop/naming/method_name.rb +5 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -2
- data/lib/rubocop/cop/offense.rb +27 -4
- data/lib/rubocop/cop/registry.rb +43 -11
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +5 -8
- data/lib/rubocop/cop/style/array_first_last.rb +1 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -6
- data/lib/rubocop/cop/style/case_like_if.rb +5 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -2
- data/lib/rubocop/cop/style/constant_visibility.rb +6 -3
- data/lib/rubocop/cop/style/copyright.rb +1 -2
- data/lib/rubocop/cop/style/data_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +83 -13
- data/lib/rubocop/cop/style/documentation_method.rb +1 -9
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +12 -2
- data/lib/rubocop/cop/style/endless_method.rb +31 -12
- data/lib/rubocop/cop/style/file_null.rb +2 -2
- data/lib/rubocop/cop/style/float_division.rb +10 -16
- data/lib/rubocop/cop/style/for.rb +5 -0
- data/lib/rubocop/cop/style/format_string_token.rb +1 -2
- data/lib/rubocop/cop/style/guard_clause.rb +5 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_lookup_method.rb +3 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -4
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -2
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +2 -4
- data/lib/rubocop/cop/style/nested_modifier.rb +9 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +36 -9
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +18 -2
- data/lib/rubocop/cop/style/not.rb +3 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +1 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +6 -8
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +11 -3
- data/lib/rubocop/cop/style/redundant_each.rb +1 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +2 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -5
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +6 -6
- data/lib/rubocop/cop/style/redundant_return.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -2
- data/lib/rubocop/cop/style/sample.rb +11 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -2
- data/lib/rubocop/cop/style/semicolon.rb +2 -4
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +1 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +18 -5
- data/lib/rubocop/cop/style/struct_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -2
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -2
- data/lib/rubocop/cop/style.rb +2 -1
- data/lib/rubocop/cop/team.rb +11 -3
- data/lib/rubocop/cop/util.rb +3 -5
- data/lib/rubocop/cop/variable_force/variable.rb +1 -2
- data/lib/rubocop/cops_documentation_generator.rb +26 -8
- data/lib/rubocop/directive_comment.rb +73 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -1
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +2 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +26 -9
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -2
- data/lib/rubocop/formatter/sarif_formatter.rb +181 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -3
- data/lib/rubocop/formatter/tap_formatter.rb +3 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
- data/lib/rubocop/formatter.rb +1 -0
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -8
- data/lib/rubocop/lsp/routes.rb +48 -19
- data/lib/rubocop/magic_comment.rb +27 -0
- data/lib/rubocop/mcp/server.rb +1 -2
- data/lib/rubocop/options.rb +69 -7
- data/lib/rubocop/path_util.rb +2 -3
- data/lib/rubocop/plugin/configuration_integrator.rb +6 -3
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -2
- data/lib/rubocop/remote_config.rb +4 -4
- data/lib/rubocop/result_cache.rb +16 -5
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +4 -2
- data/lib/rubocop/runner.rb +90 -44
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +4 -1
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/version.rb +3 -5
- data/lib/rubocop.rb +7 -1
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +18 -6
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
data/lib/rubocop/options.rb
CHANGED
|
@@ -33,6 +33,8 @@ module RuboCop
|
|
|
33
33
|
|
|
34
34
|
define_options.parse!(args)
|
|
35
35
|
|
|
36
|
+
imply_autocorrect_for_diff
|
|
37
|
+
|
|
36
38
|
@validator.validate_compatibility
|
|
37
39
|
|
|
38
40
|
if @options[:stdin]
|
|
@@ -51,7 +53,16 @@ module RuboCop
|
|
|
51
53
|
|
|
52
54
|
private
|
|
53
55
|
|
|
54
|
-
#
|
|
56
|
+
# `--diff` is a dry run of autocorrection, so it turns autocorrection on
|
|
57
|
+
# unless the user already picked a mode with `-a`, `-A` or `-x`.
|
|
58
|
+
def imply_autocorrect_for_diff
|
|
59
|
+
return unless @options[:diff] && !@options[:autocorrect]
|
|
60
|
+
|
|
61
|
+
@options[:safe_autocorrect] = true
|
|
62
|
+
@options[:autocorrect] = true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
55
66
|
def define_options
|
|
56
67
|
OptionParser.new do |opts|
|
|
57
68
|
opts.banner = rainbow.wrap('Usage: rubocop [options] [file1, file2, ...]').bright
|
|
@@ -71,7 +82,6 @@ module RuboCop
|
|
|
71
82
|
add_profile_options(opts) if RUBY_ENGINE == 'ruby' && !Platform.windows?
|
|
72
83
|
end
|
|
73
84
|
end
|
|
74
|
-
# rubocop:enable Metrics/AbcSize
|
|
75
85
|
|
|
76
86
|
def add_check_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
77
87
|
section(opts, 'Basic Options') do # rubocop:disable Metrics/BlockLength
|
|
@@ -93,12 +103,17 @@ module RuboCop
|
|
|
93
103
|
option(opts, '--enable-pending-cops')
|
|
94
104
|
option(opts, '--disable-all-cops')
|
|
95
105
|
option(opts, '--enable-all-cops')
|
|
106
|
+
option(opts, '--[no-]preview')
|
|
96
107
|
option(opts, '--ignore-disable-comments')
|
|
97
108
|
option(opts, '--force-exclusion')
|
|
98
109
|
option(opts, '--only-recognized-file-types')
|
|
99
110
|
option(opts, '--ignore-parent-exclusion')
|
|
100
111
|
option(opts, '--ignore-unrecognized-cops')
|
|
101
112
|
option(opts, '--force-default-config')
|
|
113
|
+
option(opts, '--changed [REVISION]') do |revision|
|
|
114
|
+
@options[:changed] = revision || ChangedFiles::DEFAULT_REVISION
|
|
115
|
+
@validator.validate_changed_revision(revision)
|
|
116
|
+
end
|
|
102
117
|
option(opts, '-s', '--stdin FILE')
|
|
103
118
|
option(opts, '--editor-mode')
|
|
104
119
|
option(opts, '-P', '--[no-]parallel')
|
|
@@ -132,10 +147,11 @@ module RuboCop
|
|
|
132
147
|
option(opts, '--display-only-fail-level-offenses')
|
|
133
148
|
option(opts, '--display-only-correctable')
|
|
134
149
|
option(opts, '--display-only-safe-correctable')
|
|
150
|
+
option(opts, '--display-suppressed')
|
|
135
151
|
end
|
|
136
152
|
end
|
|
137
153
|
|
|
138
|
-
# rubocop:todo Naming/InclusiveLanguage
|
|
154
|
+
# rubocop:todo Naming/InclusiveLanguage -- `--auto-correct` is the deprecated flag name
|
|
139
155
|
# the autocorrect command-line arguments map to the autocorrect @options values like so:
|
|
140
156
|
# :fix_layout :autocorrect :safe_autocorrect :autocorrect_all
|
|
141
157
|
# -x, --fix-layout true true - -
|
|
@@ -161,6 +177,8 @@ module RuboCop
|
|
|
161
177
|
end
|
|
162
178
|
|
|
163
179
|
option(opts, '--disable-uncorrectable')
|
|
180
|
+
|
|
181
|
+
option(opts, '--diff')
|
|
164
182
|
end
|
|
165
183
|
end
|
|
166
184
|
# rubocop:enable Naming/InclusiveLanguage
|
|
@@ -173,6 +191,8 @@ module RuboCop
|
|
|
173
191
|
@options.replace(ConfigRegeneration.new.options.merge(@options))
|
|
174
192
|
end
|
|
175
193
|
|
|
194
|
+
option(opts, '--report-unused-todo-entries')
|
|
195
|
+
|
|
176
196
|
option(opts, '--exclude-limit COUNT') { @validator.validate_exclude_limit_option }
|
|
177
197
|
option(opts, '--no-exclude-limit')
|
|
178
198
|
|
|
@@ -382,7 +402,7 @@ module RuboCop
|
|
|
382
402
|
%i[only except].each { |opt| OptionsValidator.validate_cop_list(@options[opt]) }
|
|
383
403
|
end
|
|
384
404
|
|
|
385
|
-
# rubocop:disable Metrics/AbcSize
|
|
405
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
386
406
|
def validate_compatibility # rubocop:disable Metrics/MethodLength
|
|
387
407
|
if only_includes_redundant_disable?
|
|
388
408
|
raise OptionArgumentError, 'Lint/RedundantCopDisableDirective cannot be used with --only.'
|
|
@@ -398,6 +418,8 @@ module RuboCop
|
|
|
398
418
|
validate_display_only_failed_and_display_only_correctable
|
|
399
419
|
validate_display_only_correctable_and_autocorrect
|
|
400
420
|
validate_lsp_and_editor_mode
|
|
421
|
+
validate_diff
|
|
422
|
+
validate_changed_and_stdin
|
|
401
423
|
validate_enable_all_cops_and_disable_all_cops
|
|
402
424
|
disable_parallel_when_invalid_option_combo
|
|
403
425
|
|
|
@@ -405,7 +427,6 @@ module RuboCop
|
|
|
405
427
|
|
|
406
428
|
raise OptionArgumentError, "Incompatible cli options: #{incompatible_options.inspect}"
|
|
407
429
|
end
|
|
408
|
-
# rubocop:enable Metrics/AbcSize
|
|
409
430
|
|
|
410
431
|
def validate_auto_gen_config
|
|
411
432
|
return if @options.key?(:auto_gen_config)
|
|
@@ -446,6 +467,20 @@ module RuboCop
|
|
|
446
467
|
'--display-only-failed cannot be used together with other display options.'
|
|
447
468
|
end
|
|
448
469
|
|
|
470
|
+
# `--diff` promises not to write anything, and `--auto-gen-config` exists to
|
|
471
|
+
# write a file.
|
|
472
|
+
def validate_diff
|
|
473
|
+
return unless @options.key?(:diff) && @options.key?(:auto_gen_config)
|
|
474
|
+
|
|
475
|
+
raise OptionArgumentError, '--diff cannot be used with --auto-gen-config.'
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def validate_changed_and_stdin
|
|
479
|
+
return unless @options.key?(:changed) && @options.key?(:stdin)
|
|
480
|
+
|
|
481
|
+
raise OptionArgumentError, '--changed cannot be used with --stdin.'
|
|
482
|
+
end
|
|
483
|
+
|
|
449
484
|
def validate_lsp_and_editor_mode
|
|
450
485
|
return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
|
|
451
486
|
|
|
@@ -510,6 +545,17 @@ module RuboCop
|
|
|
510
545
|
@incompatible_options ||= @options.keys & Options::EXITING_OPTIONS
|
|
511
546
|
end
|
|
512
547
|
|
|
548
|
+
# OptionParser hands `--changed lib/` the path as the revision, which is a
|
|
549
|
+
# natural thing to type, so point at the fix rather than at git's error.
|
|
550
|
+
def validate_changed_revision(revision)
|
|
551
|
+
return unless revision && File.exist?(revision)
|
|
552
|
+
|
|
553
|
+
raise OptionArgumentError,
|
|
554
|
+
"--changed takes a git revision, but `#{revision}` is a path. Write the revision " \
|
|
555
|
+
"as `--changed=#{revision}` if that is really what you meant, or drop it to " \
|
|
556
|
+
'compare against HEAD.'
|
|
557
|
+
end
|
|
558
|
+
|
|
513
559
|
def validate_exclude_limit_option
|
|
514
560
|
return if /^\d+$/.match?(@options[:exclude_limit])
|
|
515
561
|
|
|
@@ -527,7 +573,7 @@ module RuboCop
|
|
|
527
573
|
|
|
528
574
|
# This module contains help texts for command line options.
|
|
529
575
|
# @api private
|
|
530
|
-
# rubocop:disable Metrics/ModuleLength
|
|
576
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
531
577
|
module OptionsHelp
|
|
532
578
|
MAX_EXCL = RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS.to_s
|
|
533
579
|
FORMATTER_OPTION_LIST = RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys
|
|
@@ -545,6 +591,8 @@ module RuboCop
|
|
|
545
591
|
regenerate_todo: ['Regenerate the TODO configuration file using',
|
|
546
592
|
'the last configuration. If there is no existing',
|
|
547
593
|
'TODO file, acts like --auto-gen-config.'],
|
|
594
|
+
report_unused_todo_entries: ['Also report TODO configuration file entries that',
|
|
595
|
+
'are no longer needed, and fail if any are found.'],
|
|
548
596
|
offense_counts: ['Include offense counts in configuration',
|
|
549
597
|
'file generated by --auto-gen-config.',
|
|
550
598
|
'Default is true.'],
|
|
@@ -569,6 +617,10 @@ module RuboCop
|
|
|
569
617
|
disable_uncorrectable: ['Used with --autocorrect to annotate any',
|
|
570
618
|
'offenses that do not support autocorrect',
|
|
571
619
|
'with `rubocop:todo` comments.'],
|
|
620
|
+
diff: ['Print a unified diff of what autocorrection',
|
|
621
|
+
'would change, without writing any files.',
|
|
622
|
+
'Turns on safe autocorrection unless a mode',
|
|
623
|
+
'was already given with -a, -A or -x.'],
|
|
572
624
|
no_exclude_limit: ['Do not set the limit for how many files to exclude.'],
|
|
573
625
|
force_exclusion: ['Any files excluded by `Exclude` in configuration',
|
|
574
626
|
'files will be excluded, even if given explicitly',
|
|
@@ -581,6 +633,10 @@ module RuboCop
|
|
|
581
633
|
ignore_parent_exclusion: ['Prevent from inheriting `AllCops/Exclude` from',
|
|
582
634
|
'parent folders.'],
|
|
583
635
|
ignore_unrecognized_cops: ['Ignore unrecognized cops or departments in the config.'],
|
|
636
|
+
changed: ['Inspect only the files that differ from a git',
|
|
637
|
+
'revision, defaulting to HEAD. Untracked files',
|
|
638
|
+
'count as changed. Pass a revision with',
|
|
639
|
+
'`--changed=REVISION`.'],
|
|
584
640
|
force_default_config: ['Use default configuration even if configuration',
|
|
585
641
|
'files are present in the directory tree.'],
|
|
586
642
|
format: ['Choose an output formatter. This option',
|
|
@@ -595,6 +651,7 @@ module RuboCop
|
|
|
595
651
|
'specified --format, or the default format',
|
|
596
652
|
'if no format is specified.'],
|
|
597
653
|
fail_level: ['Minimum severity for exit with error code.',
|
|
654
|
+
'Overrides `AllCops: FailLevel` in the configuration.',
|
|
598
655
|
' [A] autocorrect',
|
|
599
656
|
' [I] info',
|
|
600
657
|
' [R] refactor',
|
|
@@ -611,6 +668,8 @@ module RuboCop
|
|
|
611
668
|
display_only_correctable: ['Only output correctable offense messages.'],
|
|
612
669
|
display_only_safe_correctable: ['Only output safe-correctable offense messages',
|
|
613
670
|
'when combined with --display-only-correctable.'],
|
|
671
|
+
display_suppressed: ['Also output offenses suppressed by directive',
|
|
672
|
+
'comments. They do not affect the exit code.'],
|
|
614
673
|
show_cops: ['Show the given cops, or all cops by',
|
|
615
674
|
'default, and their configurations for the',
|
|
616
675
|
'current directory.',
|
|
@@ -637,6 +696,10 @@ module RuboCop
|
|
|
637
696
|
'`AllCops/DisabledByDefault` in config files.'],
|
|
638
697
|
display_style_guide: 'Display style guide URLs in offense messages.',
|
|
639
698
|
enable_pending_cops: 'Run with pending cops.',
|
|
699
|
+
preview: ['Opt in to unstable behavior: cops that are',
|
|
700
|
+
'`Enabled: preview`, and changes to existing',
|
|
701
|
+
'cops that are not the default yet.',
|
|
702
|
+
'Overrides `AllCops: Preview`.'],
|
|
640
703
|
enable_all_cops: ['Run with all cops enabled, including those',
|
|
641
704
|
'disabled by default. Overrides',
|
|
642
705
|
'`AllCops/EnabledByDefault` and',
|
|
@@ -689,5 +752,4 @@ module RuboCop
|
|
|
689
752
|
memory: 'Profile rubocop memory usage.'
|
|
690
753
|
}.freeze
|
|
691
754
|
end
|
|
692
|
-
# rubocop:enable Metrics/ModuleLength
|
|
693
755
|
end
|
data/lib/rubocop/path_util.rb
CHANGED
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
|
44
44
|
uri.start_with?('http://', 'https://')
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
SMART_PATH_CACHE = {} # rubocop:disable Style/MutableConstant
|
|
47
|
+
SMART_PATH_CACHE = {} # rubocop:disable Style/MutableConstant -- a cache, written to at runtime
|
|
48
48
|
private_constant :SMART_PATH_CACHE
|
|
49
49
|
|
|
50
50
|
def smart_path(path)
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
66
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
67
67
|
def match_path?(pattern, path)
|
|
68
68
|
case pattern
|
|
69
69
|
when String
|
|
@@ -89,7 +89,6 @@ module RuboCop
|
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
|
-
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
93
92
|
|
|
94
93
|
# Returns true for an absolute Unix or Windows path.
|
|
95
94
|
def absolute?(path)
|
|
@@ -59,7 +59,11 @@ module RuboCop
|
|
|
59
59
|
|
|
60
60
|
plugin_config.make_excludes_absolute
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
# `unset_nil: false` keeps `AllCops` keys declared with a nil value by a plugin
|
|
63
|
+
# (e.g. `TargetRailsVersion: ~` of rubocop-rails); `merge_all_cop_settings` above
|
|
64
|
+
# carries such keys into each subsequent plugin's config, where `unset_nil: true`
|
|
65
|
+
# would delete them from the combined configuration.
|
|
66
|
+
ConfigLoader.merge_with_default(plugin_config, plugin_config_path, unset_nil: false)
|
|
63
67
|
end
|
|
64
68
|
end
|
|
65
69
|
end
|
|
@@ -88,7 +92,7 @@ module RuboCop
|
|
|
88
92
|
result
|
|
89
93
|
end
|
|
90
94
|
|
|
91
|
-
# rubocop:disable Metrics/AbcSize
|
|
95
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
92
96
|
def load_plugin_rubocop_config(plugin, runner_context)
|
|
93
97
|
rules = plugin.rules(runner_context)
|
|
94
98
|
|
|
@@ -105,7 +109,6 @@ module RuboCop
|
|
|
105
109
|
raise "Plugin `#{plugin_name}' failed to load with error: #{error_message}"
|
|
106
110
|
end
|
|
107
111
|
end
|
|
108
|
-
# rubocop:enable Metrics/AbcSize
|
|
109
112
|
|
|
110
113
|
# This is how we ensure "first-in wins": plugins can override AllCops settings that are
|
|
111
114
|
# set by RuboCop's default configuration, but once a plugin sets an AllCop setting, they
|
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
|
8
8
|
# A class for loading and resolving plugins.
|
|
9
9
|
# @api private
|
|
10
10
|
class Loader
|
|
11
|
-
# rubocop:disable Layout/LineLength
|
|
11
|
+
# rubocop:disable Layout/LineLength -- the comment on each key does not wrap
|
|
12
12
|
DEFAULT_PLUGIN_CONFIG = {
|
|
13
13
|
'enabled' => true,
|
|
14
14
|
'require_path' => nil, # If not set, will be set to the plugin name
|
data/lib/rubocop/rake_task.rb
CHANGED
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
|
|
75
75
|
def setup_subtasks(name, *args, &task_block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
76
76
|
namespace(name) do
|
|
77
|
-
# rubocop:todo Naming/InclusiveLanguage
|
|
77
|
+
# rubocop:todo-next Naming/InclusiveLanguage -- the deprecated flag spelling is the subject here
|
|
78
78
|
task(:auto_correct, *args) do |_, task_args|
|
|
79
79
|
require 'rainbow'
|
|
80
80
|
warn Rainbow(
|
|
@@ -86,7 +86,6 @@ module RuboCop
|
|
|
86
86
|
perform('--autocorrect')
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
|
-
# rubocop:enable Naming/InclusiveLanguage
|
|
90
89
|
|
|
91
90
|
desc "Autocorrect RuboCop offenses (only when it's safe)."
|
|
92
91
|
task(:autocorrect, *args) do |_, task_args|
|
|
@@ -49,9 +49,9 @@ module RuboCop
|
|
|
49
49
|
http.use_ssl = uri.instance_of?(URI::HTTPS)
|
|
50
50
|
|
|
51
51
|
generate_request(uri) do |request|
|
|
52
|
-
handle_response(http.request(request), limit, &block)
|
|
52
|
+
handle_response(http.request(request), uri, limit, &block)
|
|
53
53
|
rescue SocketError => e
|
|
54
|
-
handle_response(e, limit, &block)
|
|
54
|
+
handle_response(e, uri, limit, &block)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -64,12 +64,12 @@ module RuboCop
|
|
|
64
64
|
yield request
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
def handle_response(response, limit, &block)
|
|
67
|
+
def handle_response(response, uri, limit, &block)
|
|
68
68
|
case response
|
|
69
69
|
when Net::HTTPSuccess, Net::HTTPNotModified, SocketError
|
|
70
70
|
yield response
|
|
71
71
|
when Net::HTTPRedirection
|
|
72
|
-
request(URI.
|
|
72
|
+
request(URI.join(uri, response['location']), limit - 1, &block)
|
|
73
73
|
else
|
|
74
74
|
begin
|
|
75
75
|
response.error!
|
data/lib/rubocop/result_cache.rb
CHANGED
|
@@ -123,7 +123,7 @@ module RuboCop
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def valid?
|
|
126
|
-
File.exist?(@path)
|
|
126
|
+
!@checksum_unavailable && File.exist?(@path)
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def load
|
|
@@ -132,6 +132,8 @@ module RuboCop
|
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
def save(offenses)
|
|
135
|
+
return if @checksum_unavailable
|
|
136
|
+
|
|
135
137
|
dir = File.dirname(@path)
|
|
136
138
|
|
|
137
139
|
begin
|
|
@@ -176,14 +178,23 @@ module RuboCop
|
|
|
176
178
|
end
|
|
177
179
|
|
|
178
180
|
def file_checksum(file, config_store)
|
|
181
|
+
stat = File.stat(file)
|
|
182
|
+
return unavailable_checksum unless stat.file?
|
|
183
|
+
|
|
179
184
|
digester = Digest::SHA1.new
|
|
180
|
-
mode
|
|
181
|
-
digester.update("#{file}#{mode}#{config_store.for_file(file).signature}")
|
|
185
|
+
digester.update("#{file}#{stat.mode}#{config_store.for_file(file).signature}")
|
|
182
186
|
digester.file(file)
|
|
183
187
|
digester.hexdigest
|
|
184
188
|
rescue Errno::ENOENT
|
|
185
|
-
# Spurious files that come and go should not cause a crash, at least not
|
|
186
|
-
|
|
189
|
+
# Spurious files that come and go should not cause a crash, at least not here.
|
|
190
|
+
unavailable_checksum
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Every file that fails to checksum shares this sentinel value, so the cache entry
|
|
194
|
+
# must be neither saved nor considered valid, or one file's cached results could be
|
|
195
|
+
# served as another's.
|
|
196
|
+
def unavailable_checksum
|
|
197
|
+
@checksum_unavailable = true
|
|
187
198
|
'_'
|
|
188
199
|
end
|
|
189
200
|
|
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
|
117
117
|
source
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
# rubocop:disable Metrics/AbcSize
|
|
120
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
121
121
|
def expect_offense(source, file = nil, severity: nil, chomp: false, **replacements)
|
|
122
122
|
expected_annotations = parse_annotations(source, **replacements)
|
|
123
123
|
source = expected_annotations.plain_source
|
|
@@ -138,9 +138,8 @@ module RuboCop
|
|
|
138
138
|
|
|
139
139
|
@offenses
|
|
140
140
|
end
|
|
141
|
-
# rubocop:enable Metrics/AbcSize
|
|
142
141
|
|
|
143
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
142
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
144
143
|
def expect_correction(correction, loop: true, source: nil)
|
|
145
144
|
if source
|
|
146
145
|
expected_annotations = parse_annotations(source, raise_error: false)
|
|
@@ -177,7 +176,6 @@ module RuboCop
|
|
|
177
176
|
expect(new_source).to eq(correction)
|
|
178
177
|
expect(@processed_source).to be_valid_syntax, 'Expected correction to be valid syntax'
|
|
179
178
|
end
|
|
180
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
181
179
|
|
|
182
180
|
def expect_no_corrections
|
|
183
181
|
raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
|
|
@@ -6,7 +6,7 @@ require 'tmpdir'
|
|
|
6
6
|
# or stubbing Dir.pwd get a fresh value.
|
|
7
7
|
RSpec.configure { |c| c.before { RuboCop::PathUtil.reset_pwd } }
|
|
8
8
|
|
|
9
|
-
# rubocop:disable Metrics/BlockLength
|
|
9
|
+
# rubocop:disable-next Metrics/BlockLength
|
|
10
10
|
RSpec.shared_context 'isolated environment' do
|
|
11
11
|
around do |example|
|
|
12
12
|
Dir.mktmpdir do |tmpdir|
|
|
@@ -69,7 +69,6 @@ RSpec.shared_context 'isolated environment' do
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
|
-
# rubocop:enable Metrics/BlockLength
|
|
73
72
|
|
|
74
73
|
# Workaround for https://github.com/rubocop/rubocop/issues/12978,
|
|
75
74
|
# there should already be no gemfile in the temp directory
|
|
@@ -136,6 +135,8 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
|
|
|
136
135
|
|
|
137
136
|
let(:gem_versions) { {} }
|
|
138
137
|
|
|
138
|
+
let(:path_sourced_gems) { [] }
|
|
139
|
+
|
|
139
140
|
### Utilities
|
|
140
141
|
|
|
141
142
|
def source_range(range, buffer: source_buffer)
|
|
@@ -180,6 +181,7 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
|
|
|
180
181
|
**gem_versions.transform_values { |value| Gem::Version.new(value) }
|
|
181
182
|
}
|
|
182
183
|
)
|
|
184
|
+
allow(config).to receive(:path_sourced_gems_in_target).and_return(path_sourced_gems)
|
|
183
185
|
|
|
184
186
|
config
|
|
185
187
|
end
|
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, :diffs
|
|
57
57
|
attr_writer :aborting
|
|
58
58
|
|
|
59
59
|
def initialize(options, config_store)
|
|
@@ -63,15 +63,18 @@ module RuboCop
|
|
|
63
63
|
@warnings = []
|
|
64
64
|
@aborting = false
|
|
65
65
|
@inspected_files = []
|
|
66
|
+
@diffs = []
|
|
66
67
|
@report_queue = {}
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
def run(paths)
|
|
71
|
+
@inspection_team_by_config = {}.compare_by_identity
|
|
72
|
+
|
|
70
73
|
# Compute the cache source checksum once to avoid potential
|
|
71
74
|
# inconsistencies between workers.
|
|
72
75
|
ResultCache.source_checksum
|
|
73
76
|
|
|
74
|
-
target_files = find_target_files(paths)
|
|
77
|
+
target_files = only_changed(find_target_files(paths))
|
|
75
78
|
build_project_index(target_files)
|
|
76
79
|
|
|
77
80
|
if @options[:list_target_files]
|
|
@@ -93,6 +96,16 @@ module RuboCop
|
|
|
93
96
|
|
|
94
97
|
private
|
|
95
98
|
|
|
99
|
+
# The project index is deliberately built from the unfiltered file list:
|
|
100
|
+
# cross-file offenses must not depend on which files happen to have changed.
|
|
101
|
+
def only_changed(target_files)
|
|
102
|
+
return target_files unless @options[:changed]
|
|
103
|
+
|
|
104
|
+
changed = ChangedFiles.new(@options[:changed]).paths
|
|
105
|
+
|
|
106
|
+
target_files.select { |file| changed.include?(file) }.freeze
|
|
107
|
+
end
|
|
108
|
+
|
|
96
109
|
def find_target_files(paths)
|
|
97
110
|
target_finder = TargetFinder.new(@config_store, @options)
|
|
98
111
|
mode = if @options[:only_recognized_file_types]
|
|
@@ -203,8 +216,7 @@ module RuboCop
|
|
|
203
216
|
end
|
|
204
217
|
|
|
205
218
|
def run_in_parallel?(files)
|
|
206
|
-
return false
|
|
207
|
-
return false unless @options[:parallel]
|
|
219
|
+
return false unless parallel_supported_by_options?
|
|
208
220
|
|
|
209
221
|
if files.size <= 1
|
|
210
222
|
puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug]
|
|
@@ -218,6 +230,13 @@ module RuboCop
|
|
|
218
230
|
true
|
|
219
231
|
end
|
|
220
232
|
|
|
233
|
+
# `--auto-gen-config` needs the offenses of every file in one place, and
|
|
234
|
+
# `--diff` collects the diffs in this process, where a worker's copy of
|
|
235
|
+
# them would be lost.
|
|
236
|
+
def parallel_supported_by_options?
|
|
237
|
+
@options[:parallel] && !@options[:auto_gen_config] && !@options[:diff]
|
|
238
|
+
end
|
|
239
|
+
|
|
221
240
|
def project_index_disables_parallel?
|
|
222
241
|
return false if @project_index.nil? || !Gem.win_platform?
|
|
223
242
|
|
|
@@ -264,7 +283,8 @@ module RuboCop
|
|
|
264
283
|
file_offense_cache(file) do
|
|
265
284
|
source, offenses = do_inspection_loop(file)
|
|
266
285
|
offenses = add_redundant_disables(file, offenses.compact.sort, source)
|
|
267
|
-
offenses.
|
|
286
|
+
offenses = offenses.reject(&:disabled?) unless @options[:display_suppressed]
|
|
287
|
+
offenses.sort.freeze
|
|
268
288
|
end
|
|
269
289
|
end
|
|
270
290
|
|
|
@@ -321,7 +341,13 @@ module RuboCop
|
|
|
321
341
|
end
|
|
322
342
|
|
|
323
343
|
def check_for_redundant_disables?(source)
|
|
324
|
-
return false if
|
|
344
|
+
return false if except_redundant_cop_disable_directive?
|
|
345
|
+
# Detached `disable-next` directives produce no disabled ranges but must
|
|
346
|
+
# still be reported as redundant.
|
|
347
|
+
if source.disabled_line_ranges.empty? &&
|
|
348
|
+
source.comment_config.detached_next_directives.empty?
|
|
349
|
+
return false
|
|
350
|
+
end
|
|
325
351
|
|
|
326
352
|
!@options[:only]
|
|
327
353
|
end
|
|
@@ -370,6 +396,7 @@ module RuboCop
|
|
|
370
396
|
def do_inspection_loop(file)
|
|
371
397
|
# We can reuse the prism result since the source did not change yet.
|
|
372
398
|
processed_source = get_processed_source(file, @prism_result)
|
|
399
|
+
original_source = processed_source.raw_source
|
|
373
400
|
# This variable is 2d array used to track corrected offenses after each
|
|
374
401
|
# inspection iteration. This is used to output meaningful infinite loop
|
|
375
402
|
# error message.
|
|
@@ -382,11 +409,7 @@ module RuboCop
|
|
|
382
409
|
# once. The corrections are kept in memory while iterating and written
|
|
383
410
|
# back to the file when the loop is done.
|
|
384
411
|
iterate_until_no_changes(processed_source, offenses_by_iteration) do
|
|
385
|
-
|
|
386
|
-
# only keep the corrected ones in order to avoid duplicate reporting.
|
|
387
|
-
!offenses_by_iteration.empty? && offenses_by_iteration.last.select!(&:corrected?)
|
|
388
|
-
team, new_offenses, updated_source_file = inspect_iteration(processed_source)
|
|
389
|
-
offenses_by_iteration.push(new_offenses)
|
|
412
|
+
team, updated_source_file = inspect_and_correct(processed_source, offenses_by_iteration)
|
|
390
413
|
|
|
391
414
|
# We have to reprocess the source to pickup the changes. Since the
|
|
392
415
|
# change could (theoretically) introduce parsing errors, we break the
|
|
@@ -402,15 +425,49 @@ module RuboCop
|
|
|
402
425
|
# Return summary of corrected offenses after all iterations
|
|
403
426
|
[processed_source, offenses_by_iteration.flatten.uniq]
|
|
404
427
|
ensure
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
428
|
+
finalize_corrections(file, original_source, corrected_source)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def inspect_and_correct(processed_source, offenses_by_iteration)
|
|
432
|
+
# The offenses that couldn't be corrected will be found again so we
|
|
433
|
+
# only keep the corrected ones in order to avoid duplicate reporting.
|
|
434
|
+
!offenses_by_iteration.empty? && offenses_by_iteration.last.select!(&:corrected?)
|
|
435
|
+
team, new_offenses, updated_source_file = inspect_iteration(processed_source)
|
|
436
|
+
offenses_by_iteration.push(new_offenses)
|
|
437
|
+
|
|
438
|
+
[team, updated_source_file]
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Write the file once, even when the loop was left through an exception
|
|
442
|
+
# (e.g. an infinite correction loop), like the per-iteration writes used
|
|
443
|
+
# to be. Under `--diff` nothing is written at all.
|
|
444
|
+
def finalize_corrections(file, original_source, corrected_source)
|
|
445
|
+
if @options[:diff]
|
|
446
|
+
record_diff(file, original_source, corrected_source)
|
|
447
|
+
elsif corrected_source
|
|
448
|
+
File.write(file, corrected_source)
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# `--diff` reports what autocorrection would do instead of doing it. With
|
|
453
|
+
# `--stdin` the corrected source is handed back through the options rather
|
|
454
|
+
# than deferred, so that is where the new source comes from.
|
|
455
|
+
def record_diff(file, original_source, corrected_source)
|
|
456
|
+
new_source = @options[:stdin] || corrected_source
|
|
457
|
+
return unless original_source && new_source
|
|
458
|
+
|
|
459
|
+
# The original source is the file as it is on disk, so the corrected one
|
|
460
|
+
# has to go through the same line ending conversion `File.write` would
|
|
461
|
+
# apply, or on Windows every single line reads as changed.
|
|
462
|
+
new_source = emulate_write_read_cycle(new_source)
|
|
463
|
+
|
|
464
|
+
diff = UnifiedDiff.new(PathUtil.smart_path(file), original_source, new_source).to_s
|
|
465
|
+
@diffs << diff unless diff.empty?
|
|
409
466
|
end
|
|
410
467
|
|
|
411
468
|
def inspect_iteration(processed_source)
|
|
412
469
|
team = mobilize_team(processed_source)
|
|
413
|
-
team.defer_corrections = in_memory_corrections_possible?
|
|
470
|
+
team.defer_corrections = @options[:diff] || in_memory_corrections_possible?
|
|
414
471
|
offenses, updated_source_file = inspect_file(processed_source, team)
|
|
415
472
|
[team, offenses, updated_source_file]
|
|
416
473
|
end
|
|
@@ -496,15 +553,8 @@ module RuboCop
|
|
|
496
553
|
|
|
497
554
|
def mobilize_team(processed_source)
|
|
498
555
|
config = @config_store.for_file(processed_source.path)
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
if @project_index
|
|
502
|
-
team.cops.each do |cop|
|
|
503
|
-
cop.project_index = @project_index
|
|
504
|
-
end
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
team
|
|
556
|
+
@inspection_team_by_config ||= {}.compare_by_identity
|
|
557
|
+
@inspection_team_by_config[config] ||= assemble_team(config)
|
|
508
558
|
end
|
|
509
559
|
|
|
510
560
|
def mobilized_cop_classes(config)
|
|
@@ -600,16 +650,11 @@ module RuboCop
|
|
|
600
650
|
end
|
|
601
651
|
|
|
602
652
|
def minimum_severity_to_fail
|
|
603
|
-
@minimum_severity_to_fail ||=
|
|
604
|
-
|
|
605
|
-
name = @options[:fail_level] || :refactor
|
|
606
|
-
|
|
607
|
-
# autocorrect is a fake level - use the default
|
|
608
|
-
RuboCop::Cop::Severity.new(name == :autocorrect ? :refactor : name)
|
|
609
|
-
end
|
|
653
|
+
@minimum_severity_to_fail ||=
|
|
654
|
+
RuboCop::Cop::Severity.minimum_to_fail(@options, @config_store.for_pwd)
|
|
610
655
|
end
|
|
611
656
|
|
|
612
|
-
# rubocop:disable Metrics/MethodLength
|
|
657
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
613
658
|
def get_processed_source(file, prism_result, source: nil)
|
|
614
659
|
config = @config_store.for_file(file)
|
|
615
660
|
ruby_version = config.target_ruby_version
|
|
@@ -643,25 +688,26 @@ module RuboCop
|
|
|
643
688
|
processed_source.registry = mobilized_cop_classes(config)
|
|
644
689
|
processed_source
|
|
645
690
|
end
|
|
646
|
-
# rubocop:enable Metrics/MethodLength
|
|
647
691
|
|
|
648
692
|
# A Cop::Team instance is stateful and may change when inspecting.
|
|
649
693
|
# The "standby" team for a given config is an initialized but
|
|
650
694
|
# otherwise dormant team that can be used for config- and option-
|
|
651
695
|
# level caching in ResultCache.
|
|
652
696
|
def standby_team(config)
|
|
653
|
-
@
|
|
654
|
-
@
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
if @project_index
|
|
658
|
-
team.cops.each do |cop|
|
|
659
|
-
cop.project_index = @project_index
|
|
660
|
-
end
|
|
661
|
-
end
|
|
697
|
+
@standby_team_by_config ||= {}.compare_by_identity
|
|
698
|
+
@standby_team_by_config[config] ||= assemble_team(config)
|
|
699
|
+
end
|
|
662
700
|
|
|
663
|
-
|
|
701
|
+
def assemble_team(config)
|
|
702
|
+
team = Cop::Team.mobilize(mobilized_cop_classes(config), config, @options)
|
|
703
|
+
|
|
704
|
+
if @project_index
|
|
705
|
+
team.cops.each do |cop|
|
|
706
|
+
cop.project_index = @project_index
|
|
707
|
+
end
|
|
664
708
|
end
|
|
709
|
+
|
|
710
|
+
team
|
|
665
711
|
end
|
|
666
712
|
end
|
|
667
713
|
end
|