rubocop 1.84.2 → 1.86.1

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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +91 -15
  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 +1 -1
  6. data/lib/rubocop/cli/command/mcp.rb +19 -0
  7. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  8. data/lib/rubocop/cli/command/show_docs_url.rb +1 -1
  9. data/lib/rubocop/cli.rb +6 -3
  10. data/lib/rubocop/config.rb +14 -10
  11. data/lib/rubocop/config_finder.rb +1 -1
  12. data/lib/rubocop/config_loader_resolver.rb +2 -1
  13. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
  14. data/lib/rubocop/config_store.rb +1 -1
  15. data/lib/rubocop/config_validator.rb +1 -1
  16. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  17. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  18. data/lib/rubocop/cop/documentation.rb +2 -3
  19. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  20. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  21. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  22. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  23. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  24. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  25. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -2
  26. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  27. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  28. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  29. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  30. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  31. data/lib/rubocop/cop/layout/end_alignment.rb +6 -3
  32. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
  33. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  34. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  35. data/lib/rubocop/cop/layout/line_length.rb +5 -3
  36. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  37. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +28 -3
  38. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  39. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  40. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  41. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
  42. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  43. data/lib/rubocop/cop/lint/constant_reassignment.rb +59 -9
  44. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  45. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  46. data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
  47. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  48. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  49. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  50. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  51. data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
  52. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  53. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -1
  54. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  55. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +0 -9
  56. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +23 -6
  57. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
  58. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  59. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  60. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
  61. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  62. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  63. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  64. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  65. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  66. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  67. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +22 -7
  68. data/lib/rubocop/cop/lint/void.rb +32 -12
  69. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  70. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  71. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  72. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  73. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  74. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
  75. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  76. data/lib/rubocop/cop/registry.rb +20 -13
  77. data/lib/rubocop/cop/security/eval.rb +15 -2
  78. data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
  79. data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
  80. data/lib/rubocop/cop/style/alias.rb +4 -1
  81. data/lib/rubocop/cop/style/and_or.rb +1 -0
  82. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  83. data/lib/rubocop/cop/style/array_join.rb +4 -2
  84. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  85. data/lib/rubocop/cop/style/attr.rb +5 -2
  86. data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
  87. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  88. data/lib/rubocop/cop/style/block_delimiters.rb +25 -33
  89. data/lib/rubocop/cop/style/case_equality.rb +4 -0
  90. data/lib/rubocop/cop/style/class_and_module_children.rb +10 -2
  91. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  92. data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
  93. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
  94. data/lib/rubocop/cop/style/conditional_assignment.rb +0 -4
  95. data/lib/rubocop/cop/style/copyright.rb +1 -1
  96. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  97. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  98. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  99. data/lib/rubocop/cop/style/empty_class_definition.rb +43 -20
  100. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  101. data/lib/rubocop/cop/style/encoding.rb +7 -1
  102. data/lib/rubocop/cop/style/end_block.rb +3 -1
  103. data/lib/rubocop/cop/style/endless_method.rb +8 -3
  104. data/lib/rubocop/cop/style/file_open.rb +84 -0
  105. data/lib/rubocop/cop/style/for.rb +3 -0
  106. data/lib/rubocop/cop/style/format_string_token.rb +29 -2
  107. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  108. data/lib/rubocop/cop/style/guard_clause.rb +9 -6
  109. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
  110. data/lib/rubocop/cop/style/hash_lookup_method.rb +7 -0
  111. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  112. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  113. data/lib/rubocop/cop/style/if_inside_else.rb +1 -5
  114. data/lib/rubocop/cop/style/if_unless_modifier.rb +14 -3
  115. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  116. data/lib/rubocop/cop/style/inline_comment.rb +4 -1
  117. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  118. data/lib/rubocop/cop/style/magic_comment_format.rb +2 -2
  119. data/lib/rubocop/cop/style/map_join.rb +123 -0
  120. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
  121. data/lib/rubocop/cop/style/module_member_existence_check.rb +1 -11
  122. data/lib/rubocop/cop/style/multiline_if_then.rb +3 -1
  123. data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
  124. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  125. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  126. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  127. data/lib/rubocop/cop/style/not.rb +2 -0
  128. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  129. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  130. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
  131. data/lib/rubocop/cop/style/parallel_assignment.rb +4 -0
  132. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  133. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  134. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  135. data/lib/rubocop/cop/style/proc.rb +3 -2
  136. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  137. data/lib/rubocop/cop/style/reduce_to_hash.rb +184 -0
  138. data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
  139. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  140. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  141. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  142. data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
  143. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  144. data/lib/rubocop/cop/style/redundant_parentheses.rb +25 -22
  145. data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
  146. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  147. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  148. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
  149. data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
  150. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  151. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  152. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  153. data/lib/rubocop/cop/style/semicolon.rb +2 -0
  154. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  155. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
  156. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  157. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  158. data/lib/rubocop/cop/style/symbol_proc.rb +4 -3
  159. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  160. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  161. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  162. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  163. data/lib/rubocop/cop/variable_force/branch.rb +2 -2
  164. data/lib/rubocop/directive_comment.rb +2 -1
  165. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  166. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  167. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  168. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  169. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  170. data/lib/rubocop/formatter.rb +22 -21
  171. data/lib/rubocop/lsp/diagnostic.rb +1 -0
  172. data/lib/rubocop/lsp/routes.rb +10 -3
  173. data/lib/rubocop/mcp/server.rb +200 -0
  174. data/lib/rubocop/options.rb +10 -1
  175. data/lib/rubocop/path_util.rb +14 -2
  176. data/lib/rubocop/plugin/loader.rb +1 -1
  177. data/lib/rubocop/result_cache.rb +22 -10
  178. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  179. data/lib/rubocop/rspec/shared_contexts.rb +11 -2
  180. data/lib/rubocop/runner.rb +8 -3
  181. data/lib/rubocop/server/cache.rb +5 -7
  182. data/lib/rubocop/server/core.rb +2 -0
  183. data/lib/rubocop/target_finder.rb +1 -1
  184. data/lib/rubocop/target_ruby.rb +18 -12
  185. data/lib/rubocop/version.rb +2 -2
  186. data/lib/rubocop.rb +14 -0
  187. metadata +22 -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: e7e3463c6020de496396b13ecf80f691f532af83ac8f8627286f3887f07b11b2
4
+ data.tar.gz: 9e8c332d0f33ea078abcc71e0ddb7cd009497842a026dfdcae103a63fc909ba6
5
5
  SHA512:
6
- metadata.gz: f28b74f272f302feb77cdf3053f1116c7b24e3b0c57b139c71fd315d3c38fa8b4f3c122691fd071af1990699f7b7a52d9de5296ac8bb257435ef612ca317ef11
7
- data.tar.gz: 82cba886044606ae3b12eb9ef3b2b706be63d1503e80a10a9b22df2b329ed318b8b286e1b110d64bce0c9f10d7f39f84ad48735ba8a6b2d2f259dd78f4592550
6
+ metadata.gz: 0f0d7cff4de9dc7d8f04cdea8f8f28d6e45d5c0676a40ca67daa4e3fd6e3397363d2c2f4b368b5bcbb165d7478bdfb33c5352c49d2fd52896f8aa6d488e017cc
7
+ data.tar.gz: 357c3047ffea023a5c10162e4e2f2ee782796b5ca87d7c4413bde296d284c41362033ca9d997609ac6d9eceea7227b46e240150340a8a26cad8071bc5cce33c7
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
@@ -1720,6 +1711,11 @@ Lint/CopDirectiveSyntax:
1720
1711
  Enabled: pending
1721
1712
  VersionAdded: '1.72'
1722
1713
 
1714
+ Lint/DataDefineOverride:
1715
+ Description: 'Disallow overriding the `Data` built-in methods via `Data.define`.'
1716
+ Enabled: pending
1717
+ VersionAdded: '1.85'
1718
+
1723
1719
  Lint/Debugger:
1724
1720
  Description: 'Checks for debugger calls.'
1725
1721
  Enabled: true
@@ -2409,8 +2405,9 @@ Lint/SafeNavigationConsistency:
2409
2405
  consistent and appropriate safe navigation, without excess or deficiency,
2410
2406
  is used for all method calls on the same object.
2411
2407
  Enabled: true
2408
+ SafeAutoCorrect: false
2412
2409
  VersionAdded: '0.55'
2413
- VersionChanged: '0.77'
2410
+ VersionChanged: '1.85'
2414
2411
  AllowedMethods:
2415
2412
  - present?
2416
2413
  - blank?
@@ -2587,6 +2584,11 @@ Lint/UnreachableLoop:
2587
2584
  # eg. `exactly(2).times`
2588
2585
  - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/
2589
2586
 
2587
+ Lint/UnreachablePatternBranch:
2588
+ Description: 'Checks for unreachable `in` pattern branches after an unconditional catch-all pattern.'
2589
+ Enabled: pending
2590
+ VersionAdded: '1.85'
2591
+
2590
2592
  Lint/UnusedBlockArgument:
2591
2593
  Description: 'Checks for unused block arguments.'
2592
2594
  StyleGuide: '#underscore-unused-vars'
@@ -3982,10 +3984,13 @@ Style/EmptyClassDefinition:
3982
3984
  Description: 'Enforces consistent style for empty class definitions.'
3983
3985
  Enabled: pending
3984
3986
  VersionAdded: '1.84'
3985
- EnforcedStyle: class_definition
3987
+ VersionChanged: '1.86'
3988
+ EnforcedStyle: class_keyword
3986
3989
  SupportedStyles:
3987
- - class_definition
3990
+ - class_keyword
3988
3991
  - class_new
3992
+ - class_definition # Deprecated.
3993
+ AllowedParentClasses: []
3989
3994
 
3990
3995
  Style/EmptyElse:
3991
3996
  Description: 'Avoid empty else-clauses.'
@@ -4145,6 +4150,12 @@ Style/FileNull:
4145
4150
  SafeAutoCorrect: false
4146
4151
  VersionAdded: '1.69'
4147
4152
 
4153
+ Style/FileOpen:
4154
+ Description: 'Checks for `File.open` without a block, which can leak file descriptors.'
4155
+ Enabled: pending
4156
+ Safe: false
4157
+ VersionAdded: '1.85'
4158
+
4148
4159
  Style/FileRead:
4149
4160
  Description: 'Favor `File.(bin)read` convenience methods.'
4150
4161
  StyleGuide: '#file-read'
@@ -4642,6 +4653,12 @@ Style/MapIntoArray:
4642
4653
  VersionChanged: '1.67'
4643
4654
  Safe: false
4644
4655
 
4656
+ Style/MapJoin:
4657
+ Description: 'Checks for redundant `map(&:to_s)` before `join`.'
4658
+ Enabled: pending
4659
+ Safe: false
4660
+ VersionAdded: '1.85'
4661
+
4645
4662
  Style/MapToHash:
4646
4663
  Description: 'Prefer `to_h` with a block over `map.to_h`.'
4647
4664
  Enabled: pending
@@ -4779,7 +4796,6 @@ Style/ModuleMemberExistenceCheck:
4779
4796
  Description: 'Checks for usage of `Module` methods returning arrays that can be replaced with equivalent predicates.'
4780
4797
  Enabled: pending
4781
4798
  VersionAdded: '1.82'
4782
- AllowedMethods: []
4783
4799
 
4784
4800
  Style/MultilineBlockChain:
4785
4801
  Description: 'Avoid multi-line chains of blocks.'
@@ -5091,6 +5107,16 @@ Style/ObjectThen:
5091
5107
  - then
5092
5108
  - yield_self
5093
5109
 
5110
+ Style/OneClassPerFile:
5111
+ Description: 'Checks that each source file defines at most one top-level class or module.'
5112
+ Enabled: pending
5113
+ VersionAdded: '1.85'
5114
+ VersionChanged: '1.86'
5115
+ AllowedClasses: []
5116
+ Exclude:
5117
+ - 'spec/**/*'
5118
+ - 'test/**/*'
5119
+
5094
5120
  Style/OneLineConditional:
5095
5121
  Description: >-
5096
5122
  Favor the ternary operator (?:) or multi-line constructs over
@@ -5179,6 +5205,14 @@ Style/ParenthesesAroundCondition:
5179
5205
  AllowSafeAssignment: true
5180
5206
  AllowInMultilineConditions: false
5181
5207
 
5208
+ Style/PartitionInsteadOfDoubleSelect:
5209
+ Description: >-
5210
+ Checks for consecutive `select`/`filter`/`find_all` and `reject` calls
5211
+ on the same receiver with the same block body.
5212
+ Enabled: pending
5213
+ Safe: false
5214
+ VersionAdded: '1.85'
5215
+
5182
5216
  Style/PercentLiteralDelimiters:
5183
5217
  Description: 'Use `%`-literal delimiters consistently.'
5184
5218
  StyleGuide: '#percent-literal-braces'
@@ -5211,6 +5245,12 @@ Style/PerlBackrefs:
5211
5245
  Enabled: true
5212
5246
  VersionAdded: '0.13'
5213
5247
 
5248
+ Style/PredicateWithKind:
5249
+ Description: 'Prefer `any?(Klass)` to `any? { |x| x.is_a?(Klass) }`.'
5250
+ Enabled: pending
5251
+ SafeAutoCorrect: false
5252
+ VersionAdded: '1.85'
5253
+
5214
5254
  Style/PreferredHashMethods:
5215
5255
  Description: 'Checks use of `has_key?` and `has_value?` Hash methods.'
5216
5256
  StyleGuide: '#hash-key'
@@ -5261,6 +5301,12 @@ Style/RandomWithOffset:
5261
5301
  Enabled: true
5262
5302
  VersionAdded: '0.52'
5263
5303
 
5304
+ Style/ReduceToHash:
5305
+ Description: 'Use `to_h { ... }` instead of `each_with_object`, `inject`, or `reduce` to build a hash.'
5306
+ Enabled: pending
5307
+ Safe: false
5308
+ VersionAdded: '1.85'
5309
+
5264
5310
  Style/RedundantArgument:
5265
5311
  Description: 'Checks for a redundant argument passed to certain methods.'
5266
5312
  Enabled: pending
@@ -5430,6 +5476,11 @@ Style/RedundantLineContinuation:
5430
5476
  Enabled: pending
5431
5477
  VersionAdded: '1.49'
5432
5478
 
5479
+ Style/RedundantMinMaxBy:
5480
+ Description: 'Identifies places where `max_by`/`min_by` can be replaced by `max`/`min`.'
5481
+ Enabled: pending
5482
+ VersionAdded: '1.85'
5483
+
5433
5484
  Style/RedundantParentheses:
5434
5485
  Description: "Checks for parentheses that seem not to serve any purpose."
5435
5486
  Enabled: true
@@ -5507,6 +5558,13 @@ Style/RedundantStringEscape:
5507
5558
  Enabled: pending
5508
5559
  VersionAdded: '1.37'
5509
5560
 
5561
+ Style/RedundantStructKeywordInit:
5562
+ Description: 'Checks for redundant `keyword_init` option for `Struct.new`.'
5563
+ Enabled: false
5564
+ SafeAutoCorrect: false
5565
+ VersionAdded: '1.85'
5566
+ VersionChanged: '1.86'
5567
+
5510
5568
  Style/RegexpLiteral:
5511
5569
  Description: 'Use / or %r around regular expressions.'
5512
5570
  StyleGuide: '#percent-r'
@@ -5613,8 +5671,20 @@ Style/Sample:
5613
5671
  Enabled: true
5614
5672
  VersionAdded: '0.30'
5615
5673
 
5674
+ Style/SelectByKind:
5675
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a kind check.'
5676
+ Enabled: pending
5677
+ SafeAutoCorrect: false
5678
+ VersionAdded: '1.85'
5679
+
5680
+ Style/SelectByRange:
5681
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a range check.'
5682
+ Enabled: pending
5683
+ SafeAutoCorrect: false
5684
+ VersionAdded: '1.85'
5685
+
5616
5686
  Style/SelectByRegexp:
5617
- Description: 'Prefer grep/grep_v to select/reject with a regexp match.'
5687
+ Description: 'Prefer grep/grep_v to select/reject/find/detect with a regexp match.'
5618
5688
  Enabled: pending
5619
5689
  SafeAutoCorrect: false
5620
5690
  VersionAdded: '1.22'
@@ -5873,6 +5943,12 @@ Style/SymbolProc:
5873
5943
  AllowedPatterns: []
5874
5944
  AllowComments: false
5875
5945
 
5946
+ Style/TallyMethod:
5947
+ Description: 'Prefer `Enumerable#tally` over manual counting patterns.'
5948
+ Enabled: pending
5949
+ Safe: false
5950
+ VersionAdded: '1.85'
5951
+
5876
5952
  Style/TernaryParentheses:
5877
5953
  Description: 'Checks for use of parentheses around ternary conditions.'
5878
5954
  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`.
@@ -153,7 +153,7 @@ module RuboCop
153
153
  def relative_path_to_todo_from_options_config
154
154
  return AUTO_GENERATED_FILE unless @options[:config]
155
155
 
156
- base = Pathname.new(Dir.pwd)
156
+ base = Pathname.new(PathUtil.pwd)
157
157
  config_dir = Pathname.new(@options[:config]).realpath.dirname
158
158
 
159
159
  # Don't have the path start with `/`
@@ -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
data/lib/rubocop/cli.rb CHANGED
@@ -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,7 +200,7 @@ module RuboCop
198
200
  RuboCop::LSP.enable if @options[:editor_mode]
199
201
  end
200
202
 
201
- # rubocop:disable Metrics/CyclomaticComplexity
203
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
202
204
  def handle_exiting_options
203
205
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
204
206
 
@@ -206,9 +208,10 @@ module RuboCop
206
208
  run_command(:show_cops) if @options[:show_cops]
207
209
  run_command(:show_docs_url) if @options[:show_docs_url]
208
210
  run_command(:lsp) if @options[:lsp]
211
+ run_command(:mcp) if @options[:mcp]
209
212
  raise Finished
210
213
  end
211
- # rubocop:enable Metrics/CyclomaticComplexity
214
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
212
215
 
213
216
  def apply_default_formatter
214
217
  # This must be done after the options have already been processed,
@@ -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
@@ -39,8 +39,10 @@ module RuboCop
39
39
  end
40
40
 
41
41
  def plugin_loaded?
42
- # Plugins loaded via `require` are included in `loaded_features`.
43
- config.loaded_plugins.include?(gem) || config.loaded_features.include?(gem)
42
+ # Plugins loaded via `plugins` are Plugin objects with an `about.name` attribute.
43
+ # Plugins loaded via `require` are included in `loaded_features` as strings.
44
+ config.loaded_plugins.any? { |plugin| plugin.about.name == gem } ||
45
+ config.loaded_features.include?(gem)
44
46
  end
45
47
  end
46
48
  end
@@ -49,7 +49,7 @@ module RuboCop
49
49
  end
50
50
 
51
51
  def for_pwd
52
- for_dir(Dir.pwd)
52
+ for_dir(PathUtil.pwd)
53
53
  end
54
54
 
55
55
  # If type (file/dir) is known beforehand,
@@ -9,7 +9,7 @@ module RuboCop
9
9
 
10
10
  # @api private
11
11
  COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
12
- Enabled Reference References].freeze
12
+ Enabled Reference References Safe SafeAutoCorrect].freeze
13
13
  # @api private
14
14
  INTERNAL_PARAMS = %w[Description StyleGuide
15
15
  VersionAdded VersionChanged VersionRemoved
@@ -16,7 +16,7 @@ module RuboCop
16
16
 
17
17
  def negated_condition(node)
18
18
  condition = node.condition
19
- condition = condition.children.first while condition.begin_type?
19
+ condition = condition.children.last while condition.begin_type?
20
20
  condition
21
21
  end
22
22
  end
@@ -97,8 +97,8 @@ module RuboCop
97
97
  if delimiters.first != delimiters.last
98
98
  # With different delimiters (eg. `[]`, `()`), if there are the same
99
99
  # number of each, escaping is not necessary
100
- delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
101
- counts[delimiter] = content.count(delimiter)
100
+ delimiter_counts = delimiters.to_h do |delimiter|
101
+ [delimiter, content.count(delimiter)]
102
102
  end
103
103
 
104
104
  return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
@@ -55,10 +55,9 @@ module RuboCop
55
55
 
56
56
  # @api private
57
57
  def builtin?(cop_class)
58
- # any custom method will do
59
- return false unless (m = cop_class.instance_methods(false).first)
58
+ return false unless (name = cop_class.name)
60
59
 
61
- path, _line = cop_class.instance_method(m).source_location
60
+ path, _line = Module.const_source_location(name)
62
61
  path.start_with?(__dir__)
63
62
  end
64
63
  end
@@ -92,7 +92,7 @@ module RuboCop
92
92
  (str "true")
93
93
  PATTERN
94
94
 
95
- def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
95
+ def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
96
96
  gem_specification(node) do |block_var|
97
97
  metadata_value = metadata(node)
98
98
  mfa_value = mfa_value(metadata_value)
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for missing `itblock` handlers. The blocks with the `it`
7
+ # parameter introduced in Ruby 3.4 are parsed with a node type of
8
+ # `itblock` instead of block. Cops that define `block` handlers
9
+ # need to define `itblock` handlers or disable this cop for them.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # class BlockRelatedCop < Base
15
+ # def on_block(node)
16
+ # end
17
+ # end
18
+ #
19
+ # # good
20
+ # class BlockRelatedCop < Base
21
+ # def on_block(node)
22
+ # end
23
+ #
24
+ # alias on_itblock on_block
25
+ # end
26
+ #
27
+ # class BlockRelatedCop < Base
28
+ # def on_block(node)
29
+ # end
30
+ #
31
+ # alias_method :on_itblock, :on_block
32
+ # end
33
+ #
34
+ # class BlockRelatedCop < Base
35
+ # def on_block(node)
36
+ # end
37
+ #
38
+ # def on_itblock(node)
39
+ # end
40
+ # end
41
+ class ItblockHandler < Base
42
+ MSG = 'Define on_itblock to handle blocks with the `it` parameter.'
43
+
44
+ def on_def(node)
45
+ return unless block_handler?(node)
46
+ return unless node.parent
47
+
48
+ add_offense(node) unless itblock_handler?(node.parent)
49
+ end
50
+
51
+ private
52
+
53
+ # @!method block_handler?(node)
54
+ def_node_matcher :block_handler?, <<~PATTERN
55
+ (def :on_block (args (arg :node)) ...)
56
+ PATTERN
57
+
58
+ # @!method itblock_handler?(node)
59
+ def_node_matcher :itblock_handler?, <<~PATTERN
60
+ {
61
+ `(def :on_itblock (args (arg :node)) ...)
62
+ `(alias (sym :on_itblock) (sym :on_block))
63
+ `(send nil? :alias_method (sym :on_itblock) (sym :on_block))
64
+ }
65
+ PATTERN
66
+ end
67
+ end
68
+ end
69
+ end
@@ -7,6 +7,7 @@ require_relative 'internal_affairs/empty_line_between_expect_offense_and_correct
7
7
  require_relative 'internal_affairs/example_description'
8
8
  require_relative 'internal_affairs/example_heredoc_delimiter'
9
9
  require_relative 'internal_affairs/inherit_deprecated_cop_class'
10
+ require_relative 'internal_affairs/itblock_handler'
10
11
  require_relative 'internal_affairs/lambda_or_proc'
11
12
  require_relative 'internal_affairs/location_exists'
12
13
  require_relative 'internal_affairs/location_expression'
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the arguments on a multi-line method call are aligned.
6
+ # Checks that the arguments on a multi-line method call are aligned.
7
7
  #
8
8
  # @example EnforcedStyle: with_first_argument (default)
9
9
  # # good
@@ -52,7 +52,7 @@ module RuboCop
52
52
  'following the first line of a multi-line method call.'
53
53
 
54
54
  def on_send(node)
55
- return if !multiple_arguments?(node) || (node.send_type? && node.method?(:[]=)) ||
55
+ return if !multiple_arguments?(node) || (node.call_type? && node.method?(:[]=)) ||
56
56
  autocorrect_incompatible_with_other_cops?
57
57
 
58
58
  items = flattened_arguments(node)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the elements of a multi-line array literal are
6
+ # Checks that the elements of a multi-line array literal are
7
7
  # aligned.
8
8
  #
9
9
  # @example EnforcedStyle: with_first_element (default)
@@ -112,7 +112,7 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def last_heredoc_line(node)
115
- if node.send_type?
115
+ if node.call_type?
116
116
  node.arguments.select { |arg| heredoc?(arg) }.map { |arg| arg.loc.heredoc_end.line }.max
117
117
  elsif heredoc?(node)
118
118
  node.loc.heredoc_end.line