rubocop 1.84.2 → 1.86.2

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.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +99 -16
  3. data/config/obsoletion.yml +5 -0
  4. data/lib/rubocop/cache_config.rb +1 -1
  5. data/lib/rubocop/cli/command/auto_generate_config.rb +28 -2
  6. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  7. data/lib/rubocop/cli/command/mcp.rb +19 -0
  8. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  9. data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  11. data/lib/rubocop/cli.rb +7 -7
  12. data/lib/rubocop/comment_config.rb +12 -15
  13. data/lib/rubocop/config.rb +14 -10
  14. data/lib/rubocop/config_finder.rb +1 -1
  15. data/lib/rubocop/config_loader_resolver.rb +2 -1
  16. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
  17. data/lib/rubocop/config_store.rb +1 -1
  18. data/lib/rubocop/config_validator.rb +1 -1
  19. data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
  20. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  22. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  23. data/lib/rubocop/cop/correctors.rb +28 -0
  24. data/lib/rubocop/cop/documentation.rb +2 -3
  25. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  26. data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -4
  27. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  28. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  29. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  30. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  31. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  32. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -2
  34. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  35. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  36. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  37. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  38. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  39. data/lib/rubocop/cop/layout/end_alignment.rb +6 -3
  40. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
  41. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  42. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  43. data/lib/rubocop/cop/layout/line_length.rb +5 -3
  44. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  45. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  46. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +53 -3
  47. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  48. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  49. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
  51. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  52. data/lib/rubocop/cop/lint/constant_reassignment.rb +59 -9
  53. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  54. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  55. data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
  56. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  57. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  58. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  59. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  60. data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
  61. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  62. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -1
  63. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  64. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  65. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +0 -9
  66. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +23 -6
  67. data/lib/rubocop/cop/lint/require_relative_self_path.rb +2 -0
  68. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
  69. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  70. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  71. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
  72. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  73. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  74. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  75. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -9
  76. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  77. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  78. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +35 -9
  79. data/lib/rubocop/cop/lint/void.rb +32 -12
  80. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  81. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  82. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  83. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  84. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  85. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  86. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
  87. data/lib/rubocop/cop/mixin.rb +85 -0
  88. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  89. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  90. data/lib/rubocop/cop/offense.rb +8 -0
  91. data/lib/rubocop/cop/registry.rb +39 -37
  92. data/lib/rubocop/cop/security/eval.rb +15 -2
  93. data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
  94. data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
  95. data/lib/rubocop/cop/style/alias.rb +4 -1
  96. data/lib/rubocop/cop/style/and_or.rb +1 -0
  97. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  98. data/lib/rubocop/cop/style/array_join.rb +4 -2
  99. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  100. data/lib/rubocop/cop/style/attr.rb +5 -2
  101. data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
  102. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  103. data/lib/rubocop/cop/style/block_delimiters.rb +25 -33
  104. data/lib/rubocop/cop/style/case_equality.rb +4 -0
  105. data/lib/rubocop/cop/style/class_and_module_children.rb +10 -2
  106. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  107. data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
  108. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
  109. data/lib/rubocop/cop/style/conditional_assignment.rb +0 -4
  110. data/lib/rubocop/cop/style/copyright.rb +22 -11
  111. data/lib/rubocop/cop/style/date_time.rb +2 -2
  112. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  113. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  114. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  115. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  116. data/lib/rubocop/cop/style/empty_class_definition.rb +43 -20
  117. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  118. data/lib/rubocop/cop/style/encoding.rb +7 -1
  119. data/lib/rubocop/cop/style/end_block.rb +3 -1
  120. data/lib/rubocop/cop/style/endless_method.rb +8 -3
  121. data/lib/rubocop/cop/style/file_open.rb +84 -0
  122. data/lib/rubocop/cop/style/for.rb +3 -0
  123. data/lib/rubocop/cop/style/format_string_token.rb +29 -2
  124. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  125. data/lib/rubocop/cop/style/guard_clause.rb +9 -6
  126. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
  127. data/lib/rubocop/cop/style/hash_lookup_method.rb +19 -7
  128. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  129. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  130. data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
  131. data/lib/rubocop/cop/style/if_unless_modifier.rb +14 -3
  132. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  133. data/lib/rubocop/cop/style/inline_comment.rb +4 -1
  134. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  135. data/lib/rubocop/cop/style/magic_comment_format.rb +2 -2
  136. data/lib/rubocop/cop/style/map_join.rb +123 -0
  137. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
  138. data/lib/rubocop/cop/style/module_member_existence_check.rb +7 -14
  139. data/lib/rubocop/cop/style/multiline_if_then.rb +3 -1
  140. data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
  141. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  142. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  143. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  144. data/lib/rubocop/cop/style/not.rb +2 -0
  145. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  146. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  147. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
  148. data/lib/rubocop/cop/style/parallel_assignment.rb +4 -0
  149. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  150. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  151. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  152. data/lib/rubocop/cop/style/proc.rb +3 -2
  153. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  154. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  155. data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
  156. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  157. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  158. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  159. data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
  160. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  161. data/lib/rubocop/cop/style/redundant_parentheses.rb +25 -22
  162. data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
  163. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  164. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  165. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  166. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
  167. data/lib/rubocop/cop/style/regexp_literal.rb +29 -0
  168. data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
  169. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  170. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  171. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  172. data/lib/rubocop/cop/style/semicolon.rb +2 -0
  173. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  174. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
  175. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  176. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  177. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  178. data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
  179. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  180. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  181. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  182. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  183. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  184. data/lib/rubocop/cop/team.rb +86 -35
  185. data/lib/rubocop/cop/variable_force/branch.rb +2 -2
  186. data/lib/rubocop/directive_comment.rb +2 -1
  187. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -2
  188. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  189. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  190. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  191. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  192. data/lib/rubocop/formatter.rb +22 -21
  193. data/lib/rubocop/lsp/diagnostic.rb +1 -0
  194. data/lib/rubocop/lsp/routes.rb +10 -3
  195. data/lib/rubocop/lsp/runtime.rb +1 -2
  196. data/lib/rubocop/mcp/server.rb +200 -0
  197. data/lib/rubocop/options.rb +17 -4
  198. data/lib/rubocop/path_util.rb +14 -2
  199. data/lib/rubocop/plugin/loader.rb +1 -1
  200. data/lib/rubocop/result_cache.rb +22 -10
  201. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  202. data/lib/rubocop/rspec/shared_contexts.rb +32 -2
  203. data/lib/rubocop/runner.rb +78 -51
  204. data/lib/rubocop/server/cache.rb +5 -7
  205. data/lib/rubocop/server/core.rb +2 -0
  206. data/lib/rubocop/target_finder.rb +14 -7
  207. data/lib/rubocop/target_ruby.rb +18 -12
  208. data/lib/rubocop/version.rb +2 -2
  209. data/lib/rubocop.rb +21 -96
  210. metadata +25 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f04de47751f13e6453b15f6114038e6c9ef89418cde47c8e8ce73abecc1664ee
4
- data.tar.gz: d1d9cd363db45392d753d24324b1828fe20834bfea01f5efcd2ee246352cbef1
3
+ metadata.gz: dfb5d2d113d00eb380202a0e76f462318033838aa240febe88bd2861b1bf6609
4
+ data.tar.gz: 9463407310a9babcc5869f9b1db0ca273ed036a3b440b5c27438cba855bee4ec
5
5
  SHA512:
6
- metadata.gz: f28b74f272f302feb77cdf3053f1116c7b24e3b0c57b139c71fd315d3c38fa8b4f3c122691fd071af1990699f7b7a52d9de5296ac8bb257435ef612ca317ef11
7
- data.tar.gz: 82cba886044606ae3b12eb9ef3b2b706be63d1503e80a10a9b22df2b329ed318b8b286e1b110d64bce0c9f10d7f39f84ad48735ba8a6b2d2f259dd78f4592550
6
+ metadata.gz: 5084465b6aa455c8ecd75e8b8f1e52f92e966d64117d2d88ad343ca535eb6fdc02f05056e6f21ac86e2344ec52cc1db2d69f8bf14a76b76bdee86a2bd5971520
7
+ data.tar.gz: 2101bc8bb5b392fa971f9a881e96b03321442b5067b4952413d806363bb89389cb2631671bfa6af0e30203800cff947d587ac0c68ef1651fdec455cc453faa18
data/config/default.yml CHANGED
@@ -3,20 +3,16 @@
3
3
  AllCops:
4
4
  RubyInterpreters:
5
5
  - ruby
6
- - macruby
7
6
  - rake
8
7
  - jruby
9
- - rbx
10
8
  # Include common Ruby source files.
11
9
  Include:
12
10
  - '**/*.rb'
13
11
  - '**/*.arb'
14
12
  - '**/*.axlsx'
15
13
  - '**/*.builder'
16
- - '**/*.fcgi'
17
14
  - '**/*.gemfile'
18
15
  - '**/*.gemspec'
19
- - '**/*.god'
20
16
  - '**/*.jb'
21
17
  - '**/*.jbuilder'
22
18
  - '**/*.mspec'
@@ -25,15 +21,12 @@ AllCops:
25
21
  - '**/*.podspec'
26
22
  - '**/*.rabl'
27
23
  - '**/*.rake'
28
- - '**/*.rbuild'
29
24
  - '**/*.rbw'
30
- - '**/*.rbx'
31
25
  - '**/*.ru'
32
26
  - '**/*.ruby'
33
27
  - '**/*.schema'
34
28
  - '**/*.spec'
35
29
  - '**/*.thor'
36
- - '**/*.watchr'
37
30
  - '**/.irbrc'
38
31
  - '**/.pryrc'
39
32
  - '**/.simplecov'
@@ -43,7 +36,6 @@ AllCops:
43
36
  - '**/Brewfile'
44
37
  - '**/Buildfile'
45
38
  - '**/Capfile'
46
- - '**/Cheffile'
47
39
  - '**/Dangerfile'
48
40
  - '**/Deliverfile'
49
41
  - '**/Fastfile'
@@ -60,7 +52,6 @@ AllCops:
60
52
  - '**/Snapfile'
61
53
  - '**/Steepfile'
62
54
  - '**/Thorfile'
63
- - '**/Vagabondfile'
64
55
  - '**/Vagrantfile'
65
56
  Exclude:
66
57
  - 'node_modules/**/*'
@@ -117,7 +108,7 @@ AllCops:
117
108
  # line option.
118
109
  UseCache: true
119
110
  # Threshold for how many files can be stored in the result cache before some
120
- # of the files are automatically removed.
111
+ # of the files are automatically removed. Set to false to disable cache pruning.
121
112
  MaxFilesInCache: 20000
122
113
  # The cache will be stored in "rubocop_cache" under this directory. If
123
114
  # CacheRootDirectory is ~ (nil), which it is by default, the root will be
@@ -538,6 +529,10 @@ Layout/ClosingParenthesisIndentation:
538
529
  Description: 'Checks the indentation of hanging closing parentheses.'
539
530
  Enabled: true
540
531
  VersionAdded: '0.49'
532
+ VersionChanged: '1.86'
533
+ # By default the indentation width from `Layout/IndentationWidth` is used,
534
+ # but it can be overridden by setting this parameter.
535
+ IndentationWidth: ~
541
536
 
542
537
  Layout/CommentIndentation:
543
538
  Description: 'Indentation of comments.'
@@ -546,7 +541,10 @@ Layout/CommentIndentation:
546
541
  # with a comment on the preceding line.
547
542
  AllowForAlignment: false
548
543
  VersionAdded: '0.49'
549
- VersionChanged: '1.24'
544
+ VersionChanged: '1.86'
545
+ # By default the indentation width from `Layout/IndentationWidth` is used,
546
+ # but it can be overridden by setting this parameter.
547
+ IndentationWidth: ~
550
548
 
551
549
  Layout/ConditionPosition:
552
550
  Description: >-
@@ -1720,6 +1718,11 @@ Lint/CopDirectiveSyntax:
1720
1718
  Enabled: pending
1721
1719
  VersionAdded: '1.72'
1722
1720
 
1721
+ Lint/DataDefineOverride:
1722
+ Description: 'Disallow overriding the `Data` built-in methods via `Data.define`.'
1723
+ Enabled: pending
1724
+ VersionAdded: '1.85'
1725
+
1723
1726
  Lint/Debugger:
1724
1727
  Description: 'Checks for debugger calls.'
1725
1728
  Enabled: true
@@ -2409,8 +2412,9 @@ Lint/SafeNavigationConsistency:
2409
2412
  consistent and appropriate safe navigation, without excess or deficiency,
2410
2413
  is used for all method calls on the same object.
2411
2414
  Enabled: true
2415
+ SafeAutoCorrect: false
2412
2416
  VersionAdded: '0.55'
2413
- VersionChanged: '0.77'
2417
+ VersionChanged: '1.85'
2414
2418
  AllowedMethods:
2415
2419
  - present?
2416
2420
  - blank?
@@ -2587,6 +2591,11 @@ Lint/UnreachableLoop:
2587
2591
  # eg. `exactly(2).times`
2588
2592
  - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/
2589
2593
 
2594
+ Lint/UnreachablePatternBranch:
2595
+ Description: 'Checks for unreachable `in` pattern branches after an unconditional catch-all pattern.'
2596
+ Enabled: pending
2597
+ VersionAdded: '1.85'
2598
+
2590
2599
  Lint/UnusedBlockArgument:
2591
2600
  Description: 'Checks for unused block arguments.'
2592
2601
  StyleGuide: '#underscore-unused-vars'
@@ -3982,10 +3991,13 @@ Style/EmptyClassDefinition:
3982
3991
  Description: 'Enforces consistent style for empty class definitions.'
3983
3992
  Enabled: pending
3984
3993
  VersionAdded: '1.84'
3985
- EnforcedStyle: class_definition
3994
+ VersionChanged: '1.86'
3995
+ EnforcedStyle: class_keyword
3986
3996
  SupportedStyles:
3987
- - class_definition
3997
+ - class_keyword
3988
3998
  - class_new
3999
+ - class_definition # Deprecated.
4000
+ AllowedParentClasses: []
3989
4001
 
3990
4002
  Style/EmptyElse:
3991
4003
  Description: 'Avoid empty else-clauses.'
@@ -4145,6 +4157,12 @@ Style/FileNull:
4145
4157
  SafeAutoCorrect: false
4146
4158
  VersionAdded: '1.69'
4147
4159
 
4160
+ Style/FileOpen:
4161
+ Description: 'Checks for `File.open` without a block, which can leak file descriptors.'
4162
+ Enabled: pending
4163
+ Safe: false
4164
+ VersionAdded: '1.85'
4165
+
4148
4166
  Style/FileRead:
4149
4167
  Description: 'Favor `File.(bin)read` convenience methods.'
4150
4168
  StyleGuide: '#file-read'
@@ -4642,6 +4660,12 @@ Style/MapIntoArray:
4642
4660
  VersionChanged: '1.67'
4643
4661
  Safe: false
4644
4662
 
4663
+ Style/MapJoin:
4664
+ Description: 'Checks for redundant `map(&:to_s)` before `join`.'
4665
+ Enabled: pending
4666
+ Safe: false
4667
+ VersionAdded: '1.85'
4668
+
4645
4669
  Style/MapToHash:
4646
4670
  Description: 'Prefer `to_h` with a block over `map.to_h`.'
4647
4671
  Enabled: pending
@@ -4779,7 +4803,6 @@ Style/ModuleMemberExistenceCheck:
4779
4803
  Description: 'Checks for usage of `Module` methods returning arrays that can be replaced with equivalent predicates.'
4780
4804
  Enabled: pending
4781
4805
  VersionAdded: '1.82'
4782
- AllowedMethods: []
4783
4806
 
4784
4807
  Style/MultilineBlockChain:
4785
4808
  Description: 'Avoid multi-line chains of blocks.'
@@ -5091,6 +5114,16 @@ Style/ObjectThen:
5091
5114
  - then
5092
5115
  - yield_self
5093
5116
 
5117
+ Style/OneClassPerFile:
5118
+ Description: 'Checks that each source file defines at most one top-level class or module.'
5119
+ Enabled: pending
5120
+ VersionAdded: '1.85'
5121
+ VersionChanged: '1.86'
5122
+ AllowedClasses: []
5123
+ Exclude:
5124
+ - 'spec/**/*'
5125
+ - 'test/**/*'
5126
+
5094
5127
  Style/OneLineConditional:
5095
5128
  Description: >-
5096
5129
  Favor the ternary operator (?:) or multi-line constructs over
@@ -5179,6 +5212,14 @@ Style/ParenthesesAroundCondition:
5179
5212
  AllowSafeAssignment: true
5180
5213
  AllowInMultilineConditions: false
5181
5214
 
5215
+ Style/PartitionInsteadOfDoubleSelect:
5216
+ Description: >-
5217
+ Checks for consecutive `select`/`filter`/`find_all` and `reject` calls
5218
+ on the same receiver with the same block body.
5219
+ Enabled: pending
5220
+ Safe: false
5221
+ VersionAdded: '1.85'
5222
+
5182
5223
  Style/PercentLiteralDelimiters:
5183
5224
  Description: 'Use `%`-literal delimiters consistently.'
5184
5225
  StyleGuide: '#percent-literal-braces'
@@ -5211,6 +5252,12 @@ Style/PerlBackrefs:
5211
5252
  Enabled: true
5212
5253
  VersionAdded: '0.13'
5213
5254
 
5255
+ Style/PredicateWithKind:
5256
+ Description: 'Prefer `any?(Klass)` to `any? { |x| x.is_a?(Klass) }`.'
5257
+ Enabled: pending
5258
+ SafeAutoCorrect: false
5259
+ VersionAdded: '1.85'
5260
+
5214
5261
  Style/PreferredHashMethods:
5215
5262
  Description: 'Checks use of `has_key?` and `has_value?` Hash methods.'
5216
5263
  StyleGuide: '#hash-key'
@@ -5261,6 +5308,12 @@ Style/RandomWithOffset:
5261
5308
  Enabled: true
5262
5309
  VersionAdded: '0.52'
5263
5310
 
5311
+ Style/ReduceToHash:
5312
+ Description: 'Use `to_h { ... }` instead of `each_with_object`, `inject`, or `reduce` to build a hash.'
5313
+ Enabled: pending
5314
+ Safe: false
5315
+ VersionAdded: '1.85'
5316
+
5264
5317
  Style/RedundantArgument:
5265
5318
  Description: 'Checks for a redundant argument passed to certain methods.'
5266
5319
  Enabled: pending
@@ -5430,6 +5483,11 @@ Style/RedundantLineContinuation:
5430
5483
  Enabled: pending
5431
5484
  VersionAdded: '1.49'
5432
5485
 
5486
+ Style/RedundantMinMaxBy:
5487
+ Description: 'Identifies places where `max_by`/`min_by` can be replaced by `max`/`min`.'
5488
+ Enabled: pending
5489
+ VersionAdded: '1.85'
5490
+
5433
5491
  Style/RedundantParentheses:
5434
5492
  Description: "Checks for parentheses that seem not to serve any purpose."
5435
5493
  Enabled: true
@@ -5507,6 +5565,13 @@ Style/RedundantStringEscape:
5507
5565
  Enabled: pending
5508
5566
  VersionAdded: '1.37'
5509
5567
 
5568
+ Style/RedundantStructKeywordInit:
5569
+ Description: 'Checks for redundant `keyword_init` option for `Struct.new`.'
5570
+ Enabled: false
5571
+ SafeAutoCorrect: false
5572
+ VersionAdded: '1.85'
5573
+ VersionChanged: '1.86'
5574
+
5510
5575
  Style/RegexpLiteral:
5511
5576
  Description: 'Use / or %r around regular expressions.'
5512
5577
  StyleGuide: '#percent-r'
@@ -5613,8 +5678,20 @@ Style/Sample:
5613
5678
  Enabled: true
5614
5679
  VersionAdded: '0.30'
5615
5680
 
5681
+ Style/SelectByKind:
5682
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a kind check.'
5683
+ Enabled: pending
5684
+ SafeAutoCorrect: false
5685
+ VersionAdded: '1.85'
5686
+
5687
+ Style/SelectByRange:
5688
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a range check.'
5689
+ Enabled: pending
5690
+ SafeAutoCorrect: false
5691
+ VersionAdded: '1.85'
5692
+
5616
5693
  Style/SelectByRegexp:
5617
- Description: 'Prefer grep/grep_v to select/reject with a regexp match.'
5694
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a regexp match.'
5618
5695
  Enabled: pending
5619
5696
  SafeAutoCorrect: false
5620
5697
  VersionAdded: '1.22'
@@ -5873,6 +5950,12 @@ Style/SymbolProc:
5873
5950
  AllowedPatterns: []
5874
5951
  AllowComments: false
5875
5952
 
5953
+ Style/TallyMethod:
5954
+ Description: 'Prefer `Enumerable#tally` over manual counting patterns.'
5955
+ Enabled: pending
5956
+ Safe: false
5957
+ VersionAdded: '1.85'
5958
+
5876
5959
  Style/TernaryParentheses:
5877
5960
  Description: 'Checks for use of parentheses around ternary conditions.'
5878
5961
  Enabled: true
@@ -245,3 +245,8 @@ changed_enforced_styles:
245
245
  parameters: EnforcedStyle
246
246
  value: rails
247
247
  alternative: indented_internal_methods
248
+ - cops: Style/EmptyClassDefinition
249
+ parameters: EnforcedStyle
250
+ value: class_definition
251
+ alternative: class_keyword
252
+ severity: warning
@@ -35,7 +35,7 @@ module RuboCop
35
35
  root_dir do
36
36
  next cache_root_override if cache_root_override
37
37
 
38
- config_path = ConfigFinder.find_config_path(Dir.pwd)
38
+ config_path = ConfigFinder.find_config_path(PathUtil.pwd)
39
39
  file_contents = File.read(config_path)
40
40
 
41
41
  # Returns early if `CacheRootDirectory` is not used before requiring `erb` or `yaml`.
@@ -24,13 +24,39 @@ module RuboCop
24
24
 
25
25
  def run
26
26
  add_formatter
27
+ use_temporary_cache
28
+ reset_auto_gen_tmp_dir
27
29
  reset_config_and_auto_gen_file
28
30
  line_length_contents = maybe_run_line_length_cop
29
- run_all_cops(line_length_contents)
31
+ result = run_all_cops(line_length_contents)
32
+ reset_auto_gen_tmp_dir
33
+ result
30
34
  end
31
35
 
32
36
  private
33
37
 
38
+ def use_temporary_cache
39
+ # Use a separate cache directory to ensure MinDigits and Max values are calculated.
40
+ # This allows parallel execution (which requires cache) while ensuring MinDigits
41
+ # and Max values are computed, since the cache starts empty.
42
+ @options[:cache_root] = auto_gen_tmp_dir.join('cache').to_s
43
+ end
44
+
45
+ def reset_auto_gen_tmp_dir
46
+ auto_gen_tmp_dir.rmtree if auto_gen_tmp_dir.exist?
47
+ auto_gen_tmp_dir.mkpath
48
+ end
49
+
50
+ def auto_gen_tmp_dir
51
+ @auto_gen_tmp_dir ||= Pathname.new(
52
+ RuboCop::CacheConfig.root_dir_from_toplevel_config
53
+ ).join('auto-gen-tmp').tap do |path|
54
+ path.mkpath
55
+ # Set the temp directory path for ExcludeLimit to use
56
+ RuboCop::ExcludeLimit.tmp_dir = path
57
+ end
58
+ end
59
+
34
60
  def maybe_run_line_length_cop
35
61
  if only_exclude?
36
62
  skip_line_length_cop(PHASE_1_SKIPPED_ONLY_EXCLUDE)
@@ -153,7 +179,7 @@ module RuboCop
153
179
  def relative_path_to_todo_from_options_config
154
180
  return AUTO_GENERATED_FILE unless @options[:config]
155
181
 
156
- base = Pathname.new(Dir.pwd)
182
+ base = Pathname.new(PathUtil.pwd)
157
183
  config_dir = Pathname.new(@options[:config]).realpath.dirname
158
184
 
159
185
  # Don't have the path start with `/`
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Lists the cops that will inspect the given file or directory.
7
+ # @api private
8
+ class ListEnabledCopsFor < Base
9
+ self.command_name = :list_enabled_cops_for
10
+
11
+ def initialize(env)
12
+ super
13
+
14
+ # Load the configs so the require()s are done for custom cops
15
+ @config = @config_store.for(@options[:list_enabled_cops_for])
16
+ end
17
+
18
+ def run
19
+ print_available_cops
20
+ end
21
+
22
+ private
23
+
24
+ def print_available_cops
25
+ registry = Cop::Registry.global
26
+
27
+ registry.departments.sort.each do |department|
28
+ puts cops_of_department(registry, department).sort
29
+ end
30
+ end
31
+
32
+ def cops_of_department(registry, department)
33
+ registry.with_department(department)
34
+ .map(&:cop_name)
35
+ .select { |cop_name| @config.cop_enabled?(cop_name) }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Start Model Context Protocol of RuboCop.
7
+ # @api private
8
+ class MCP < Base
9
+ self.command_name = :mcp
10
+
11
+ def run
12
+ require_relative '../../mcp/server'
13
+
14
+ RuboCop::MCP::Server.new(@config_store).start
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -25,7 +25,7 @@ module RuboCop
25
25
  super
26
26
 
27
27
  # Load the configs so the require()s are done for custom cops
28
- @config = @config_store.for(Dir.pwd)
28
+ @config = @config_store.for(PathUtil.pwd)
29
29
 
30
30
  @cop_matchers = @options[:show_cops].map do |pattern|
31
31
  if pattern.include?('*')
@@ -46,7 +46,7 @@ module RuboCop
46
46
  registry = Cop::Registry.global
47
47
  show_all = @cop_matchers.empty?
48
48
 
49
- puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: " if show_all
49
+ puts "# Available cops (#{registry.length}) + config for #{PathUtil.pwd}: " if show_all
50
50
 
51
51
  registry.departments.sort!.each do |department|
52
52
  print_cops_of_department(registry, department, show_all)
@@ -12,7 +12,7 @@ module RuboCop
12
12
  def initialize(env)
13
13
  super
14
14
 
15
- @config = @config_store.for(Dir.pwd)
15
+ @config = @config_store.for(PathUtil.pwd)
16
16
  end
17
17
 
18
18
  def run
@@ -25,10 +25,10 @@ module RuboCop
25
25
  puts Cop::Documentation.default_base_url if cops_array.empty?
26
26
 
27
27
  cops_array.each do |cop_name|
28
- cop = registry_hash[cop_name]
29
- next if cop.empty?
28
+ cop = Cop::Registry.global.find_by_cop_name(cop_name)
29
+ next unless cop
30
30
 
31
- url = Cop::Documentation.url_for(cop.first, @config)
31
+ url = Cop::Documentation.url_for(cop, @config)
32
32
  puts url if url
33
33
  end
34
34
 
@@ -38,10 +38,6 @@ module RuboCop
38
38
  def cops_array
39
39
  @cops_array ||= @options[:show_docs_url]
40
40
  end
41
-
42
- def registry_hash
43
- @registry_hash ||= Cop::Registry.global.to_h
44
- end
45
41
  end
46
42
  end
47
43
  end
@@ -60,7 +60,7 @@ module RuboCop
60
60
  def print_opt_out_instruction
61
61
  puts
62
62
  puts 'You can opt out of this message by adding the following to your config ' \
63
- '(see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions ' \
63
+ '(see https://docs.rubocop.org/rubocop/plugins.html#plugin-suggestions ' \
64
64
  'for more options):'
65
65
  puts ' AllCops:'
66
66
  puts ' SuggestExtensions: false'
data/lib/rubocop/cli.rb CHANGED
@@ -13,7 +13,7 @@ module RuboCop
13
13
  DEFAULT_PARALLEL_OPTIONS = %i[
14
14
  color config debug display_style_guide display_time display_only_fail_level_offenses
15
15
  display_only_failed editor_mode except extra_details fail_level fix_layout format formatters
16
- ignore_disable_comments lint only only_guide_cops require safe
16
+ ignore_disable_comments lint only only_guide_cops out require safe
17
17
  autocorrect safe_autocorrect autocorrect_all
18
18
  ].freeze
19
19
 
@@ -76,7 +76,9 @@ module RuboCop
76
76
  STATUS_ERROR
77
77
  ensure
78
78
  elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start
79
- puts "Finished in #{elapsed_time} seconds" if @options[:debug] || @options[:display_time]
79
+ if @options[:debug] || @options[:display_time]
80
+ puts "Finished in #{elapsed_time.round(5)} seconds"
81
+ end
80
82
  end
81
83
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
82
84
 
@@ -198,17 +200,15 @@ module RuboCop
198
200
  RuboCop::LSP.enable if @options[:editor_mode]
199
201
  end
200
202
 
201
- # rubocop:disable Metrics/CyclomaticComplexity
202
203
  def handle_exiting_options
203
204
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
204
205
 
205
206
  run_command(:version) if @options[:version] || @options[:verbose_version]
206
- run_command(:show_cops) if @options[:show_cops]
207
- run_command(:show_docs_url) if @options[:show_docs_url]
208
- run_command(:lsp) if @options[:lsp]
207
+ %i[show_cops list_enabled_cops_for show_docs_url lsp mcp].each do |name|
208
+ run_command(name) if @options[name]
209
+ end
209
210
  raise Finished
210
211
  end
211
- # rubocop:enable Metrics/CyclomaticComplexity
212
212
 
213
213
  def apply_default_formatter
214
214
  # This must be done after the options have already been processed,
@@ -95,7 +95,8 @@ module RuboCop
95
95
  end
96
96
  end
97
97
 
98
- def analyze # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
98
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
99
+ def analyze
99
100
  return {} if @no_directives
100
101
 
101
102
  analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
@@ -103,9 +104,9 @@ module RuboCop
103
104
 
104
105
  each_directive do |directive|
105
106
  if directive.push?
106
- resolved = resolve_push_cops(directive)
107
- @stack.push(snapshot_cops(analyses, resolved.values.flatten))
108
- apply_push(analyses, resolved, directive.line_number)
107
+ restore_point = analyses.transform_values(&:dup)
108
+ @stack.push(restore_point)
109
+ apply_push(analyses, resolve_push_cops(directive), directive.line_number)
109
110
  elsif directive.pop?
110
111
  pop_state(analyses, directive.line_number) if @stack.any?
111
112
  else
@@ -121,10 +122,7 @@ module RuboCop
121
122
  hash[cop_name] = cop_line_ranges(analysis)
122
123
  end
123
124
  end
124
-
125
- def snapshot_cops(analyses, cop_names)
126
- cop_names.to_h { |name| [name, analyses[name].dup] }
127
- end
125
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
128
126
 
129
127
  def resolve_push_cops(directive)
130
128
  directive.push_args.transform_values do |names|
@@ -155,13 +153,12 @@ module RuboCop
155
153
  end
156
154
 
157
155
  def pop_state(analyses, line)
158
- saved = @stack.pop
159
- saved.each do |cop, old|
160
- cur = analyses[cop]
161
- new_range = cur.start_line_number ? [cur.start_line_number..(line - 1)] : []
162
- ranges = cur.line_ranges + new_range
163
- new_start = old.start_line_number ? line : nil
164
- analyses[cop] = CopAnalysis.new(ranges, new_start)
156
+ restore_point = @stack.pop
157
+ (restore_point.keys | analyses.keys).each do |cop|
158
+ current = analyses[cop]
159
+ new_range = current.start_line_number ? [current.start_line_number..(line - 1)] : []
160
+ new_start = restore_point[cop]&.start_line_number ? line : nil
161
+ analyses[cop] = CopAnalysis.new(current.line_ranges + new_range, new_start)
165
162
  end
166
163
  end
167
164
 
@@ -217,6 +217,9 @@ module RuboCop
217
217
  for_all_cops['StringLiteralsFrozenByDefault']
218
218
  end
219
219
 
220
+ # Returns true if the file matches any include pattern. If a block is given, the block is called
221
+ # to determine if the pattern is relevant (true returned by the block) or should be skipped
222
+ # (false returned).
220
223
  def file_to_include?(file)
221
224
  relative_file_path = path_relative_to_config(file)
222
225
 
@@ -228,11 +231,9 @@ module RuboCop
228
231
  absolute_file_path = File.expand_path(file)
229
232
 
230
233
  patterns_to_include.any? do |pattern|
231
- if block_given?
232
- yield pattern, relative_file_path, absolute_file_path
233
- else
234
- match_path?(pattern, relative_file_path) || match_path?(pattern, absolute_file_path)
235
- end
234
+ next if block_given? && !yield(pattern)
235
+
236
+ match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
236
237
  end
237
238
  end
238
239
 
@@ -242,10 +243,7 @@ module RuboCop
242
243
  # `bundler-console` conveys `Bundler::Console`).
243
244
  return true if File.extname(file) == '.gemspec'
244
245
 
245
- file_to_include?(file) do |pattern, relative_path, absolute_path|
246
- /[A-Z]/.match?(pattern.to_s) &&
247
- (match_path?(pattern, relative_path) || match_path?(pattern, absolute_path))
248
- end
246
+ file_to_include?(file) { |pattern| /[A-Z]/.match?(pattern.to_s) }
249
247
  end
250
248
 
251
249
  # Returns true if there's a chance that an Include pattern matches hidden
@@ -286,7 +284,7 @@ module RuboCop
286
284
  loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
287
285
  File.expand_path(File.dirname(loaded_path))
288
286
  else
289
- Dir.pwd
287
+ PathUtil.pwd
290
288
  end
291
289
  end
292
290
 
@@ -345,6 +343,12 @@ module RuboCop
345
343
 
346
344
  private
347
345
 
346
+ def match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
347
+ should_use_absolute_path = absolute?(pattern.to_s) || pattern.to_s.start_with?('..') ||
348
+ relative_file_path.start_with?('..')
349
+ match_path?(pattern, should_use_absolute_path ? absolute_file_path : relative_file_path)
350
+ end
351
+
348
352
  # @return [Float, nil] The Rails version as a `major.minor` Float.
349
353
  def target_rails_version_from_bundler_lock_file
350
354
  @target_rails_version_from_bundler_lock_file ||= read_rails_version_from_bundler_lock_file
@@ -30,7 +30,7 @@ module RuboCop
30
30
  private
31
31
 
32
32
  def find_project_root
33
- pwd = Dir.pwd
33
+ pwd = PathUtil.pwd
34
34
  gems_file = find_last_file_upwards('Gemfile', pwd) || find_last_file_upwards('gems.rb', pwd)
35
35
  return unless gems_file
36
36
 
@@ -45,6 +45,7 @@ module RuboCop
45
45
  base_config.each do |k, v|
46
46
  next unless v.is_a?(Hash)
47
47
 
48
+ only_base_has_include = v.key?('Include') && !hash.dig(k, 'Include')
48
49
  if hash.key?(k)
49
50
  v = merge(v, hash[k],
50
51
  cop_name: k, file: file, debug: debug,
@@ -52,7 +53,7 @@ module RuboCop
52
53
  inherit_mode: determine_inherit_mode(hash, k))
53
54
  end
54
55
  hash[k] = v
55
- fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
56
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if only_base_has_include
56
57
  end
57
58
  end
58
59
  end