rubocop 1.71.1 → 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/LICENSE.txt +1 -1
- data/README.md +23 -19
- data/config/default.yml +883 -168
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +47 -4
- data/exe/rubocop +2 -9
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/changed_files.rb +112 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- data/lib/rubocop/cli/command/execute_runner.rb +52 -1
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli.rb +58 -17
- 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 +92 -48
- data/lib/rubocop/config.rb +137 -19
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +72 -49
- data/lib/rubocop/config_loader_resolver.rb +94 -28
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/removed_cop.rb +8 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +47 -3
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +64 -12
- data/lib/rubocop/cop/autocorrect_logic.rb +35 -14
- data/lib/rubocop/cop/badge.rb +9 -1
- data/lib/rubocop/cop/base.rb +93 -21
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +79 -10
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +36 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
- data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +14 -15
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +3 -16
- data/lib/rubocop/cop/layout/argument_alignment.rb +4 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +59 -4
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +163 -35
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +9 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +56 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +11 -13
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +157 -10
- data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +2 -3
- data/lib/rubocop/cop/layout/line_length.rb +160 -23
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +245 -40
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +89 -6
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +14 -3
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -3
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +42 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +13 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +20 -65
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
- data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +137 -11
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +13 -19
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +185 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
- data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +149 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +9 -5
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
- data/lib/rubocop/cop/lint/to_json.rb +20 -17
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +36 -10
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
- data/lib/rubocop/cop/lint/useless_assignment.rb +56 -27
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
- data/lib/rubocop/cop/lint/void.rb +60 -21
- data/lib/rubocop/cop/lint.rb +179 -0
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +2 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +3 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +11 -5
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/alignment.rb +3 -3
- data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +27 -9
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -7
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +44 -16
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +29 -26
- data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +62 -6
- data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -5
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +47 -11
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
- data/lib/rubocop/cop/mixin.rb +91 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +6 -5
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
- data/lib/rubocop/cop/naming/method_name.rb +190 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +80 -8
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -6
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +52 -9
- data/lib/rubocop/cop/registry.rb +233 -64
- data/lib/rubocop/cop/security/eval.rb +17 -3
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +47 -13
- data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
- data/lib/rubocop/cop/style/alias.rb +15 -3
- data/lib/rubocop/cop/style/and_or.rb +2 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +49 -37
- data/lib/rubocop/cop/style/array_first_last.rb +13 -3
- data/lib/rubocop/cop/style/array_intersect.rb +136 -38
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +7 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +43 -38
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +6 -8
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +135 -21
- data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
- data/lib/rubocop/cop/style/collection_compact.rb +37 -17
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_loops.rb +7 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +8 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +54 -24
- data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
- data/lib/rubocop/cop/style/copyright.rb +27 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
- data/lib/rubocop/cop/style/dig_chain.rb +6 -1
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +122 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +53 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -12
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +4 -3
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +11 -2
- data/lib/rubocop/cop/style/empty_method.rb +12 -8
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +191 -19
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
- data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
- data/lib/rubocop/cop/style/file_null.rb +6 -4
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +21 -16
- data/lib/rubocop/cop/style/float_division.rb +25 -17
- data/lib/rubocop/cop/style/for.rb +9 -0
- data/lib/rubocop/cop/style/format_string.rb +17 -4
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +32 -23
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -12
- data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +105 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +7 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
- data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -9
- data/lib/rubocop/cop/style/if_inside_else.rb +25 -20
- data/lib/rubocop/cop/style/if_unless_modifier.rb +71 -46
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +15 -19
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +10 -6
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
- data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
- data/lib/rubocop/cop/style/lambda.rb +12 -1
- data/lib/rubocop/cop/style/lambda_call.rb +26 -10
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +5 -2
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +31 -15
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +34 -5
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -7
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -5
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
- data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +4 -2
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -18
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +111 -12
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +9 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +41 -13
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
- data/lib/rubocop/cop/style/not.rb +5 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +22 -13
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +4 -2
- data/lib/rubocop/cop/style/raise_args.rb +9 -9
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +38 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +63 -5
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +11 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +7 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -10
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +319 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +164 -82
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +8 -8
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -0
- data/lib/rubocop/cop/style/redundant_return.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self.rb +20 -7
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
- data/lib/rubocop/cop/style/sample.rb +11 -6
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +45 -14
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -8
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
- data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -1
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +31 -15
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +38 -2
- data/lib/rubocop/cop/style/super_arguments.rb +4 -6
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +11 -9
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +18 -19
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_do.rb +7 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +2 -3
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/style.rb +311 -0
- data/lib/rubocop/cop/team.rb +163 -45
- data/lib/rubocop/cop/util.rb +7 -10
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +28 -10
- data/lib/rubocop/cop/variable_force.rb +26 -9
- data/lib/rubocop/cops_documentation_generator.rb +49 -15
- data/lib/rubocop/directive_comment.rb +147 -5
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +3 -2
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +3 -5
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +27 -10
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +2 -3
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +181 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +8 -3
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
- data/lib/rubocop/formatter.rb +23 -21
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +22 -41
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +136 -33
- data/lib/rubocop/lsp/runtime.rb +23 -8
- data/lib/rubocop/lsp/server.rb +4 -2
- data/lib/rubocop/lsp/stdin_runner.rb +31 -18
- data/lib/rubocop/magic_comment.rb +55 -0
- data/lib/rubocop/mcp/server.rb +199 -0
- data/lib/rubocop/options.rb +129 -21
- data/lib/rubocop/path_util.rb +20 -5
- data/lib/rubocop/pending_cops_reporter.rb +51 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +146 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/project_index_loader.rb +82 -0
- data/lib/rubocop/rake_task.rb +6 -4
- data/lib/rubocop/remote_config.rb +14 -12
- data/lib/rubocop/result_cache.rb +90 -52
- data/lib/rubocop/rspec/cop_helper.rb +21 -1
- data/lib/rubocop/rspec/expect_offense.rb +11 -7
- data/lib/rubocop/rspec/shared_contexts.rb +85 -3
- data/lib/rubocop/rspec/support.rb +4 -0
- data/lib/rubocop/runner.rb +294 -100
- data/lib/rubocop/server/cache.rb +67 -48
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +25 -11
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/version.rb +48 -10
- data/lib/rubocop.rb +30 -682
- data/lib/ruby_lsp/rubocop/addon.rb +28 -17
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +116 -19
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../feature_loader'
|
|
4
|
+
require_relative 'load_error'
|
|
5
|
+
|
|
6
|
+
module RuboCop
|
|
7
|
+
module Plugin
|
|
8
|
+
# A class for loading and resolving plugins.
|
|
9
|
+
# @api private
|
|
10
|
+
class Loader
|
|
11
|
+
# rubocop:disable Layout/LineLength -- the comment on each key does not wrap
|
|
12
|
+
DEFAULT_PLUGIN_CONFIG = {
|
|
13
|
+
'enabled' => true,
|
|
14
|
+
'require_path' => nil, # If not set, will be set to the plugin name
|
|
15
|
+
'plugin_class_name' => nil # If not set, looks for gemspec `spec.metadata["default_lint_roller_plugin"]`
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
# rubocop:enable Layout/LineLength
|
|
19
|
+
class << self
|
|
20
|
+
def load(plugins)
|
|
21
|
+
normalized_plugin_configs = normalize(plugins)
|
|
22
|
+
normalized_plugin_configs.filter_map do |plugin_name, plugin_config|
|
|
23
|
+
next unless plugin_config['enabled']
|
|
24
|
+
|
|
25
|
+
plugin_class = constantize_plugin_from(plugin_name, plugin_config)
|
|
26
|
+
|
|
27
|
+
plugin_class.new(plugin_config)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
|
34
|
+
def normalize(plugin_configs)
|
|
35
|
+
plugin_configs.to_h do |plugin_config|
|
|
36
|
+
if plugin_config == Plugin::OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
|
|
37
|
+
warn Rainbow(<<~MESSAGE).yellow
|
|
38
|
+
Specify `rubocop-internal_affairs` instead of `rubocop/cop/internal_affairs` in your configuration.
|
|
39
|
+
MESSAGE
|
|
40
|
+
plugin_config = Plugin::INTERNAL_AFFAIRS_PLUGIN_NAME
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if plugin_config.is_a?(Hash)
|
|
44
|
+
plugin_name = plugin_config.keys.first
|
|
45
|
+
|
|
46
|
+
[
|
|
47
|
+
plugin_name, DEFAULT_PLUGIN_CONFIG.merge(
|
|
48
|
+
{ 'require_path' => plugin_name }, plugin_config.values.first
|
|
49
|
+
)
|
|
50
|
+
]
|
|
51
|
+
# NOTE: Compatibility is maintained when `require: rubocop/cop/internal_affairs` remains
|
|
52
|
+
# specified in `.rubocop.yml`.
|
|
53
|
+
elsif (builtin_plugin_config = Plugin::BUILTIN_INTERNAL_PLUGINS[plugin_config])
|
|
54
|
+
[plugin_config, builtin_plugin_config]
|
|
55
|
+
else
|
|
56
|
+
[plugin_config, DEFAULT_PLUGIN_CONFIG.merge('require_path' => plugin_config)]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def constantize_plugin_from(plugin_name, plugin_config)
|
|
62
|
+
if plugin_name.is_a?(String) || plugin_name.is_a?(Symbol)
|
|
63
|
+
constantize(plugin_name, plugin_config)
|
|
64
|
+
else
|
|
65
|
+
plugin_name
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# rubocop:enable Metrics/MethodLength
|
|
70
|
+
def constantize(plugin_name, plugin_config)
|
|
71
|
+
require_plugin(plugin_config['require_path'])
|
|
72
|
+
|
|
73
|
+
if (constant_name = plugin_config['plugin_class_name'])
|
|
74
|
+
begin
|
|
75
|
+
Kernel.const_get(constant_name)
|
|
76
|
+
rescue StandardError
|
|
77
|
+
raise <<~MESSAGE
|
|
78
|
+
Failed while configuring plugin `#{plugin_name}': no constant with name `#{constant_name}' was found.
|
|
79
|
+
MESSAGE
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
constantize_plugin_from_gemspec_metadata(plugin_name)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def require_plugin(require_path)
|
|
87
|
+
FeatureLoader.load(config_directory_path: PathUtil.pwd, feature: require_path)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def constantize_plugin_from_gemspec_metadata(plugin_name)
|
|
91
|
+
plugin_class_name = Gem.loaded_specs[plugin_name].metadata['default_lint_roller_plugin']
|
|
92
|
+
|
|
93
|
+
Kernel.const_get(plugin_class_name)
|
|
94
|
+
rescue LoadError, StandardError
|
|
95
|
+
raise Plugin::LoadError, plugin_name
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Plugin
|
|
5
|
+
# An exception raised when a plugin is not supported by the RuboCop engine.
|
|
6
|
+
# @api private
|
|
7
|
+
class NotSupportedError < Error
|
|
8
|
+
def initialize(unsupported_plugins)
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
@unsupported_plugins = unsupported_plugins
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def message
|
|
15
|
+
if @unsupported_plugins.one?
|
|
16
|
+
about = @unsupported_plugins.first.about
|
|
17
|
+
|
|
18
|
+
"#{about.name} #{about.version} is not a plugin supported by RuboCop engine."
|
|
19
|
+
else
|
|
20
|
+
unsupported_plugin_names = @unsupported_plugins.map do |plugin|
|
|
21
|
+
"#{plugin.about.name} #{plugin.about.version}"
|
|
22
|
+
end.join(', ')
|
|
23
|
+
|
|
24
|
+
"#{unsupported_plugin_names} are not plugins supported by RuboCop engine."
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'plugin/configuration_integrator'
|
|
4
|
+
require_relative 'plugin/loader'
|
|
5
|
+
|
|
6
|
+
module RuboCop
|
|
7
|
+
# Provides a plugin for RuboCop extensions that conform to lint_roller.
|
|
8
|
+
# https://github.com/standardrb/lint_roller
|
|
9
|
+
# @api private
|
|
10
|
+
module Plugin
|
|
11
|
+
BUILTIN_INTERNAL_PLUGINS = {
|
|
12
|
+
'rubocop-internal_affairs' => {
|
|
13
|
+
'enabled' => true,
|
|
14
|
+
'require_path' => 'rubocop/cop/internal_affairs/plugin',
|
|
15
|
+
'plugin_class_name' => 'RuboCop::InternalAffairs::Plugin'
|
|
16
|
+
}
|
|
17
|
+
}.freeze
|
|
18
|
+
INTERNAL_AFFAIRS_PLUGIN_NAME = Plugin::BUILTIN_INTERNAL_PLUGINS.keys.first
|
|
19
|
+
OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME = 'rubocop/cop/internal_affairs'
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
def plugin_capable?(feature_name)
|
|
23
|
+
return true if BUILTIN_INTERNAL_PLUGINS.key?(feature_name)
|
|
24
|
+
return true if feature_name == OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
|
|
25
|
+
|
|
26
|
+
begin
|
|
27
|
+
# When not using Bundler. Makes the spec available but does not require it.
|
|
28
|
+
gem feature_name
|
|
29
|
+
rescue Gem::LoadError
|
|
30
|
+
# The user requested a gem that they do not have installed
|
|
31
|
+
end
|
|
32
|
+
return false unless (spec = Gem.loaded_specs[feature_name])
|
|
33
|
+
|
|
34
|
+
!!spec.metadata['default_lint_roller_plugin']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def integrate_plugins(rubocop_config, plugins)
|
|
38
|
+
plugins = Plugin::Loader.load(plugins)
|
|
39
|
+
|
|
40
|
+
ConfigurationIntegrator.integrate_plugins_into_rubocop_config(rubocop_config, plugins)
|
|
41
|
+
|
|
42
|
+
plugins
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
# Defensive loader for the optional `rubydex` gem.
|
|
5
|
+
#
|
|
6
|
+
# When `AllCops/UseProjectIndex` is enabled in the user's configuration, RuboCop builds
|
|
7
|
+
# a project-wide index using `Rubydex::Graph` and exposes it to cops that opt in.
|
|
8
|
+
# The gem is intentionally not a runtime dependency; if it is not installed,
|
|
9
|
+
# or if the running Ruby is older than what `rubydex` supports, RuboCop falls back to
|
|
10
|
+
# its standard file-local behavior.
|
|
11
|
+
module ProjectIndexLoader
|
|
12
|
+
MINIMUM_RUBY_VERSION = '3.2'
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Returns whether the `rubydex` gem can be loaded. The result is memoized
|
|
17
|
+
# for the lifetime of the process.
|
|
18
|
+
def available?
|
|
19
|
+
return @available if defined?(@available)
|
|
20
|
+
|
|
21
|
+
@available = supported_ruby? && try_require
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def supported_ruby?
|
|
25
|
+
RUBY_VERSION >= MINIMUM_RUBY_VERSION
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def warn_unavailable
|
|
29
|
+
return if @warned
|
|
30
|
+
|
|
31
|
+
@warned = true
|
|
32
|
+
|
|
33
|
+
if supported_ruby?
|
|
34
|
+
warn Rainbow(<<~MSG).yellow
|
|
35
|
+
`AllCops/UseProjectIndex` is enabled but the `rubydex` gem is not installed.
|
|
36
|
+
Analyses that use the project index will be skipped. Add `gem 'rubydex'` to your Gemfile.
|
|
37
|
+
MSG
|
|
38
|
+
else
|
|
39
|
+
warn Rainbow(<<~MSG).yellow
|
|
40
|
+
`AllCops/UseProjectIndex` is enabled but `rubydex` requires Ruby #{MINIMUM_RUBY_VERSION} or later (current: #{RUBY_VERSION}).
|
|
41
|
+
Analyses that use the project index will be skipped.
|
|
42
|
+
MSG
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def try_require
|
|
47
|
+
require 'rubydex'
|
|
48
|
+
true
|
|
49
|
+
rescue LoadError
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Builds and resolves a `Rubydex::Graph` for the given file paths. Returns the resolved graph,
|
|
54
|
+
# or `nil` if the build fails. This is the only place in RuboCop that depends on the concrete
|
|
55
|
+
# `Rubydex::Graph` API, so callers (e.g. `Runner`) do not need to know which Rubydex classes
|
|
56
|
+
# or methods are involved.
|
|
57
|
+
def build_index(paths)
|
|
58
|
+
graph = Rubydex::Graph.new
|
|
59
|
+
graph.index_all(paths.map(&:to_s))
|
|
60
|
+
graph.resolve
|
|
61
|
+
graph
|
|
62
|
+
rescue StandardError => e
|
|
63
|
+
warn Rainbow("rubydex index build failed: #{e.message}. Continuing without it.").yellow
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The Ruby source files of every gem in the project's bundle, for
|
|
67
|
+
# `AllCops/ProjectIndexIncludesGems`. Returns an empty array when RuboCop
|
|
68
|
+
# does not run inside Bundler, so the option silently degrades to
|
|
69
|
+
# project-only indexing.
|
|
70
|
+
def bundled_gem_source_files
|
|
71
|
+
return [] unless defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
|
|
72
|
+
|
|
73
|
+
Bundler.load.specs.flat_map do |spec|
|
|
74
|
+
Dir.glob(File.join(spec.full_gem_path, 'lib', '**', '*.rb'))
|
|
75
|
+
end
|
|
76
|
+
rescue StandardError => e
|
|
77
|
+
message = "rubydex bundle indexing failed: #{e.message}. Indexing the project only."
|
|
78
|
+
warn Rainbow(message).yellow
|
|
79
|
+
[]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
data/lib/rubocop/rake_task.rb
CHANGED
|
@@ -12,7 +12,8 @@ module RuboCop
|
|
|
12
12
|
# Use global Rake namespace here to avoid namespace issues with custom
|
|
13
13
|
# rubocop-rake tasks
|
|
14
14
|
class RakeTask < ::Rake::TaskLib
|
|
15
|
-
attr_accessor :name, :verbose, :fail_on_error, :patterns, :formatters, :
|
|
15
|
+
attr_accessor :name, :verbose, :fail_on_error, :patterns, :formatters, :plugins, :requires,
|
|
16
|
+
:options
|
|
16
17
|
|
|
17
18
|
def initialize(name = :rubocop, *args, &task_block)
|
|
18
19
|
super()
|
|
@@ -54,6 +55,7 @@ module RuboCop
|
|
|
54
55
|
|
|
55
56
|
def full_options
|
|
56
57
|
formatters.map { |f| ['--format', f] }.flatten
|
|
58
|
+
.concat(plugins.map { |plugin| ['--plugin', plugin] }.flatten)
|
|
57
59
|
.concat(requires.map { |r| ['--require', r] }.flatten)
|
|
58
60
|
.concat(options.flatten)
|
|
59
61
|
.concat(patterns)
|
|
@@ -64,6 +66,7 @@ module RuboCop
|
|
|
64
66
|
@verbose = true
|
|
65
67
|
@fail_on_error = true
|
|
66
68
|
@patterns = []
|
|
69
|
+
@plugins = []
|
|
67
70
|
@requires = []
|
|
68
71
|
@options = []
|
|
69
72
|
@formatters = []
|
|
@@ -71,8 +74,8 @@ module RuboCop
|
|
|
71
74
|
|
|
72
75
|
def setup_subtasks(name, *args, &task_block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
73
76
|
namespace(name) do
|
|
74
|
-
# rubocop:todo Naming/InclusiveLanguage
|
|
75
|
-
task(:auto_correct, *args) do
|
|
77
|
+
# rubocop:todo-next Naming/InclusiveLanguage -- the deprecated flag spelling is the subject here
|
|
78
|
+
task(:auto_correct, *args) do |_, task_args|
|
|
76
79
|
require 'rainbow'
|
|
77
80
|
warn Rainbow(
|
|
78
81
|
'rubocop:auto_correct task is deprecated; ' \
|
|
@@ -83,7 +86,6 @@ module RuboCop
|
|
|
83
86
|
perform('--autocorrect')
|
|
84
87
|
end
|
|
85
88
|
end
|
|
86
|
-
# rubocop:enable Naming/InclusiveLanguage
|
|
87
89
|
|
|
88
90
|
desc "Autocorrect RuboCop offenses (only when it's safe)."
|
|
89
91
|
task(:autocorrect, *args) do |_, task_args|
|
|
@@ -11,13 +11,13 @@ module RuboCop
|
|
|
11
11
|
|
|
12
12
|
CACHE_LIFETIME = 24 * 60 * 60
|
|
13
13
|
|
|
14
|
-
def initialize(url,
|
|
14
|
+
def initialize(url, cache_root)
|
|
15
15
|
begin
|
|
16
16
|
@uri = URI.parse(url)
|
|
17
17
|
rescue URI::InvalidURIError
|
|
18
18
|
raise ConfigNotFoundError, "Failed to resolve configuration: '#{url}' is not a valid URI"
|
|
19
19
|
end
|
|
20
|
-
@
|
|
20
|
+
@cache_root = cache_root
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def file
|
|
@@ -27,16 +27,17 @@ module RuboCop
|
|
|
27
27
|
next if response.is_a?(Net::HTTPNotModified)
|
|
28
28
|
next if response.is_a?(SocketError)
|
|
29
29
|
|
|
30
|
+
FileUtils.mkdir_p(File.dirname(cache_path))
|
|
30
31
|
File.write(cache_path, response.body)
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
cache_path
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
def inherit_from_remote(file
|
|
37
|
+
def inherit_from_remote(file)
|
|
37
38
|
new_uri = @uri.dup
|
|
38
39
|
new_uri.path.gsub!(%r{/[^/]*$}, "/#{file.delete_prefix('./')}")
|
|
39
|
-
RemoteConfig.new(new_uri.to_s,
|
|
40
|
+
RemoteConfig.new(new_uri.to_s, @cache_root)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
private
|
|
@@ -48,9 +49,9 @@ module RuboCop
|
|
|
48
49
|
http.use_ssl = uri.instance_of?(URI::HTTPS)
|
|
49
50
|
|
|
50
51
|
generate_request(uri) do |request|
|
|
51
|
-
handle_response(http.request(request), limit, &block)
|
|
52
|
+
handle_response(http.request(request), uri, limit, &block)
|
|
52
53
|
rescue SocketError => e
|
|
53
|
-
handle_response(e, limit, &block)
|
|
54
|
+
handle_response(e, uri, limit, &block)
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
@@ -63,12 +64,12 @@ module RuboCop
|
|
|
63
64
|
yield request
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
def handle_response(response, limit, &block)
|
|
67
|
+
def handle_response(response, uri, limit, &block)
|
|
67
68
|
case response
|
|
68
69
|
when Net::HTTPSuccess, Net::HTTPNotModified, SocketError
|
|
69
70
|
yield response
|
|
70
71
|
when Net::HTTPRedirection
|
|
71
|
-
request(URI.
|
|
72
|
+
request(URI.join(uri, response['location']), limit - 1, &block)
|
|
72
73
|
else
|
|
73
74
|
begin
|
|
74
75
|
response.error!
|
|
@@ -80,7 +81,7 @@ module RuboCop
|
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
def cache_path
|
|
83
|
-
File.expand_path(
|
|
84
|
+
@cache_path ||= File.expand_path(cache_name_from_uri, @cache_root)
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
def cache_path_exists?
|
|
@@ -97,9 +98,10 @@ module RuboCop
|
|
|
97
98
|
end
|
|
98
99
|
|
|
99
100
|
def cache_name_from_uri
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
uri.
|
|
101
|
+
# The md5 checksum suffix is 37 bytes, so we play it save and
|
|
102
|
+
# allow 254 bytes total - this should be safe on Linux/macOS/Windows
|
|
103
|
+
filename = File.basename(@uri.path).gsub(/\.ya?ml\z/i, '').byteslice(0, 217).scrub('')
|
|
104
|
+
"#{filename}-#{Digest::MD5.hexdigest(@uri.to_s)}.yml"
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
def cloned_url
|
data/lib/rubocop/result_cache.rb
CHANGED
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
|
9
9
|
# Provides functionality for caching RuboCop runs.
|
|
10
10
|
# @api private
|
|
11
11
|
class ResultCache
|
|
12
|
-
NON_CHANGING = %i[color format formatters out debug fail_level
|
|
12
|
+
NON_CHANGING = %i[color format formatters out debug display_time fail_level
|
|
13
13
|
fix_layout autocorrect safe_autocorrect autocorrect_all
|
|
14
14
|
cache fail_fast stdin parallel].freeze
|
|
15
15
|
|
|
@@ -22,19 +22,22 @@ module RuboCop
|
|
|
22
22
|
# Remove old files so that the cache doesn't grow too big. When the
|
|
23
23
|
# threshold MaxFilesInCache has been exceeded, the oldest 50% of all the
|
|
24
24
|
# files in the cache are removed. The reason for removing so much is that
|
|
25
|
-
#
|
|
25
|
+
# removing should be done relatively seldom, since there is a slight risk
|
|
26
26
|
# that some other RuboCop process was just about to read the file, when
|
|
27
27
|
# there's parallel execution and the cache is shared.
|
|
28
28
|
def self.cleanup(config_store, verbose, cache_root_override = nil)
|
|
29
29
|
return if inhibit_cleanup # OPTIMIZE: For faster testing
|
|
30
|
+
return unless config_store.for_pwd.for_all_cops['MaxFilesInCache']
|
|
30
31
|
|
|
31
32
|
rubocop_cache_dir = cache_root(config_store, cache_root_override)
|
|
32
33
|
return unless File.exist?(rubocop_cache_dir)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
# We know the cache entries are 3 level deep, so globing
|
|
36
|
+
# for `*/*/*` only returns files.
|
|
37
|
+
files = Dir[File.join(rubocop_cache_dir, '*/*/*')]
|
|
35
38
|
return unless requires_file_removal?(files.length, config_store)
|
|
36
39
|
|
|
37
|
-
remove_oldest_files(files,
|
|
40
|
+
remove_oldest_files(files, rubocop_cache_dir, verbose)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
class << self
|
|
@@ -49,39 +52,57 @@ module RuboCop
|
|
|
49
52
|
file_count > 1 && file_count > config_store.for_pwd.for_all_cops['MaxFilesInCache']
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
def remove_oldest_files(files,
|
|
55
|
+
def remove_oldest_files(files, rubocop_cache_dir, verbose)
|
|
53
56
|
# Add 1 to half the number of files, so that we remove the file if
|
|
54
57
|
# there's only 1 left.
|
|
55
58
|
remove_count = (files.length / 2) + 1
|
|
56
59
|
puts "Removing the #{remove_count} oldest files from #{rubocop_cache_dir}" if verbose
|
|
57
60
|
sorted = files.sort_by { |path| File.mtime(path) }
|
|
58
|
-
remove_files(sorted,
|
|
61
|
+
remove_files(sorted, remove_count)
|
|
59
62
|
rescue Errno::ENOENT
|
|
60
63
|
# This can happen if parallel RuboCop invocations try to remove the
|
|
61
64
|
# same files. No problem.
|
|
62
65
|
puts $ERROR_INFO if verbose
|
|
63
66
|
end
|
|
64
67
|
|
|
65
|
-
def remove_files(files,
|
|
68
|
+
def remove_files(files, remove_count)
|
|
66
69
|
# Batch file deletions, deleting over 130,000+ files will crash
|
|
67
70
|
# File.delete.
|
|
68
71
|
files[0, remove_count].each_slice(10_000).each do |files_slice|
|
|
69
72
|
File.delete(*files_slice)
|
|
70
73
|
end
|
|
71
|
-
|
|
74
|
+
|
|
75
|
+
dirs = files.map { |f| File.dirname(f) }.uniq
|
|
76
|
+
until dirs.empty?
|
|
77
|
+
dirs.select! do |dir|
|
|
78
|
+
Dir.rmdir(dir)
|
|
79
|
+
true
|
|
80
|
+
rescue SystemCallError # ENOTEMPTY etc
|
|
81
|
+
false
|
|
82
|
+
end
|
|
83
|
+
dirs = dirs.map { |f| File.dirname(f) }.uniq
|
|
84
|
+
end
|
|
72
85
|
end
|
|
73
86
|
end
|
|
74
87
|
|
|
75
88
|
def self.cache_root(config_store, cache_root_override = nil)
|
|
76
|
-
|
|
89
|
+
return @cache_root if @cache_root && !cache_root_override
|
|
90
|
+
|
|
91
|
+
result = CacheConfig.root_dir do
|
|
77
92
|
cache_root_override || config_store.for_pwd.for_all_cops['CacheRootDirectory']
|
|
78
93
|
end
|
|
94
|
+
@cache_root = result unless cache_root_override
|
|
95
|
+
result
|
|
79
96
|
end
|
|
80
97
|
|
|
81
98
|
def self.allow_symlinks_in_cache_location?(config_store)
|
|
82
99
|
config_store.for_pwd.for_all_cops['AllowSymlinksInCacheRootDirectory']
|
|
83
100
|
end
|
|
84
101
|
|
|
102
|
+
def self.reset_config_cache
|
|
103
|
+
@cache_root = nil
|
|
104
|
+
end
|
|
105
|
+
|
|
85
106
|
attr_reader :path
|
|
86
107
|
|
|
87
108
|
def initialize(file, team, options, config_store, cache_root_override = nil)
|
|
@@ -90,7 +111,7 @@ module RuboCop
|
|
|
90
111
|
@allow_symlinks_in_cache_location =
|
|
91
112
|
ResultCache.allow_symlinks_in_cache_location?(config_store)
|
|
92
113
|
@path = File.join(rubocop_cache_dir,
|
|
93
|
-
|
|
114
|
+
self.class.source_checksum,
|
|
94
115
|
context_checksum(team, options),
|
|
95
116
|
file_checksum(file, config_store))
|
|
96
117
|
@cached_data = CachedData.new(file)
|
|
@@ -102,7 +123,7 @@ module RuboCop
|
|
|
102
123
|
end
|
|
103
124
|
|
|
104
125
|
def valid?
|
|
105
|
-
File.exist?(@path)
|
|
126
|
+
!@checksum_unavailable && File.exist?(@path)
|
|
106
127
|
end
|
|
107
128
|
|
|
108
129
|
def load
|
|
@@ -111,6 +132,8 @@ module RuboCop
|
|
|
111
132
|
end
|
|
112
133
|
|
|
113
134
|
def save(offenses)
|
|
135
|
+
return if @checksum_unavailable
|
|
136
|
+
|
|
114
137
|
dir = File.dirname(@path)
|
|
115
138
|
|
|
116
139
|
begin
|
|
@@ -155,25 +178,32 @@ module RuboCop
|
|
|
155
178
|
end
|
|
156
179
|
|
|
157
180
|
def file_checksum(file, config_store)
|
|
181
|
+
stat = File.stat(file)
|
|
182
|
+
return unavailable_checksum unless stat.file?
|
|
183
|
+
|
|
158
184
|
digester = Digest::SHA1.new
|
|
159
|
-
mode
|
|
160
|
-
digester.update("#{file}#{mode}#{config_store.for_file(file).signature}")
|
|
185
|
+
digester.update("#{file}#{stat.mode}#{config_store.for_file(file).signature}")
|
|
161
186
|
digester.file(file)
|
|
162
187
|
digester.hexdigest
|
|
163
188
|
rescue Errno::ENOENT
|
|
164
|
-
# Spurious files that come and go should not cause a crash, at least not
|
|
165
|
-
|
|
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
|
|
166
198
|
'_'
|
|
167
199
|
end
|
|
168
200
|
|
|
169
201
|
class << self
|
|
170
|
-
attr_accessor :
|
|
171
|
-
end
|
|
202
|
+
attr_accessor :inhibit_cleanup
|
|
172
203
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
begin
|
|
204
|
+
# The checksum of the RuboCop program running the inspection.
|
|
205
|
+
def source_checksum
|
|
206
|
+
@source_checksum ||= begin
|
|
177
207
|
digest = Digest::SHA1.new
|
|
178
208
|
rubocop_extra_features
|
|
179
209
|
.select { |path| File.file?(path) }
|
|
@@ -184,42 +214,50 @@ module RuboCop
|
|
|
184
214
|
digest << RuboCop::Version::STRING << RuboCop::AST::Version::STRING
|
|
185
215
|
digest.hexdigest
|
|
186
216
|
end
|
|
187
|
-
|
|
217
|
+
end
|
|
188
218
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
219
|
+
# Return a hash of the options given at invocation, minus the ones that have
|
|
220
|
+
# no effect on which offenses and disabled line ranges are found, and thus
|
|
221
|
+
# don't affect caching.
|
|
222
|
+
def relevant_options_digest(options)
|
|
223
|
+
@relevant_options_digest ||= {}
|
|
224
|
+
@relevant_options_digest[options] ||= begin
|
|
225
|
+
options = options.reject { |key, _| NON_CHANGING.include?(key) }
|
|
226
|
+
options.to_s.gsub(/[^a-z]+/i, '_')
|
|
227
|
+
end
|
|
228
|
+
end
|
|
199
229
|
|
|
200
|
-
|
|
201
|
-
lib_root = File.join(File.dirname(__FILE__), '..')
|
|
202
|
-
exe_root = File.join(lib_root, '..', 'exe')
|
|
230
|
+
private
|
|
203
231
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
232
|
+
def digest(path)
|
|
233
|
+
content = if path.end_with?(*DL_EXTENSIONS)
|
|
234
|
+
# Shared libraries often contain timestamps of when
|
|
235
|
+
# they were compiled and other non-stable data.
|
|
236
|
+
File.basename(path)
|
|
237
|
+
else
|
|
238
|
+
File.binread(path) # mtime not reliable
|
|
239
|
+
end
|
|
240
|
+
Zlib.crc32(content).to_s
|
|
241
|
+
end
|
|
207
242
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
source_files = $LOADED_FEATURES + Find.find(exe_root).to_a
|
|
212
|
-
source_files -= ResultCache.rubocop_required_features # Rely on gem versions
|
|
243
|
+
def rubocop_extra_features
|
|
244
|
+
lib_root = File.join(File.dirname(__FILE__), '..')
|
|
245
|
+
exe_root = File.join(lib_root, '..', 'exe')
|
|
213
246
|
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
# Make sure to use an absolute path to prevent errors on Windows
|
|
248
|
+
# when traversing the relative paths with symlinks.
|
|
249
|
+
exe_root = File.absolute_path(exe_root)
|
|
216
250
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
251
|
+
# These are all the files we have `require`d, all of RuboCop's own files whether loaded
|
|
252
|
+
# or not (cops are loaded lazily, so which of them are in `$LOADED_FEATURES` varies from
|
|
253
|
+
# run to run), plus everything in the exe directory. A change to any of them could affect
|
|
254
|
+
# the cop output so we include them in the cache hash.
|
|
255
|
+
rubocop_lib_files = Dir[File.join(File.absolute_path(lib_root), 'rubocop', '**', '*.rb')]
|
|
256
|
+
source_files = $LOADED_FEATURES | rubocop_lib_files | Find.find(exe_root).to_a
|
|
257
|
+
source_files -= ResultCache.rubocop_required_features # Rely on gem versions
|
|
258
|
+
|
|
259
|
+
source_files
|
|
260
|
+
end
|
|
223
261
|
end
|
|
224
262
|
|
|
225
263
|
# We combine team and options into a single "context" checksum to avoid
|
|
@@ -227,7 +265,7 @@ module RuboCop
|
|
|
227
265
|
# This context is for anything that's not (1) the RuboCop executable
|
|
228
266
|
# checksum or (2) the inspected file checksum.
|
|
229
267
|
def context_checksum(team, options)
|
|
230
|
-
keys = [team.external_dependency_checksum, relevant_options_digest(options)]
|
|
268
|
+
keys = [team.external_dependency_checksum, self.class.relevant_options_digest(options)]
|
|
231
269
|
Digest::SHA1.hexdigest(keys.join)
|
|
232
270
|
end
|
|
233
271
|
end
|
|
@@ -6,13 +6,33 @@ require 'tempfile'
|
|
|
6
6
|
module CopHelper
|
|
7
7
|
extend RSpec::SharedContext
|
|
8
8
|
|
|
9
|
+
@integrated_plugins = false
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
attr_accessor :integrated_plugins
|
|
13
|
+
end
|
|
14
|
+
|
|
9
15
|
let(:ruby_version) do
|
|
10
16
|
# The minimum version Prism can parse is 3.3.
|
|
11
17
|
ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
|
|
12
18
|
end
|
|
13
|
-
let(:parser_engine)
|
|
19
|
+
let(:parser_engine) do
|
|
20
|
+
# The maximum version Parser can correctly parse is 3.3.
|
|
21
|
+
ruby_version >= 3.4 ? :parser_prism : ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym
|
|
22
|
+
end
|
|
14
23
|
let(:rails_version) { false }
|
|
15
24
|
|
|
25
|
+
before(:all) do
|
|
26
|
+
next if ENV['RUBOCOP_CORE_DEVELOPMENT']
|
|
27
|
+
next if CopHelper.integrated_plugins
|
|
28
|
+
|
|
29
|
+
plugins = Gem.loaded_specs.filter_map do |feature_name, feature_specification|
|
|
30
|
+
feature_name if feature_specification.metadata['default_lint_roller_plugin']
|
|
31
|
+
end
|
|
32
|
+
RuboCop::Plugin.integrate_plugins(RuboCop::Config.new, plugins)
|
|
33
|
+
CopHelper.integrated_plugins = true
|
|
34
|
+
end
|
|
35
|
+
|
|
16
36
|
def inspect_source(source, file = nil)
|
|
17
37
|
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
|
|
18
38
|
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
|