sonicop 26.8.112 → 26.9.100
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/Cargo.lock +39 -47
- data/Cargo.toml +7 -7
- data/README.ja.md +36 -23
- data/README.md +38 -26
- data/lib/sonicop/version.rb +1 -1
- data/src/config/inheritance.rs +45 -3
- data/src/engine.rs +11 -7
- data/src/lib.rs +1 -0
- data/src/nul_bytes.rs +2 -6
- data/src/parser.rs +37 -0
- data/src/profile.rs +13 -1
- data/src/rules/bundler/duplicated_group.rs +3 -2
- data/src/rules/bundler/gem_comment.rs +5 -4
- data/src/rules/gemspec/attribute_assignment.rs +4 -3
- data/src/rules/gemspec/deprecated_attribute_assignment.rs +7 -6
- data/src/rules/gemspec/duplicated_assignment.rs +4 -3
- data/src/rules/gemspec/require_mfa.rs +11 -10
- data/src/rules/gemspec/required_ruby_version.rs +3 -2
- data/src/rules/gemspec/support.rs +3 -2
- data/src/rules/layout/access_modifier_indentation.rs +1 -1
- data/src/rules/layout/array_alignment.rs +1 -2
- data/src/rules/layout/block_alignment.rs +1 -1
- data/src/rules/layout/block_end_newline.rs +6 -6
- data/src/rules/layout/class_structure.rs +5 -3
- data/src/rules/layout/closing_heredoc_indentation.rs +4 -3
- data/src/rules/layout/closing_parenthesis_indentation.rs +1 -2
- data/src/rules/layout/condition_position.rs +3 -2
- data/src/rules/layout/def_end_alignment.rs +2 -2
- data/src/rules/layout/dot_position.rs +1 -2
- data/src/rules/layout/empty_line_after_guard_clause.rs +3 -6
- data/src/rules/layout/empty_line_after_multiline_condition.rs +5 -5
- data/src/rules/layout/empty_lines_around_access_modifier.rs +2 -3
- data/src/rules/layout/empty_lines_around_arguments.rs +5 -5
- data/src/rules/layout/empty_lines_around_exception_handling_keywords.rs +2 -3
- data/src/rules/layout/empty_lines_around_method_body.rs +3 -2
- data/src/rules/layout/end_alignment.rs +2 -2
- data/src/rules/layout/extra_spacing.rs +7 -6
- data/src/rules/layout/first_argument_indentation.rs +1 -1
- data/src/rules/layout/first_array_element_indentation.rs +2 -3
- data/src/rules/layout/first_hash_element_indentation.rs +9 -7
- data/src/rules/layout/hash_alignment.rs +4 -4
- data/src/rules/layout/heredoc_argument_closing_parenthesis.rs +7 -6
- data/src/rules/layout/heredoc_indentation.rs +4 -3
- data/src/rules/layout/indentation_style.rs +4 -3
- data/src/rules/layout/indentation_width.rs +15 -14
- data/src/rules/layout/line_continuation_leading_space.rs +4 -3
- data/src/rules/layout/line_continuation_spacing.rs +2 -2
- data/src/rules/layout/line_length.rs +101 -57
- data/src/rules/layout/multiline_assignment_layout.rs +4 -3
- data/src/rules/layout/multiline_block_layout.rs +1 -2
- data/src/rules/layout/multiline_brace.rs +1 -1
- data/src/rules/layout/multiline_expression.rs +62 -33
- data/src/rules/layout/multiline_hash_brace_layout.rs +4 -3
- data/src/rules/layout/multiline_method_call_indentation.rs +1 -1
- data/src/rules/layout/multiline_operation_indentation.rs +3 -3
- data/src/rules/layout/redundant_line_break.rs +3 -2
- data/src/rules/layout/single_line_block_chain.rs +4 -3
- data/src/rules/layout/space_around_block_parameters.rs +1 -2
- data/src/rules/layout/space_around_equals_in_parameter_default.rs +1 -2
- data/src/rules/layout/space_around_operators.rs +1 -2
- data/src/rules/layout/space_before_brackets.rs +6 -5
- data/src/rules/layout/space_before_comma.rs +3 -2
- data/src/rules/layout/space_inside_array_percent_literal.rs +1 -1
- data/src/rules/layout/space_inside_block_braces.rs +1 -1
- data/src/rules/layout/space_inside_hash_literal_braces.rs +1 -1
- data/src/rules/layout/space_inside_percent_literal_delimiters.rs +1 -1
- data/src/rules/layout/space_inside_range_literal.rs +8 -6
- data/src/rules/layout/space_inside_string_interpolation.rs +1 -1
- data/src/rules/layout/support.rs +11 -12
- data/src/rules/layout/tokens.rs +16 -9
- data/src/rules/lint/access_modifier.rs +20 -11
- data/src/rules/lint/ambiguity.rs +2 -2
- data/src/rules/lint/ambiguous_block_association.rs +7 -10
- data/src/rules/lint/ambiguous_regexp_literal.rs +7 -5
- data/src/rules/lint/array_literal_in_regexp.rs +4 -3
- data/src/rules/lint/assignment_in_condition.rs +3 -2
- data/src/rules/lint/blocks.rs +2 -1
- data/src/rules/lint/boolean_symbol.rs +4 -4
- data/src/rules/lint/constant_definition_in_block.rs +1 -2
- data/src/rules/lint/constant_reassignment.rs +2 -1
- data/src/rules/lint/deprecated_open_ssl_constant.rs +1 -2
- data/src/rules/lint/disjunctive_assignment_in_constructor.rs +2 -2
- data/src/rules/lint/duplicate_branch.rs +6 -5
- data/src/rules/lint/duplicate_case_condition.rs +5 -5
- data/src/rules/lint/duplicate_hash_key.rs +4 -3
- data/src/rules/lint/duplicate_match_pattern.rs +7 -5
- data/src/rules/lint/duplicate_methods.rs +4 -3
- data/src/rules/lint/duplicate_require.rs +1 -2
- data/src/rules/lint/duplicate_set_element.rs +3 -2
- data/src/rules/lint/empty_conditional_body.rs +5 -4
- data/src/rules/lint/empty_in_pattern.rs +3 -2
- data/src/rules/lint/empty_when.rs +4 -4
- data/src/rules/lint/ensure_return.rs +3 -2
- data/src/rules/lint/float_comparison.rs +8 -6
- data/src/rules/lint/format_parameter_mismatch.rs +4 -3
- data/src/rules/lint/hash_compare_by_identity.rs +5 -4
- data/src/rules/lint/heredoc_method_call_position.rs +3 -2
- data/src/rules/lint/implicit_string_concatenation.rs +7 -5
- data/src/rules/lint/ineffective_access_modifier.rs +5 -4
- data/src/rules/lint/inherit_exception.rs +4 -3
- data/src/rules/lint/literal_as_condition.rs +5 -3
- data/src/rules/lint/literal_assignment_in_condition.rs +4 -3
- data/src/rules/lint/literal_in_interpolation.rs +7 -7
- data/src/rules/lint/literals.rs +96 -53
- data/src/rules/lint/loop.rs +1 -2
- data/src/rules/lint/nil_receiver.rs +1 -1
- data/src/rules/lint/no_return_in_begin_end_blocks.rs +2 -2
- data/src/rules/lint/node_equality.rs +13 -7
- data/src/rules/lint/non_atomic_file_operation.rs +2 -2
- data/src/rules/lint/non_deterministic_require_order.rs +5 -3
- data/src/rules/lint/non_local_exit_from_iterator.rs +3 -2
- data/src/rules/lint/number_conversion.rs +1 -1
- data/src/rules/lint/out_of_range_regexp_ref.rs +6 -4
- data/src/rules/lint/redundant_dir_glob_sort.rs +1 -2
- data/src/rules/lint/redundant_safe_navigation.rs +4 -3
- data/src/rules/lint/redundant_splat_expansion.rs +4 -2
- data/src/rules/lint/redundant_string_coercion.rs +3 -2
- data/src/rules/lint/regexp.rs +1 -1
- data/src/rules/lint/regexp_source.rs +2 -2
- data/src/rules/lint/require_range_parentheses.rs +5 -5
- data/src/rules/lint/rescue_exception.rs +4 -3
- data/src/rules/lint/rescue_type.rs +3 -2
- data/src/rules/lint/return_in_void_context.rs +2 -2
- data/src/rules/lint/safe_navigation_chain.rs +3 -2
- data/src/rules/lint/self_assignment.rs +3 -2
- data/src/rules/lint/shadowed_argument.rs +2 -2
- data/src/rules/lint/shadowed_exception.rs +2 -2
- data/src/rules/lint/suppressed_exception.rs +1 -1
- data/src/rules/lint/suppressed_exception_in_number_conversion.rs +4 -3
- data/src/rules/lint/symbol_conversion.rs +6 -5
- data/src/rules/lint/syntax.rs +5 -4
- data/src/rules/lint/triple_quotes.rs +3 -2
- data/src/rules/lint/unescaped_bracket_in_regexp.rs +1 -1
- data/src/rules/lint/unexpected_block_arity.rs +3 -2
- data/src/rules/lint/unmodified_reduce_accumulator.rs +7 -6
- data/src/rules/lint/unreachable_loop.rs +27 -11
- data/src/rules/lint/unreachable_pattern_branch.rs +4 -4
- data/src/rules/lint/unused_block_argument.rs +2 -2
- data/src/rules/lint/unused_method_argument.rs +1 -2
- data/src/rules/lint/useless_assignment.rs +3 -2
- data/src/rules/lint/useless_constant_scoping.rs +3 -2
- data/src/rules/lint/useless_else_without_rescue.rs +4 -3
- data/src/rules/lint/useless_rescue.rs +5 -4
- data/src/rules/lint/useless_ruby2_keywords.rs +2 -1
- data/src/rules/lint/useless_setter_call.rs +5 -4
- data/src/rules/lint/useless_times.rs +4 -3
- data/src/rules/lint/variable_force.rs +147 -101
- data/src/rules/lint/void.rs +5 -4
- data/src/rules/metrics/block_nesting.rs +1 -2
- data/src/rules/metrics/collection_literal_length.rs +2 -1
- data/src/rules/metrics/complexity.rs +18 -13
- data/src/rules/metrics/fragments.rs +10 -14
- data/src/rules/metrics/locals.rs +24 -13
- data/src/rules/metrics/parameter_lists.rs +7 -6
- data/src/rules/metrics/support.rs +1 -1
- data/src/rules/mod.rs +543 -62
- data/src/rules/naming/ascii_identifiers.rs +3 -3
- data/src/rules/naming/block_forwarding.rs +9 -8
- data/src/rules/naming/constant_name.rs +1 -1
- data/src/rules/naming/predicate_method.rs +6 -5
- data/src/rules/naming/predicate_prefix.rs +10 -8
- data/src/rules/naming/rescued_exceptions_variable_name.rs +8 -6
- data/src/rules/naming/support.rs +8 -6
- data/src/rules/naming/variable_number.rs +4 -4
- data/src/rules/node_ext.rs +45 -14
- data/src/rules/ruby_literal.rs +3 -2
- data/src/rules/security/compound_hash.rs +3 -2
- data/src/rules/security/open.rs +5 -4
- data/src/rules/send_node.rs +135 -1
- data/src/rules/single_line.rs +4 -4
- data/src/rules/style/access_modifier_declarations.rs +11 -4
- data/src/rules/style/alias.rs +1 -2
- data/src/rules/style/and_or.rs +2 -2
- data/src/rules/style/arguments_forwarding.rs +5 -5
- data/src/rules/style/array_coercion.rs +5 -5
- data/src/rules/style/array_first_last.rs +3 -3
- data/src/rules/style/array_intersect.rs +2 -2
- data/src/rules/style/array_intersect_with_single_element.rs +1 -1
- data/src/rules/style/attr.rs +1 -1
- data/src/rules/style/auto_resource_cleanup.rs +1 -1
- data/src/rules/style/bitwise_predicate.rs +2 -2
- data/src/rules/style/block_args.rs +1 -1
- data/src/rules/style/block_delimiters.rs +7 -6
- data/src/rules/style/case_equality.rs +3 -2
- data/src/rules/style/case_like_if.rs +1 -1
- data/src/rules/style/class_and_module_children.rs +9 -7
- data/src/rules/style/class_methods.rs +1 -1
- data/src/rules/style/collection_compact.rs +4 -4
- data/src/rules/style/combinable_defined.rs +2 -2
- data/src/rules/style/combinable_loops.rs +1 -1
- data/src/rules/style/command_literal.rs +1 -1
- data/src/rules/style/comparable_clamp.rs +2 -2
- data/src/rules/style/concat_array_literals.rs +4 -4
- data/src/rules/style/conditional.rs +8 -1
- data/src/rules/style/conditional_assignment.rs +1 -1
- data/src/rules/style/constant_visibility.rs +3 -3
- data/src/rules/style/copyright.rs +1 -1
- data/src/rules/style/data_inheritance.rs +1 -1
- data/src/rules/style/def_with_parentheses.rs +2 -2
- data/src/rules/style/document_dynamic_eval_definition.rs +1 -1
- data/src/rules/style/documentation.rs +1 -1
- data/src/rules/style/each_for_simple_loop.rs +1 -1
- data/src/rules/style/each_with_object.rs +4 -4
- data/src/rules/style/empty_block_parameter.rs +1 -1
- data/src/rules/style/empty_case_condition.rs +6 -6
- data/src/rules/style/empty_class_definition.rs +1 -1
- data/src/rules/style/empty_else.rs +2 -2
- data/src/rules/style/empty_heredoc.rs +1 -1
- data/src/rules/style/empty_lambda_parameter.rs +1 -1
- data/src/rules/style/empty_literal.rs +2 -2
- data/src/rules/style/empty_method.rs +1 -1
- data/src/rules/style/empty_string_inside_interpolation.rs +1 -1
- data/src/rules/style/endless.rs +1 -1
- data/src/rules/style/env_home.rs +1 -1
- data/src/rules/style/even_odd.rs +1 -1
- data/src/rules/style/exact_regexp_match.rs +1 -1
- data/src/rules/style/expand_path_arguments.rs +3 -3
- data/src/rules/style/explicit_block_argument.rs +3 -3
- data/src/rules/style/file_open_call.rs +3 -3
- data/src/rules/style/file_write.rs +1 -1
- data/src/rules/style/for.rs +1 -1
- data/src/rules/style/format_string.rs +2 -2
- data/src/rules/style/format_string_token.rs +8 -8
- data/src/rules/style/guard_clause.rs +8 -7
- data/src/rules/style/hash_as_last_array_item.rs +5 -5
- data/src/rules/style/hash_conversion.rs +1 -1
- data/src/rules/style/hash_each_methods.rs +1 -1
- data/src/rules/style/hash_fetch_chain.rs +1 -1
- data/src/rules/style/hash_like_case.rs +8 -8
- data/src/rules/style/hash_lookup_method.rs +3 -3
- data/src/rules/style/hash_subset.rs +16 -10
- data/src/rules/style/hash_syntax.rs +4 -4
- data/src/rules/style/hash_transform.rs +20 -18
- data/src/rules/style/identical_conditional_branches.rs +4 -5
- data/src/rules/style/if_inside_else.rs +3 -3
- data/src/rules/style/if_unless_modifier.rs +13 -14
- data/src/rules/style/if_with_boolean_literal_branches.rs +1 -1
- data/src/rules/style/if_with_semicolon.rs +1 -1
- data/src/rules/style/in_pattern_then.rs +2 -2
- data/src/rules/style/infinite_loop.rs +1 -1
- data/src/rules/style/inverse_methods.rs +2 -2
- data/src/rules/style/invertible_unless_condition.rs +3 -3
- data/src/rules/style/it_block_parameter.rs +1 -1
- data/src/rules/style/keyword_arguments_merging.rs +2 -2
- data/src/rules/style/keyword_parameters_order.rs +1 -1
- data/src/rules/style/lambda.rs +1 -1
- data/src/rules/style/literal.rs +2 -2
- data/src/rules/style/magic_comment_format.rs +3 -2
- data/src/rules/style/map_chain.rs +1 -1
- data/src/rules/style/map_compact_with_conditional_block.rs +3 -3
- data/src/rules/style/map_into_array.rs +7 -7
- data/src/rules/style/map_join.rs +3 -3
- data/src/rules/style/method_call_with_args_parentheses.rs +7 -7
- data/src/rules/style/method_call_without_args_parentheses.rs +2 -2
- data/src/rules/style/method_def_parentheses.rs +2 -3
- data/src/rules/style/min_max.rs +3 -3
- data/src/rules/style/min_max_comparison.rs +2 -2
- data/src/rules/style/missing_else.rs +4 -4
- data/src/rules/style/missing_respond_to_missing.rs +1 -1
- data/src/rules/style/mixin_grouping.rs +1 -1
- data/src/rules/style/multiline_block_chain.rs +3 -3
- data/src/rules/style/multiline_if_then.rs +1 -1
- data/src/rules/style/multiline_in_pattern_then.rs +1 -1
- data/src/rules/style/multiline_memoization.rs +1 -1
- data/src/rules/style/multiline_method_signature.rs +1 -1
- data/src/rules/style/multiline_when_then.rs +2 -2
- data/src/rules/style/mutable_constant.rs +3 -3
- data/src/rules/style/negated_if.rs +2 -2
- data/src/rules/style/negated_if_else_condition.rs +2 -2
- data/src/rules/style/negated_while.rs +1 -1
- data/src/rules/style/negative_array_index.rs +2 -2
- data/src/rules/style/nested_modifier.rs +1 -1
- data/src/rules/style/nested_parenthesized_calls.rs +2 -2
- data/src/rules/style/nested_ternary_operator.rs +2 -2
- data/src/rules/style/next.rs +1 -1
- data/src/rules/style/nil_lambda.rs +2 -2
- data/src/rules/style/nodes.rs +21 -0
- data/src/rules/style/non_nil_check.rs +3 -3
- data/src/rules/style/numbered_parameters_limit.rs +2 -2
- data/src/rules/style/one_line_conditional.rs +4 -4
- data/src/rules/style/optional_arguments.rs +1 -1
- data/src/rules/style/or_assignment.rs +1 -1
- data/src/rules/style/parallel_assignment.rs +9 -10
- data/src/rules/style/parens.rs +1 -1
- data/src/rules/style/parentheses_around_condition.rs +3 -3
- data/src/rules/style/partition_instead_of_double_select.rs +3 -3
- data/src/rules/style/percent.rs +10 -8
- data/src/rules/style/percent_array.rs +3 -3
- data/src/rules/style/percent_q_literals.rs +4 -3
- data/src/rules/style/preferred_hash_methods.rs +1 -1
- data/src/rules/style/random_with_offset.rs +1 -1
- data/src/rules/style/reduce_to_hash.rs +6 -6
- data/src/rules/style/redundant_argument.rs +1 -1
- data/src/rules/style/redundant_assignment.rs +5 -5
- data/src/rules/style/redundant_begin.rs +2 -2
- data/src/rules/style/redundant_capital_w.rs +3 -2
- data/src/rules/style/redundant_condition.rs +9 -7
- data/src/rules/style/redundant_current_directory_in_path.rs +2 -2
- data/src/rules/style/redundant_double_splat_hash_braces.rs +4 -4
- data/src/rules/style/redundant_file_extension_in_require.rs +2 -2
- data/src/rules/style/redundant_format.rs +16 -14
- data/src/rules/style/redundant_freeze.rs +1 -1
- data/src/rules/style/redundant_heredoc_delimiter_quotes.rs +1 -1
- data/src/rules/style/redundant_initialize.rs +2 -2
- data/src/rules/style/redundant_interpolation.rs +2 -2
- data/src/rules/style/redundant_interpolation_unfreeze.rs +2 -2
- data/src/rules/style/redundant_line_continuation.rs +5 -4
- data/src/rules/style/redundant_parentheses.rs +16 -15
- data/src/rules/style/redundant_regexp_argument.rs +1 -1
- data/src/rules/style/redundant_regexp_character_class.rs +5 -4
- data/src/rules/style/redundant_regexp_constructor.rs +1 -1
- data/src/rules/style/redundant_regexp_escape.rs +4 -3
- data/src/rules/style/redundant_return.rs +1 -2
- data/src/rules/style/redundant_self.rs +11 -11
- data/src/rules/style/redundant_sort.rs +1 -1
- data/src/rules/style/redundant_sort_by.rs +1 -1
- data/src/rules/style/redundant_string_escape.rs +6 -5
- data/src/rules/style/regexp_literal.rs +4 -3
- data/src/rules/style/require_order.rs +8 -4
- data/src/rules/style/rescue_modifier.rs +1 -1
- data/src/rules/style/rescue_standard_error.rs +1 -1
- data/src/rules/style/return_nil.rs +2 -2
- data/src/rules/style/return_nil_in_predicate_method_definition.rs +2 -2
- data/src/rules/style/safe_navigation.rs +2 -2
- data/src/rules/style/sample.rs +3 -3
- data/src/rules/style/select_by.rs +2 -2
- data/src/rules/style/select_by_range.rs +1 -1
- data/src/rules/style/semicolon.rs +5 -4
- data/src/rules/style/single_argument_dig.rs +1 -1
- data/src/rules/style/single_line_block_params.rs +7 -6
- data/src/rules/style/single_line_do_end_block.rs +13 -12
- data/src/rules/style/single_line_methods.rs +3 -3
- data/src/rules/style/slicing_with_range.rs +2 -2
- data/src/rules/style/sole_nested_conditional.rs +4 -4
- data/src/rules/style/special_global_vars.rs +2 -2
- data/src/rules/style/stabby_lambda_parentheses.rs +1 -1
- data/src/rules/style/statement_modifier.rs +3 -2
- data/src/rules/style/static_class.rs +1 -1
- data/src/rules/style/string_concatenation.rs +11 -9
- data/src/rules/style/string_hash_keys.rs +3 -2
- data/src/rules/style/string_literals.rs +3 -3
- data/src/rules/style/string_literals_in_interpolation.rs +1 -1
- data/src/rules/style/struct_inheritance.rs +4 -4
- data/src/rules/style/super_arguments.rs +2 -2
- data/src/rules/style/super_with_args_parentheses.rs +1 -1
- data/src/rules/style/swap_values.rs +1 -1
- data/src/rules/style/symbol_array.rs +1 -1
- data/src/rules/style/symbol_proc.rs +3 -3
- data/src/rules/style/tally_method.rs +4 -4
- data/src/rules/style/ternary_parentheses.rs +4 -4
- data/src/rules/style/top_level_method_definition.rs +1 -1
- data/src/rules/style/trailing_body.rs +1 -1
- data/src/rules/style/trailing_body_on_method_definition.rs +1 -1
- data/src/rules/style/trailing_comma.rs +1 -1
- data/src/rules/style/trailing_comma_in_array_literal.rs +1 -1
- data/src/rules/style/trailing_comma_in_hash_literal.rs +1 -1
- data/src/rules/style/trailing_method_end_statement.rs +2 -2
- data/src/rules/style/trailing_underscore_variable.rs +4 -5
- data/src/rules/style/trivial_accessors.rs +2 -2
- data/src/rules/style/unless_logical_operators.rs +1 -1
- data/src/rules/style/unpack_first.rs +1 -1
- data/src/rules/style/when_then.rs +4 -4
- data/src/rules/style/while_until_do.rs +1 -1
- data/src/rules/style/while_until_modifier.rs +3 -3
- data/src/rules/style/word_array.rs +3 -3
- data/src/rules/style/yoda_condition.rs +2 -2
- data/src/rules/support.rs +33 -8
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a163c5bd6a8d400159bd4ba0f973dffb08ec9a588554d11ba4d1240962b7f4ed
|
|
4
|
+
data.tar.gz: 23e90583b4aafc8fbe66ecee0202d0fedddf45ed75d90e6060a7d5fb77345343
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0cb9a7320c8bbbe4b3fa3d773486cf66460bc5f29eb43161226dd195566210ec7cab52757c4543a01a6d9f127e0508bcb3ccb9c1ddcd95dbc6908678a202115a
|
|
7
|
+
data.tar.gz: faa62e145f9d96b10db86cf60a9a565a3c6033b8a4b28c994ecb76d99a1a4e8e79ed30775a85e1b512988117901f7b9ddb3ff19e9a8e9d116e34125a0eed03f2
|
data/Cargo.lock
CHANGED
|
@@ -67,12 +67,6 @@ version = "1.0.104"
|
|
|
67
67
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
68
68
|
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
|
69
69
|
|
|
70
|
-
[[package]]
|
|
71
|
-
name = "arrayref"
|
|
72
|
-
version = "0.3.9"
|
|
73
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
-
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
|
75
|
-
|
|
76
70
|
[[package]]
|
|
77
71
|
name = "arrayvec"
|
|
78
72
|
version = "0.7.8"
|
|
@@ -114,11 +108,10 @@ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
|
|
114
108
|
|
|
115
109
|
[[package]]
|
|
116
110
|
name = "blake3"
|
|
117
|
-
version = "1.8.
|
|
111
|
+
version = "1.8.7"
|
|
118
112
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
119
|
-
checksum = "
|
|
113
|
+
checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae"
|
|
120
114
|
dependencies = [
|
|
121
|
-
"arrayref",
|
|
122
115
|
"arrayvec",
|
|
123
116
|
"cc",
|
|
124
117
|
"cfg-if",
|
|
@@ -128,9 +121,9 @@ dependencies = [
|
|
|
128
121
|
|
|
129
122
|
[[package]]
|
|
130
123
|
name = "bstr"
|
|
131
|
-
version = "1.13.
|
|
124
|
+
version = "1.13.1"
|
|
132
125
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
133
|
-
checksum = "
|
|
126
|
+
checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f"
|
|
134
127
|
dependencies = [
|
|
135
128
|
"memchr",
|
|
136
129
|
"regex-automata",
|
|
@@ -145,9 +138,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
|
|
145
138
|
|
|
146
139
|
[[package]]
|
|
147
140
|
name = "cc"
|
|
148
|
-
version = "1.4.
|
|
141
|
+
version = "1.4.5"
|
|
149
142
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
150
|
-
checksum = "
|
|
143
|
+
checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80"
|
|
151
144
|
dependencies = [
|
|
152
145
|
"find-msvc-tools",
|
|
153
146
|
"shlex",
|
|
@@ -191,7 +184,7 @@ dependencies = [
|
|
|
191
184
|
"heck",
|
|
192
185
|
"proc-macro2",
|
|
193
186
|
"quote",
|
|
194
|
-
"syn 3.0.
|
|
187
|
+
"syn 3.0.5",
|
|
195
188
|
]
|
|
196
189
|
|
|
197
190
|
[[package]]
|
|
@@ -230,18 +223,18 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|
|
230
223
|
|
|
231
224
|
[[package]]
|
|
232
225
|
name = "cpufeatures"
|
|
233
|
-
version = "0.3.
|
|
226
|
+
version = "0.3.1"
|
|
234
227
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
235
|
-
checksum = "
|
|
228
|
+
checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
|
|
236
229
|
dependencies = [
|
|
237
230
|
"libc",
|
|
238
231
|
]
|
|
239
232
|
|
|
240
233
|
[[package]]
|
|
241
234
|
name = "crossbeam-deque"
|
|
242
|
-
version = "0.8.
|
|
235
|
+
version = "0.8.8"
|
|
243
236
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
244
|
-
checksum = "
|
|
237
|
+
checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a"
|
|
245
238
|
dependencies = [
|
|
246
239
|
"crossbeam-epoch",
|
|
247
240
|
"crossbeam-utils",
|
|
@@ -249,24 +242,24 @@ dependencies = [
|
|
|
249
242
|
|
|
250
243
|
[[package]]
|
|
251
244
|
name = "crossbeam-epoch"
|
|
252
|
-
version = "0.9.
|
|
245
|
+
version = "0.9.21"
|
|
253
246
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
254
|
-
checksum = "
|
|
247
|
+
checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d"
|
|
255
248
|
dependencies = [
|
|
256
249
|
"crossbeam-utils",
|
|
257
250
|
]
|
|
258
251
|
|
|
259
252
|
[[package]]
|
|
260
253
|
name = "crossbeam-utils"
|
|
261
|
-
version = "0.8.
|
|
254
|
+
version = "0.8.23"
|
|
262
255
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
263
|
-
checksum = "
|
|
256
|
+
checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6"
|
|
264
257
|
|
|
265
258
|
[[package]]
|
|
266
259
|
name = "der"
|
|
267
|
-
version = "0.8.
|
|
260
|
+
version = "0.8.2"
|
|
268
261
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
269
|
-
checksum = "
|
|
262
|
+
checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a"
|
|
270
263
|
dependencies = [
|
|
271
264
|
"pem-rfc7468",
|
|
272
265
|
"zeroize",
|
|
@@ -280,9 +273,9 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
|
|
280
273
|
|
|
281
274
|
[[package]]
|
|
282
275
|
name = "either"
|
|
283
|
-
version = "1.
|
|
276
|
+
version = "1.18.0"
|
|
284
277
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
285
|
-
checksum = "
|
|
278
|
+
checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
|
|
286
279
|
|
|
287
280
|
[[package]]
|
|
288
281
|
name = "encoding_rs"
|
|
@@ -317,9 +310,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
|
|
317
310
|
|
|
318
311
|
[[package]]
|
|
319
312
|
name = "find-msvc-tools"
|
|
320
|
-
version = "0.1.
|
|
313
|
+
version = "0.1.12"
|
|
321
314
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
322
|
-
checksum = "
|
|
315
|
+
checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d"
|
|
323
316
|
|
|
324
317
|
[[package]]
|
|
325
318
|
name = "foreign-types"
|
|
@@ -416,9 +409,9 @@ dependencies = [
|
|
|
416
409
|
|
|
417
410
|
[[package]]
|
|
418
411
|
name = "indexmap"
|
|
419
|
-
version = "2.14.
|
|
412
|
+
version = "2.14.2"
|
|
420
413
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
421
|
-
checksum = "
|
|
414
|
+
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
|
422
415
|
dependencies = [
|
|
423
416
|
"equivalent",
|
|
424
417
|
"hashbrown",
|
|
@@ -450,9 +443,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
|
|
450
443
|
|
|
451
444
|
[[package]]
|
|
452
445
|
name = "log"
|
|
453
|
-
version = "0.4.
|
|
446
|
+
version = "0.4.34"
|
|
454
447
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
455
|
-
checksum = "
|
|
448
|
+
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
|
456
449
|
|
|
457
450
|
[[package]]
|
|
458
451
|
name = "memchr"
|
|
@@ -549,9 +542,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|
|
549
542
|
|
|
550
543
|
[[package]]
|
|
551
544
|
name = "pkg-config"
|
|
552
|
-
version = "0.3.
|
|
545
|
+
version = "0.3.34"
|
|
553
546
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
554
|
-
checksum = "
|
|
547
|
+
checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
|
|
555
548
|
|
|
556
549
|
[[package]]
|
|
557
550
|
name = "predicates"
|
|
@@ -749,7 +742,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
|
749
742
|
dependencies = [
|
|
750
743
|
"proc-macro2",
|
|
751
744
|
"quote",
|
|
752
|
-
"syn 3.0.
|
|
745
|
+
"syn 3.0.5",
|
|
753
746
|
]
|
|
754
747
|
|
|
755
748
|
[[package]]
|
|
@@ -793,7 +786,7 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
|
793
786
|
|
|
794
787
|
[[package]]
|
|
795
788
|
name = "sonicop"
|
|
796
|
-
version = "26.
|
|
789
|
+
version = "26.9.100"
|
|
797
790
|
dependencies = [
|
|
798
791
|
"anyhow",
|
|
799
792
|
"assert_cmd",
|
|
@@ -840,9 +833,9 @@ dependencies = [
|
|
|
840
833
|
|
|
841
834
|
[[package]]
|
|
842
835
|
name = "syn"
|
|
843
|
-
version = "3.0.
|
|
836
|
+
version = "3.0.5"
|
|
844
837
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
845
|
-
checksum = "
|
|
838
|
+
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
|
846
839
|
dependencies = [
|
|
847
840
|
"proc-macro2",
|
|
848
841
|
"quote",
|
|
@@ -880,13 +873,12 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
|
|
|
880
873
|
|
|
881
874
|
[[package]]
|
|
882
875
|
name = "tree-sitter"
|
|
883
|
-
version = "0.
|
|
876
|
+
version = "0.27.0"
|
|
884
877
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
885
|
-
checksum = "
|
|
878
|
+
checksum = "2038684e0058edba0d17302619f62eabce4a8e11c6ac59506996a8d79848851d"
|
|
886
879
|
dependencies = [
|
|
887
880
|
"cc",
|
|
888
881
|
"regex",
|
|
889
|
-
"regex-syntax",
|
|
890
882
|
"serde_json",
|
|
891
883
|
"streaming-iterator",
|
|
892
884
|
"tree-sitter-language",
|
|
@@ -894,9 +886,9 @@ dependencies = [
|
|
|
894
886
|
|
|
895
887
|
[[package]]
|
|
896
888
|
name = "tree-sitter-language"
|
|
897
|
-
version = "0.1.
|
|
889
|
+
version = "0.1.8"
|
|
898
890
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
899
|
-
checksum = "
|
|
891
|
+
checksum = "ca0d1bf6fdd806e43ae5198f82f527056d359def39e54e67a0f478ac09dac081"
|
|
900
892
|
|
|
901
893
|
[[package]]
|
|
902
894
|
name = "tree-sitter-ruby"
|
|
@@ -921,9 +913,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
|
|
921
913
|
|
|
922
914
|
[[package]]
|
|
923
915
|
name = "ureq"
|
|
924
|
-
version = "3.4.
|
|
916
|
+
version = "3.4.1"
|
|
925
917
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
926
|
-
checksum = "
|
|
918
|
+
checksum = "af5546be8f5378d5414f83733f5c9a2526f4645829edbc1c41790aeef1b38e8b"
|
|
927
919
|
dependencies = [
|
|
928
920
|
"base64",
|
|
929
921
|
"der",
|
|
@@ -938,9 +930,9 @@ dependencies = [
|
|
|
938
930
|
|
|
939
931
|
[[package]]
|
|
940
932
|
name = "ureq-proto"
|
|
941
|
-
version = "0.6.
|
|
933
|
+
version = "0.6.2"
|
|
942
934
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
943
|
-
checksum = "
|
|
935
|
+
checksum = "fabc3e92916c89c95b20eef7b06b00b066bc217ef9ea3a4ac9bf1a7e35261e10"
|
|
944
936
|
dependencies = [
|
|
945
937
|
"base64",
|
|
946
938
|
"http",
|
data/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "sonicop"
|
|
3
|
-
version = "26.
|
|
3
|
+
version = "26.9.100"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.85"
|
|
6
6
|
description = "A fast, native RuboCop-compatible Ruby linter and formatter"
|
|
@@ -16,7 +16,7 @@ path = "src/main.rs"
|
|
|
16
16
|
|
|
17
17
|
[dependencies]
|
|
18
18
|
anyhow = "1.0.104"
|
|
19
|
-
blake3 = "1.8.
|
|
19
|
+
blake3 = "1.8.7"
|
|
20
20
|
clap = { version = "4.6.6", features = ["derive", "wrap_help"] }
|
|
21
21
|
encoding_rs = "0.8.35"
|
|
22
22
|
fs2 = "0.4.3"
|
|
@@ -29,23 +29,23 @@ serde_json = "1.0.151"
|
|
|
29
29
|
serde_yaml_ng = "0.10"
|
|
30
30
|
shell-words = "1.1.1"
|
|
31
31
|
tempfile = "3.27.0"
|
|
32
|
-
tree-sitter = "0.
|
|
32
|
+
tree-sitter = "0.27.0"
|
|
33
33
|
tree-sitter-ruby = { git = "https://github.com/owayo/tree-sitter-ruby.git", tag = "v26.8.103" }
|
|
34
|
-
ureq = { version = "3.4", default-features = false, features = ["native-tls"] }
|
|
34
|
+
ureq = { version = "3.4.1", default-features = false, features = ["native-tls"] }
|
|
35
35
|
|
|
36
36
|
[dev-dependencies]
|
|
37
37
|
assert_cmd = "2.2.2"
|
|
38
38
|
|
|
39
39
|
[build-dependencies]
|
|
40
|
-
blake3 = "1.8.
|
|
40
|
+
blake3 = "1.8.7"
|
|
41
41
|
|
|
42
42
|
[profile.release]
|
|
43
43
|
lto = "thin"
|
|
44
44
|
codegen-units = 1
|
|
45
45
|
strip = true
|
|
46
46
|
|
|
47
|
-
# `cargo build --profile profiling`
|
|
48
|
-
#
|
|
47
|
+
# `cargo build --profile profiling` はサンプリングプロファイラ用のシンボルを残しつつ、
|
|
48
|
+
# `--release` と同じ最適化コードを生成する。
|
|
49
49
|
[profile.profiling]
|
|
50
50
|
inherits = "release"
|
|
51
51
|
debug = 1
|
data/README.ja.md
CHANGED
|
@@ -153,6 +153,8 @@ sonicop --show-cops
|
|
|
153
153
|
`AllCops/DisabledByDefault`、`Include`/`Exclude`、Cop ごとの `Enabled`、`Exclude`、
|
|
154
154
|
`Severity`、`Safe`、`SafeAutoCorrect` と設定値に対応します。宣言されたプラグイン由来の
|
|
155
155
|
Cop は「認識済み・未実装」として受理し、Ruby プラグインコード自体は実行しません。
|
|
156
|
+
リモート設定のリクエストには 30 秒のネットワークタイムアウトを設け、応答は 1 件あたり
|
|
157
|
+
5 MiB に制限します。
|
|
156
158
|
|
|
157
159
|
```yaml
|
|
158
160
|
inherit_from: .rubocop_todo.yml
|
|
@@ -229,52 +231,63 @@ autocorrect は RuboCop 自身のツリーと Mastodon でバイト単位に一
|
|
|
229
231
|
既定の実行はどちらの群にも届きません。)
|
|
230
232
|
各値は暖機後 2 回の最速値です。
|
|
231
233
|
|
|
232
|
-
| コーパス | ファイル | RuboCop 並列 | Sonicop 並列 | RuboCop 単一 | Sonicop 単一 |
|
|
233
|
-
|
|
234
|
-
| rubocop/rubocop | 1,
|
|
235
|
-
| mastodon/mastodon | 3,
|
|
236
|
-
| Homebrew/brew | 2,
|
|
237
|
-
| rails/rails | 3,
|
|
238
|
-
| ruby/ruby | 7,
|
|
234
|
+
| コーパス | ファイル | offense | RuboCop 並列 | Sonicop 並列 | RuboCop 単一 | Sonicop 単一 |
|
|
235
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
236
|
+
| rubocop/rubocop | 1,780 | 5,826 | 10.85 秒 | **1.53 秒** | 41.44 秒 | **8.96 秒** |
|
|
237
|
+
| mastodon/mastodon | 3,292 | 15,293 | 22.59 秒 | **3.04 秒** | 34.74 秒 | **6.86 秒** |
|
|
238
|
+
| Homebrew/brew | 2,296 | 51,527 | 13.56 秒 | **2.21 秒** | 40.36 秒 | **6.51 秒** |
|
|
239
|
+
| rails/rails | 3,562 | 168,615 | 32.90 秒 | **8.84 秒** | 85.71 秒 | **19.17 秒** |
|
|
240
|
+
| ruby/ruby | 7,477 | 765,975 | 86.89 秒 | **15.59 秒** | 193.59 秒 | **37.98 秒** |
|
|
239
241
|
|
|
240
|
-
差は並列で
|
|
242
|
+
差は並列で 3.7〜7.4 倍、単一プロセスで 4.5〜6.2 倍と幅があり、1 コーパスでは代表できません。
|
|
241
243
|
**単一プロセスの列を読み、並列は目安として扱ってください。** 同じ 2 つのバイナリを 1 日に
|
|
242
244
|
3 回測ったところ、単一プロセスの値は毎回 16% 以内に収まったのに対し、RuboCop 自身のツリーでの
|
|
243
245
|
並列の倍率は、マシンが他に何をしていたかだけで 3.3 倍から 9.2 倍まで動きました。単一プロセスは
|
|
244
246
|
エンジンを測っていますが、並列はエンジンに加えて「その実行でスケジューリングがそのツリーに
|
|
245
247
|
どれだけ噛み合ったか」を測っています。
|
|
246
248
|
|
|
247
|
-
仕事を省いて速いわけではありません。この同じ 394 Cop
|
|
248
|
-
|
|
249
|
-
|
|
249
|
+
仕事を省いて速いわけではありません。この同じ 394 Cop について、表のどのコーパスでも
|
|
250
|
+
**offense の総数が一致**し、RuboCop 自身のツリーと Mastodon ではその 1 件ずつが同じ位置・
|
|
251
|
+
同じメッセージ・同じ severity です。Rails は 168,615 件のうち 2 件だけ食い違います
|
|
252
|
+
(Sonicop が出す `Style/CaseLikeIf` 1 件と、出さない `Metrics/AbcSize` 1 件)。
|
|
253
|
+
RuboCop 自身のツリーでは 1 件の `correctable` フラグが違います。
|
|
254
|
+
autocorrect は前者と後者でバイト単位に一致します。
|
|
250
255
|
|
|
251
|
-
再現時に注意が必要な点が
|
|
256
|
+
再現時に注意が必要な点が 4 つあります。RuboCop は **`--cache false` と併用すると
|
|
252
257
|
`--parallel` を黙って無効化します**。そのためここでの並列実行はキャッシュを有効にしたうえで
|
|
253
258
|
実行ごとにキャッシュディレクトリを消しており、`--cache false --parallel` で計測すると
|
|
254
259
|
単一プロセスを測ることになり差が過大に出ます。また RuboCop の既定は単一プロセス、
|
|
255
260
|
Sonicop は `--no-parallel` を渡さない限り並列です。そして**両方ともキャッシュを空にする**
|
|
256
261
|
必要があります。Sonicop も既定でキャッシュするため、同じツリーを 2 回目に流すと自分の
|
|
257
262
|
キャッシュが答えてしまい、エンジンについては何も測れません。どちらにも使い捨ての
|
|
258
|
-
|
|
263
|
+
キャッシュディレクトリを渡してください。最後に、そのキャッシュディレクトリは**実パス**である
|
|
264
|
+
必要があります。macOS の `mktemp -d` は `/var/folders/…` を返し、その `/var` は symlink なので
|
|
265
|
+
RuboCop はそこを拒み、キャッシュ無しで走ってしまいます。
|
|
259
266
|
|
|
260
267
|
```bash
|
|
261
268
|
# RuboCop(並列・キャッシュは毎回空・既定の全 394 Cop)
|
|
262
|
-
|
|
269
|
+
root=$(mktemp -d /private/tmp/bench.XXXXXX)
|
|
270
|
+
rubocop --force-default-config --cache true --cache-root "$root" \
|
|
263
271
|
--no-color --parallel -f quiet
|
|
264
272
|
|
|
265
273
|
# Sonicop(キャッシュは毎回空)
|
|
266
|
-
sonicop --force-default-config --cache-root "$
|
|
274
|
+
sonicop --force-default-config --cache-root "$root" --format quiet
|
|
267
275
|
```
|
|
268
276
|
|
|
277
|
+
キャッシュの書き込みもこの数値に含まれており、無料ではありません。索引は全 offense を
|
|
278
|
+
「見つかった行のテキスト」付きで保持するため、`ruby/ruby` では 336 MB になります。
|
|
279
|
+
2 回目の実行(キャッシュ命中)は `ruby/ruby` で 1.59 秒、Rails で 0.42 秒です。
|
|
280
|
+
|
|
269
281
|
測定機は Apple M2(8 コア)、Ruby 4.0.6(YJIT 利用可)、RubyGems 導入の RuboCop 1.89.0。
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
282
|
+
2026-08-31 に、`rubocop_rubocop` 2693129 / `mastodon_mastodon` b59ddc7 / `Homebrew_brew` b42173b /
|
|
283
|
+
`rails_rails` a19f07f / `ruby_ruby` 22e4a75 の各リビジョンに対して測定しました。
|
|
284
|
+
1 分平均のロードアベレージは各行の測定時点で 4.5〜7.1 で、その大半は RuboCop 自身の並列
|
|
285
|
+
ワーカーです(計測する以上避けられません)。**アイドル状態ではありません。**
|
|
286
|
+
各コーパスで両者を連続して同じ条件で測っているため倍率は保たれますが、秒数そのものは下限ではなく、
|
|
287
|
+
静かなマシンならより速く出ます。コアを奪い合うものが動いていると両者とも膨らみ、その度合いは
|
|
288
|
+
一致しません。それが並列の列があれだけ動く理由です。秒数そのものが重要なときは、他に負荷のない
|
|
289
|
+
状態で測り、**実行の前後でロードアベレージを記録してください** — その情報が無い数値は、
|
|
290
|
+
別の数値と比べられません。
|
|
278
291
|
|
|
279
292
|
## 開発
|
|
280
293
|
|
data/README.md
CHANGED
|
@@ -160,6 +160,8 @@ run. Local and HTTPS `inherit_from`, `inherit_gem`, `inherit_mode`,
|
|
|
160
160
|
`AllCops/DisabledByDefault`, `Include`, and `Exclude`, plus per-cop `Enabled`, `Exclude`,
|
|
161
161
|
`Severity`, `Safe`, `SafeAutoCorrect`, and cop settings are supported. Cops supplied by declared
|
|
162
162
|
plugins are accepted as recognized-but-unimplemented without executing Ruby plugin code.
|
|
163
|
+
Remote configuration requests use 30-second network timeouts, and each response is limited to
|
|
164
|
+
5 MiB.
|
|
163
165
|
|
|
164
166
|
```yaml
|
|
165
167
|
inherit_from: .rubocop_todo.yml
|
|
@@ -240,52 +242,62 @@ once the 159 RuboCop ships as `Enabled: pending` and the 56 it ships as `Enabled
|
|
|
240
242
|
aside; a default run reaches neither group on either side.) Times are the fastest of two
|
|
241
243
|
warmed runs.
|
|
242
244
|
|
|
243
|
-
| Corpus | Files | RuboCop parallel | Sonicop parallel | RuboCop single | Sonicop single |
|
|
244
|
-
|
|
245
|
-
| rubocop/rubocop | 1,
|
|
246
|
-
| mastodon/mastodon | 3,
|
|
247
|
-
| Homebrew/brew | 2,
|
|
248
|
-
| rails/rails | 3,
|
|
249
|
-
| ruby/ruby | 7,
|
|
245
|
+
| Corpus | Files | Offenses | RuboCop parallel | Sonicop parallel | RuboCop single | Sonicop single |
|
|
246
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
247
|
+
| rubocop/rubocop | 1,780 | 5,826 | 10.85 s | **1.53 s** | 41.44 s | **8.96 s** |
|
|
248
|
+
| mastodon/mastodon | 3,292 | 15,293 | 22.59 s | **3.04 s** | 34.74 s | **6.86 s** |
|
|
249
|
+
| Homebrew/brew | 2,296 | 51,527 | 13.56 s | **2.21 s** | 40.36 s | **6.51 s** |
|
|
250
|
+
| rails/rails | 3,562 | 168,615 | 32.90 s | **8.84 s** | 85.71 s | **19.17 s** |
|
|
251
|
+
| ruby/ruby | 7,477 | 765,975 | 86.89 s | **15.59 s** | 193.59 s | **37.98 s** |
|
|
250
252
|
|
|
251
|
-
The gap is
|
|
253
|
+
The gap is 3.7x to 7.4x in parallel and 4.5x to 6.2x single-process, so no single corpus summarizes
|
|
252
254
|
it. **Read the single-process column and treat the parallel one as indicative.** Measuring the same
|
|
253
255
|
two binaries three times over a day put the single-process figures within 16% of each other every
|
|
254
256
|
time, while the parallel ratio on RuboCop's own tree moved between 3.3x and 9.2x purely with what
|
|
255
257
|
else the machine was doing. Single-process measures the engines; parallel measures the engines plus
|
|
256
258
|
how well each one's scheduling happens to fit that tree on that run.
|
|
257
259
|
|
|
258
|
-
The speed is not bought by skipping work
|
|
259
|
-
on
|
|
260
|
-
|
|
260
|
+
The speed is not bought by skipping work. Over those same 394 cops the two find the **same number of
|
|
261
|
+
offenses** on every corpus in the table, and on RuboCop's own tree and on Mastodon every one of them
|
|
262
|
+
is at the same position with the same message and severity. Rails, at 168,615 offenses, differs in
|
|
263
|
+
two of them — one `Style/CaseLikeIf` Sonicop reports and one `Metrics/AbcSize` it does not — and
|
|
264
|
+
RuboCop's own tree differs in one offense's `correctable` flag. Autocorrect is byte-identical on the
|
|
265
|
+
first and the last.
|
|
261
266
|
|
|
262
|
-
|
|
267
|
+
Four details matter for reproducing this. RuboCop **silently turns `--parallel` off when combined
|
|
263
268
|
with `--cache false`**, so its parallel runs here use a cache directory that is deleted before each
|
|
264
269
|
run rather than disabled; timing it with `--cache false --parallel` measures a single process and
|
|
265
270
|
overstates the difference. RuboCop's default is a single process, while Sonicop is parallel unless
|
|
266
|
-
`--no-parallel` is passed.
|
|
267
|
-
second run over the same tree answers from its own cache and measures nothing about the engine
|
|
268
|
-
|
|
271
|
+
`--no-parallel` is passed. Both sides need a **cold** cache: Sonicop caches by default too, so a
|
|
272
|
+
second run over the same tree answers from its own cache and measures nothing about the engine —
|
|
273
|
+
give each tool a throwaway cache root. And the cache root must be a **real path**: macOS `mktemp -d`
|
|
274
|
+
returns `/var/folders/…`, whose `/var` is a symlink, and RuboCop refuses such a location and runs
|
|
275
|
+
with no cache at all.
|
|
269
276
|
|
|
270
277
|
```bash
|
|
271
278
|
# RuboCop, parallel, cold cache, its full default set of 394 cops
|
|
272
|
-
|
|
279
|
+
root=$(mktemp -d /private/tmp/bench.XXXXXX)
|
|
280
|
+
rubocop --force-default-config --cache true --cache-root "$root" \
|
|
273
281
|
--no-color --parallel -f quiet
|
|
274
282
|
|
|
275
283
|
# Sonicop, cold cache
|
|
276
|
-
sonicop --force-default-config --cache-root "$
|
|
284
|
+
sonicop --force-default-config --cache-root "$root" --format quiet
|
|
277
285
|
```
|
|
278
286
|
|
|
287
|
+
Writing the cache is part of these numbers, and it is not free: the index holds every offense with
|
|
288
|
+
the source line it was found on, which is 336 MB over `ruby/ruby`. A second run against a warm cache
|
|
289
|
+
answers in 1.59 s there, and in 0.42 s over Rails.
|
|
290
|
+
|
|
279
291
|
Machine: Apple M2 (8 cores), Ruby 4.0.6 with YJIT available, RubyGems-installed RuboCop 1.89.0.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
292
|
+
Measured on 2026-08-31 against the corpora at `rubocop_rubocop` 2693129, `mastodon_mastodon` b59ddc7,
|
|
293
|
+
`Homebrew_brew` b42173b, `rails_rails` a19f07f and `ruby_ruby` 22e4a75. The one-minute load average
|
|
294
|
+
was between 4.5 and 7.1 as each row was taken — most of it RuboCop's own parallel workers, which is
|
|
295
|
+
inherent to measuring them. **The machine was in use, not idle.** Both tools ran back to back under
|
|
296
|
+
the same conditions on each corpus, so the ratios hold, but the absolute seconds are not a floor:
|
|
297
|
+
expect better on a quiet machine. Anything competing for cores inflates both sides, and not by the
|
|
298
|
+
same factor on each, which is what makes the parallel column move as much as it does. If the
|
|
299
|
+
absolute numbers matter to you, measure on an idle machine and record the load either side of the
|
|
300
|
+
run — a figure without that context cannot be compared with another one.
|
|
289
301
|
|
|
290
302
|
## Development
|
|
291
303
|
|
data/lib/sonicop/version.rb
CHANGED
data/src/config/inheritance.rs
CHANGED
|
@@ -8,6 +8,8 @@ use std::time::Duration;
|
|
|
8
8
|
use anyhow::{Context, Result, bail};
|
|
9
9
|
use serde_yaml_ng::{Mapping, Value};
|
|
10
10
|
|
|
11
|
+
const MAX_REMOTE_CONFIG_BYTES: u64 = 5 * 1024 * 1024;
|
|
12
|
+
|
|
11
13
|
/// Configuration files whose inheritance has already been resolved, keyed by canonical path for
|
|
12
14
|
/// local files and by URL for remote ones.
|
|
13
15
|
///
|
|
@@ -164,7 +166,8 @@ fn fetch_remote_config(url: &str) -> Result<String> {
|
|
|
164
166
|
response
|
|
165
167
|
.body_mut()
|
|
166
168
|
.with_config()
|
|
167
|
-
|
|
169
|
+
// ureq は指定値と同じ長さでも上限超過にするため、論理上限を含む 1 バイト先を渡す。
|
|
170
|
+
.limit(MAX_REMOTE_CONFIG_BYTES + 1)
|
|
168
171
|
.read_to_string()
|
|
169
172
|
.with_context(|| format!("failed to read remote configuration: {url}"))
|
|
170
173
|
}
|
|
@@ -459,14 +462,17 @@ fn mode_keys(mode: &Value, name: &str) -> HashSet<String> {
|
|
|
459
462
|
mod tests {
|
|
460
463
|
use std::collections::HashSet;
|
|
461
464
|
use std::fs;
|
|
465
|
+
use std::io::{Read, Write};
|
|
466
|
+
use std::net::TcpListener;
|
|
462
467
|
use std::path::Path;
|
|
468
|
+
use std::thread;
|
|
463
469
|
|
|
464
470
|
use serde_yaml_ng::Value;
|
|
465
471
|
use tempfile::tempdir;
|
|
466
472
|
|
|
467
473
|
use super::{
|
|
468
|
-
InheritMode, PARSED_CONFIG_COUNT, deep_merge,
|
|
469
|
-
merge_config, merge_inherited_config,
|
|
474
|
+
InheritMode, MAX_REMOTE_CONFIG_BYTES, PARSED_CONFIG_COUNT, deep_merge, fetch_remote_config,
|
|
475
|
+
join_remote_url, load_with_inheritance, merge_config, merge_inherited_config,
|
|
470
476
|
};
|
|
471
477
|
use crate::config::Config;
|
|
472
478
|
|
|
@@ -483,6 +489,24 @@ mod tests {
|
|
|
483
489
|
load_with_inheritance(path, &mut HashSet::new())
|
|
484
490
|
}
|
|
485
491
|
|
|
492
|
+
fn serve_once(body: Vec<u8>) -> (String, thread::JoinHandle<()>) {
|
|
493
|
+
let listener = TcpListener::bind(("127.0.0.1", 0)).unwrap();
|
|
494
|
+
let address = listener.local_addr().unwrap();
|
|
495
|
+
let server = thread::spawn(move || {
|
|
496
|
+
let (mut stream, _) = listener.accept().unwrap();
|
|
497
|
+
let mut request = [0; 1024];
|
|
498
|
+
assert_ne!(stream.read(&mut request).unwrap(), 0);
|
|
499
|
+
write!(
|
|
500
|
+
stream,
|
|
501
|
+
"HTTP/1.1 200 OK\r\nContent-Length: {}\r\nConnection: close\r\n\r\n",
|
|
502
|
+
body.len()
|
|
503
|
+
)
|
|
504
|
+
.unwrap();
|
|
505
|
+
stream.write_all(&body).unwrap();
|
|
506
|
+
});
|
|
507
|
+
(format!("http://{address}/config.yml"), server)
|
|
508
|
+
}
|
|
509
|
+
|
|
486
510
|
fn cop_exclude(merged: &Value, cop: &str) -> Value {
|
|
487
511
|
merged
|
|
488
512
|
.as_mapping()
|
|
@@ -577,6 +601,24 @@ mod tests {
|
|
|
577
601
|
assert!(join_remote_url("no-directory", "shared.yml").is_err());
|
|
578
602
|
}
|
|
579
603
|
|
|
604
|
+
#[test]
|
|
605
|
+
fn remote_configuration_enforces_the_response_size_limit() {
|
|
606
|
+
let limit = MAX_REMOTE_CONFIG_BYTES as usize;
|
|
607
|
+
|
|
608
|
+
let (url, server) = serve_once(vec![b'a'; limit]);
|
|
609
|
+
let accepted = fetch_remote_config(&url).unwrap();
|
|
610
|
+
server.join().unwrap();
|
|
611
|
+
assert_eq!(accepted.len(), limit);
|
|
612
|
+
|
|
613
|
+
let (url, server) = serve_once(vec![b'a'; limit + 1]);
|
|
614
|
+
let error = fetch_remote_config(&url).unwrap_err().to_string();
|
|
615
|
+
server.join().unwrap();
|
|
616
|
+
assert!(
|
|
617
|
+
error.starts_with("failed to read remote configuration:"),
|
|
618
|
+
"unexpected error: {error}"
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
|
|
580
622
|
#[test]
|
|
581
623
|
fn merges_configurations_without_losing_untouched_keys() {
|
|
582
624
|
let merged = merge_config(
|
data/src/engine.rs
CHANGED
|
@@ -10,7 +10,6 @@ use ignore::WalkBuilder;
|
|
|
10
10
|
use rayon::prelude::*;
|
|
11
11
|
use serde::{Deserialize, Serialize};
|
|
12
12
|
use tempfile::NamedTempFile;
|
|
13
|
-
use tree_sitter::Parser;
|
|
14
13
|
|
|
15
14
|
use crate::config::{Config, ConfigStore};
|
|
16
15
|
use crate::cop_name::selector_matches;
|
|
@@ -554,7 +553,16 @@ fn persist_cache_index(path: &Path, index: &CacheIndex) -> bool {
|
|
|
554
553
|
let Ok(mut temporary) = NamedTempFile::new_in(parent) else {
|
|
555
554
|
return false;
|
|
556
555
|
};
|
|
557
|
-
|
|
556
|
+
// **Buffered.** `serde_json::to_writer` hands the writer each token as it produces it, so an
|
|
557
|
+
// unbuffered `File` turns one index into millions of `write` calls. The index holds every
|
|
558
|
+
// offense of every file with the source line it was found on, which is 336 MB over `ruby/ruby`:
|
|
559
|
+
// writing it a token at a time cost 115 seconds of a 135-second run, nearly all of it blocked
|
|
560
|
+
// in the kernel rather than serializing.
|
|
561
|
+
let written = {
|
|
562
|
+
let mut writer = std::io::BufWriter::with_capacity(1 << 20, temporary.as_file_mut());
|
|
563
|
+
serde_json::to_writer(&mut writer, index).is_ok() && writer.flush().is_ok()
|
|
564
|
+
};
|
|
565
|
+
if !written
|
|
558
566
|
|| temporary.as_file_mut().flush().is_err()
|
|
559
567
|
|| temporary.as_file().sync_all().is_err()
|
|
560
568
|
{
|
|
@@ -992,12 +1000,8 @@ fn inspect_planned(
|
|
|
992
1000
|
let length_as_read = text.len();
|
|
993
1001
|
let text = crate::nul_bytes::as_ruby_reads_it(&text).unwrap_or(text);
|
|
994
1002
|
let source = SourceFile::new(path, text).read_as_long_as(length_as_read);
|
|
995
|
-
let mut parser = Parser::new();
|
|
996
|
-
parser
|
|
997
|
-
.set_language(&tree_sitter_ruby::LANGUAGE.into())
|
|
998
|
-
.context("failed to initialize the Ruby parser")?;
|
|
999
1003
|
let tree = crate::profile::phase(crate::profile::Phase::Parse, || {
|
|
1000
|
-
parser
|
|
1004
|
+
crate::parser::parse(source.text())
|
|
1001
1005
|
})
|
|
1002
1006
|
.context("Ruby parser returned no syntax tree")?;
|
|
1003
1007
|
let ast = crate::profile::phase(crate::profile::Phase::Index, || {
|