rubocop 1.81.7 → 1.92.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 (621) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +626 -111
  5. data/config/obsoletion.yml +39 -1
  6. data/exe/rubocop +1 -1
  7. data/lib/rubocop/cache_config.rb +29 -0
  8. data/lib/rubocop/cached_data.rb +50 -5
  9. data/lib/rubocop/changed_files.rb +134 -0
  10. data/lib/rubocop/cli/command/auto_generate_config.rb +34 -2
  11. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  12. data/lib/rubocop/cli/command/execute_runner.rb +54 -3
  13. data/lib/rubocop/cli/command/explain.rb +34 -0
  14. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  15. data/lib/rubocop/cli/command/lsp.rb +1 -1
  16. data/lib/rubocop/cli/command/mcp.rb +19 -0
  17. data/lib/rubocop/cli/command/show_cops.rb +8 -2
  18. data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
  19. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  20. data/lib/rubocop/cli.rb +41 -14
  21. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  22. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  23. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  24. data/lib/rubocop/comment_config.rb +97 -44
  25. data/lib/rubocop/config.rb +100 -15
  26. data/lib/rubocop/config_finder.rb +1 -1
  27. data/lib/rubocop/config_loader.rb +49 -27
  28. data/lib/rubocop/config_loader_resolver.rb +95 -20
  29. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  30. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
  31. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  32. data/lib/rubocop/config_obsoletion.rb +1 -1
  33. data/lib/rubocop/config_store.rb +2 -2
  34. data/lib/rubocop/config_validator.rb +69 -7
  35. data/lib/rubocop/cop/autocorrect_logic.rb +24 -6
  36. data/lib/rubocop/cop/badge.rb +10 -2
  37. data/lib/rubocop/cop/base.rb +128 -35
  38. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
  39. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  40. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -10
  41. data/lib/rubocop/cop/bundler.rb +19 -0
  42. data/lib/rubocop/cop/commissioner.rb +13 -11
  43. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  44. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  45. data/lib/rubocop/cop/corrector.rb +4 -4
  46. data/lib/rubocop/cop/correctors/alignment_corrector.rb +87 -9
  47. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  48. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
  49. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  50. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
  51. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
  52. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  53. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +70 -2
  54. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  55. data/lib/rubocop/cop/correctors.rb +28 -0
  56. data/lib/rubocop/cop/documentation.rb +3 -4
  57. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  58. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  59. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  60. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +14 -4
  61. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -8
  62. data/lib/rubocop/cop/gemspec/require_mfa.rb +9 -6
  63. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  64. data/lib/rubocop/cop/gemspec.rb +22 -0
  65. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  66. data/lib/rubocop/cop/generator.rb +5 -1
  67. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  68. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  69. data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
  70. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  71. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +12 -16
  72. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  73. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  74. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
  75. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  76. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  77. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  78. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  79. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  80. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  81. data/lib/rubocop/cop/layout/argument_alignment.rb +9 -3
  82. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  83. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  84. data/lib/rubocop/cop/layout/block_alignment.rb +84 -4
  85. data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
  86. data/lib/rubocop/cop/layout/class_structure.rb +156 -41
  87. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  88. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  89. data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
  90. data/lib/rubocop/cop/layout/dot_position.rb +26 -16
  91. data/lib/rubocop/cop/layout/else_alignment.rb +2 -14
  92. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  93. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +25 -7
  94. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  95. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
  96. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +15 -2
  97. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  98. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
  99. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
  100. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +21 -5
  101. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  102. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  103. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  104. data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
  105. data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
  106. data/lib/rubocop/cop/layout/first_argument_indentation.rb +81 -2
  107. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  108. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
  109. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
  110. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  111. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  112. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  113. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  114. data/lib/rubocop/cop/layout/hash_alignment.rb +16 -11
  115. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -4
  116. data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
  117. data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
  118. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  119. data/lib/rubocop/cop/layout/indentation_width.rb +158 -12
  120. data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
  121. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
  122. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  123. data/lib/rubocop/cop/layout/line_length.rb +265 -29
  124. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
  125. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  126. data/lib/rubocop/cop/layout/multiline_block_layout.rb +10 -1
  127. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
  128. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
  129. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +268 -38
  130. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  131. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  132. data/lib/rubocop/cop/layout/redundant_line_break.rb +102 -2
  133. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +19 -5
  134. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  135. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  136. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  137. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  138. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  139. data/lib/rubocop/cop/layout/space_around_keyword.rb +14 -2
  140. data/lib/rubocop/cop/layout/space_around_operators.rb +18 -3
  141. data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
  142. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  143. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  144. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +44 -34
  145. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
  146. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
  147. data/lib/rubocop/cop/layout.rb +114 -0
  148. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  149. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  150. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  151. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  152. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
  153. data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
  154. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
  155. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  156. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  157. data/lib/rubocop/cop/lint/circular_argument_reference.rb +45 -3
  158. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  159. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  160. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  161. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +165 -15
  162. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  163. data/lib/rubocop/cop/lint/debugger.rb +13 -2
  164. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  165. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  166. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  167. data/lib/rubocop/cop/lint/duplicate_methods.rb +405 -28
  168. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  169. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  170. data/lib/rubocop/cop/lint/empty_conditional_body.rb +9 -2
  171. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  172. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  173. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  174. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
  175. data/lib/rubocop/cop/lint/float_comparison.rb +2 -1
  176. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
  177. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  178. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  179. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  180. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  181. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  182. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  183. data/lib/rubocop/cop/lint/literal_as_condition.rb +36 -9
  184. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  185. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
  186. data/lib/rubocop/cop/lint/loop.rb +24 -2
  187. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  188. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +46 -18
  189. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  190. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  191. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  192. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  193. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  194. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  195. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  196. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  197. data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
  198. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  199. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +10 -0
  200. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  201. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  202. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  203. data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
  204. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  205. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
  206. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  207. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
  208. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -4
  209. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +37 -14
  210. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  211. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +11 -5
  212. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -3
  213. data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
  214. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  215. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  216. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  217. data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
  218. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  219. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  220. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +24 -0
  221. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
  222. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  223. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  224. data/lib/rubocop/cop/lint/self_assignment.rb +33 -2
  225. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  226. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  227. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
  228. data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
  229. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  230. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  231. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +13 -2
  232. data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
  233. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  234. data/lib/rubocop/cop/lint/to_enum_arguments.rb +72 -4
  235. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  236. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  237. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  238. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
  239. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  240. data/lib/rubocop/cop/lint/unreachable_code.rb +15 -9
  241. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  242. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  243. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  244. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
  245. data/lib/rubocop/cop/lint/useless_assignment.rb +61 -27
  246. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +40 -4
  247. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  248. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  249. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +10 -10
  250. data/lib/rubocop/cop/lint/useless_or.rb +15 -2
  251. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
  252. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +10 -4
  253. data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
  254. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  255. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +94 -14
  256. data/lib/rubocop/cop/lint/void.rb +59 -22
  257. data/lib/rubocop/cop/lint.rb +179 -0
  258. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  259. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  260. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  261. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  262. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  263. data/lib/rubocop/cop/metrics/method_length.rb +2 -2
  264. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  265. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  266. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  267. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  268. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  269. data/lib/rubocop/cop/metrics.rb +31 -0
  270. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  271. data/lib/rubocop/cop/migration.rb +13 -0
  272. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  273. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  274. data/lib/rubocop/cop/mixin/allowed_pattern.rb +5 -1
  275. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  276. data/lib/rubocop/cop/mixin/check_line_breakable.rb +47 -25
  277. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +12 -8
  278. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  279. data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
  280. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  281. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  282. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
  283. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
  284. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  285. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
  286. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +5 -1
  287. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +58 -12
  288. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +37 -10
  289. data/lib/rubocop/cop/mixin/hash_subset.rb +9 -2
  290. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  291. data/lib/rubocop/cop/mixin/hash_transform_method.rb +14 -60
  292. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  293. data/lib/rubocop/cop/mixin/line_length_help.rb +28 -3
  294. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  295. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  296. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  297. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  298. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
  299. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  300. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  301. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
  302. data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
  303. data/lib/rubocop/cop/mixin/range_help.rb +1 -2
  304. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
  305. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  306. data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
  307. data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -6
  308. data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
  309. data/lib/rubocop/cop/mixin.rb +93 -0
  310. data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
  311. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  312. data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
  313. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  314. data/lib/rubocop/cop/naming/file_name.rb +4 -3
  315. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  316. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  317. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  318. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -5
  319. data/lib/rubocop/cop/naming/method_name.rb +6 -3
  320. data/lib/rubocop/cop/naming/predicate_method.rb +13 -2
  321. data/lib/rubocop/cop/naming/predicate_prefix.rb +30 -17
  322. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
  323. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  324. data/lib/rubocop/cop/naming.rb +31 -0
  325. data/lib/rubocop/cop/offense.rb +108 -9
  326. data/lib/rubocop/cop/registry.rb +232 -66
  327. data/lib/rubocop/cop/security/eval.rb +15 -2
  328. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  329. data/lib/rubocop/cop/security/json_load.rb +16 -4
  330. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  331. data/lib/rubocop/cop/security.rb +19 -0
  332. data/lib/rubocop/cop/severity.rb +12 -0
  333. data/lib/rubocop/cop/style/access_modifier_declarations.rb +55 -8
  334. data/lib/rubocop/cop/style/accessor_grouping.rb +16 -5
  335. data/lib/rubocop/cop/style/alias.rb +33 -8
  336. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  337. data/lib/rubocop/cop/style/and_or.rb +8 -3
  338. data/lib/rubocop/cop/style/arguments_forwarding.rb +61 -17
  339. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  340. data/lib/rubocop/cop/style/array_intersect.rb +28 -5
  341. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +3 -0
  342. data/lib/rubocop/cop/style/array_join.rb +4 -2
  343. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  344. data/lib/rubocop/cop/style/attr.rb +8 -6
  345. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  346. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  347. data/lib/rubocop/cop/style/bitwise_predicate.rb +7 -6
  348. data/lib/rubocop/cop/style/block_delimiters.rb +74 -38
  349. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  350. data/lib/rubocop/cop/style/case_like_if.rb +11 -10
  351. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  352. data/lib/rubocop/cop/style/class_and_module_children.rb +151 -35
  353. data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
  354. data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
  355. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  356. data/lib/rubocop/cop/style/collection_querying.rb +79 -46
  357. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  358. data/lib/rubocop/cop/style/combinable_loops.rb +91 -9
  359. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  360. data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
  361. data/lib/rubocop/cop/style/conditional_assignment.rb +34 -18
  362. data/lib/rubocop/cop/style/constant_visibility.rb +13 -7
  363. data/lib/rubocop/cop/style/copyright.rb +27 -12
  364. data/lib/rubocop/cop/style/data_inheritance.rb +18 -0
  365. data/lib/rubocop/cop/style/date_time.rb +4 -4
  366. data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -2
  367. data/lib/rubocop/cop/style/dig_chain.rb +5 -0
  368. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  369. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  370. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
  371. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  372. data/lib/rubocop/cop/style/documentation.rb +53 -6
  373. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  374. data/lib/rubocop/cop/style/double_negation.rb +11 -0
  375. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  376. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  377. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  378. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  379. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  380. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  381. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  382. data/lib/rubocop/cop/style/empty_literal.rb +8 -3
  383. data/lib/rubocop/cop/style/empty_method.rb +15 -9
  384. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +74 -22
  385. data/lib/rubocop/cop/style/encoding.rb +7 -1
  386. data/lib/rubocop/cop/style/end_block.rb +3 -1
  387. data/lib/rubocop/cop/style/endless_method.rb +100 -21
  388. data/lib/rubocop/cop/style/env_home.rb +4 -0
  389. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  390. data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
  391. data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
  392. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  393. data/lib/rubocop/cop/style/file_null.rb +6 -4
  394. data/lib/rubocop/cop/style/file_open.rb +84 -0
  395. data/lib/rubocop/cop/style/file_write.rb +21 -16
  396. data/lib/rubocop/cop/style/float_division.rb +28 -14
  397. data/lib/rubocop/cop/style/for.rb +60 -1
  398. data/lib/rubocop/cop/style/format_string.rb +44 -9
  399. data/lib/rubocop/cop/style/format_string_token.rb +50 -7
  400. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  401. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  402. data/lib/rubocop/cop/style/guard_clause.rb +57 -40
  403. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
  404. data/lib/rubocop/cop/style/hash_conversion.rb +39 -11
  405. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
  406. data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
  407. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  408. data/lib/rubocop/cop/style/hash_syntax.rb +19 -5
  409. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  410. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  411. data/lib/rubocop/cop/style/identical_conditional_branches.rb +38 -10
  412. data/lib/rubocop/cop/style/if_inside_else.rb +36 -8
  413. data/lib/rubocop/cop/style/if_unless_modifier.rb +80 -76
  414. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +17 -14
  415. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
  416. data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
  417. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  418. data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
  419. data/lib/rubocop/cop/style/invertible_unless_condition.rb +25 -5
  420. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  421. data/lib/rubocop/cop/style/it_block_parameter.rb +94 -4
  422. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  423. data/lib/rubocop/cop/style/keyword_parameters_order.rb +10 -4
  424. data/lib/rubocop/cop/style/lambda.rb +45 -2
  425. data/lib/rubocop/cop/style/lambda_call.rb +24 -8
  426. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  427. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  428. data/lib/rubocop/cop/style/map_into_array.rb +2 -3
  429. data/lib/rubocop/cop/style/map_join.rb +123 -0
  430. data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
  431. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +102 -20
  432. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  433. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +42 -6
  434. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
  435. data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
  436. data/lib/rubocop/cop/style/min_max_comparison.rb +4 -1
  437. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  438. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  439. data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
  440. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  441. data/lib/rubocop/cop/style/module_function.rb +4 -2
  442. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  443. data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
  444. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  445. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  446. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  447. data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -13
  448. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  449. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  450. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  451. data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
  452. data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
  453. data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
  454. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  455. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  456. data/lib/rubocop/cop/style/next.rb +24 -10
  457. data/lib/rubocop/cop/style/nil_comparison.rb +50 -12
  458. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  459. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  460. data/lib/rubocop/cop/style/not.rb +12 -3
  461. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  462. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  463. data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
  464. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  465. data/lib/rubocop/cop/style/one_line_conditional.rb +18 -6
  466. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  467. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  468. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  469. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  470. data/lib/rubocop/cop/style/parallel_assignment.rb +26 -7
  471. data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
  472. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  473. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
  474. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  475. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  476. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  477. data/lib/rubocop/cop/style/proc.rb +3 -2
  478. data/lib/rubocop/cop/style/raise_args.rb +20 -10
  479. data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
  480. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  481. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  482. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  483. data/lib/rubocop/cop/style/redundant_begin.rb +25 -7
  484. data/lib/rubocop/cop/style/redundant_condition.rb +41 -23
  485. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  486. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +13 -1
  487. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
  488. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  489. data/lib/rubocop/cop/style/redundant_exception.rb +21 -3
  490. data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
  491. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  492. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  493. data/lib/rubocop/cop/style/redundant_format.rb +43 -7
  494. data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
  495. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  496. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
  497. data/lib/rubocop/cop/style/redundant_line_continuation.rb +82 -115
  498. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  499. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -83
  500. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  501. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +13 -2
  502. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  503. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
  504. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -4
  505. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  506. data/lib/rubocop/cop/style/redundant_self.rb +11 -2
  507. data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
  508. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
  509. data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
  510. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  511. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  512. data/lib/rubocop/cop/style/regexp_literal.rb +106 -28
  513. data/lib/rubocop/cop/style/require_order.rb +25 -8
  514. data/lib/rubocop/cop/style/rescue_modifier.rb +15 -14
  515. data/lib/rubocop/cop/style/return_nil.rb +17 -2
  516. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  517. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  518. data/lib/rubocop/cop/style/safe_navigation.rb +18 -9
  519. data/lib/rubocop/cop/style/sample.rb +19 -13
  520. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  521. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  522. data/lib/rubocop/cop/style/select_by_regexp.rb +52 -23
  523. data/lib/rubocop/cop/style/self_assignment.rb +13 -16
  524. data/lib/rubocop/cop/style/semicolon.rb +39 -13
  525. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
  526. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  527. data/lib/rubocop/cop/style/single_line_do_end_block.rb +19 -7
  528. data/lib/rubocop/cop/style/single_line_methods.rb +24 -5
  529. data/lib/rubocop/cop/style/sole_nested_conditional.rb +25 -7
  530. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  531. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +31 -5
  532. data/lib/rubocop/cop/style/static_class.rb +21 -0
  533. data/lib/rubocop/cop/style/string_concatenation.rb +25 -6
  534. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  535. data/lib/rubocop/cop/style/struct_inheritance.rb +36 -1
  536. data/lib/rubocop/cop/style/super_arguments.rb +6 -4
  537. data/lib/rubocop/cop/style/symbol_proc.rb +32 -14
  538. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  539. data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
  540. data/lib/rubocop/cop/style/time_now.rb +41 -0
  541. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  542. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  543. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  544. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
  545. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  546. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  547. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  548. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  549. data/lib/rubocop/cop/style/word_array.rb +1 -0
  550. data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
  551. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  552. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  553. data/lib/rubocop/cop/style.rb +311 -0
  554. data/lib/rubocop/cop/team.rb +171 -48
  555. data/lib/rubocop/cop/util.rb +5 -8
  556. data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
  557. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  558. data/lib/rubocop/cop/variable_force/variable.rb +33 -9
  559. data/lib/rubocop/cops_documentation_generator.rb +27 -9
  560. data/lib/rubocop/directive_comment.rb +116 -7
  561. data/lib/rubocop/feature_loader.rb +0 -6
  562. data/lib/rubocop/file_patterns.rb +9 -1
  563. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  564. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  565. data/lib/rubocop/formatter/disabled_config_formatter.rb +39 -10
  566. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  567. data/lib/rubocop/formatter/formatter_set.rb +7 -2
  568. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  569. data/lib/rubocop/formatter/html_formatter.rb +2 -4
  570. data/lib/rubocop/formatter/json_formatter.rb +82 -7
  571. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  572. data/lib/rubocop/formatter/offense_count_formatter.rb +4 -3
  573. data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
  574. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  575. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  576. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  577. data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
  578. data/lib/rubocop/formatter.rb +23 -21
  579. data/lib/rubocop/lockfile.rb +18 -0
  580. data/lib/rubocop/lsp/diagnostic.rb +22 -42
  581. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  582. data/lib/rubocop/lsp/routes.rb +130 -83
  583. data/lib/rubocop/lsp/runtime.rb +64 -15
  584. data/lib/rubocop/lsp/server.rb +6 -2
  585. data/lib/rubocop/lsp/stdin_runner.rb +35 -2
  586. data/lib/rubocop/lsp.rb +5 -2
  587. data/lib/rubocop/magic_comment.rb +47 -0
  588. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  589. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  590. data/lib/rubocop/mcp/scope.rb +65 -0
  591. data/lib/rubocop/mcp/server.rb +307 -0
  592. data/lib/rubocop/mcp/source_files.rb +35 -0
  593. data/lib/rubocop/offense_limit.rb +30 -0
  594. data/lib/rubocop/options.rb +141 -13
  595. data/lib/rubocop/path_util.rb +16 -5
  596. data/lib/rubocop/pending_cops_reporter.rb +1 -6
  597. data/lib/rubocop/plugin/configuration_integrator.rb +13 -3
  598. data/lib/rubocop/plugin/loader.rb +2 -2
  599. data/lib/rubocop/project_index_loader.rb +82 -0
  600. data/lib/rubocop/rake_task.rb +2 -3
  601. data/lib/rubocop/remote_config.rb +18 -13
  602. data/lib/rubocop/result_cache.rb +102 -59
  603. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  604. data/lib/rubocop/rspec/expect_offense.rb +2 -4
  605. data/lib/rubocop/rspec/shared_contexts.rb +53 -5
  606. data/lib/rubocop/rspec/support.rb +2 -1
  607. data/lib/rubocop/runner.rb +362 -106
  608. data/lib/rubocop/server/cache.rb +21 -40
  609. data/lib/rubocop/server/cli.rb +2 -4
  610. data/lib/rubocop/server/core.rb +8 -0
  611. data/lib/rubocop/server.rb +14 -0
  612. data/lib/rubocop/target_finder.rb +18 -8
  613. data/lib/rubocop/target_ruby.rb +42 -22
  614. data/lib/rubocop/todo_audit.rb +111 -0
  615. data/lib/rubocop/unified_diff.rb +257 -0
  616. data/lib/rubocop/util.rb +69 -0
  617. data/lib/rubocop/version.rb +23 -7
  618. data/lib/rubocop.rb +34 -701
  619. data/lib/ruby_lsp/rubocop/addon.rb +1 -2
  620. metadata +80 -14
  621. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
@@ -2,7 +2,7 @@
2
2
 
3
3
  # FIXME: Moving Rails department code to RuboCop Rails will remove
4
4
  # the following rubocop:disable comment.
5
- # rubocop:disable Metrics/ClassLength
5
+ # rubocop:disable-next Metrics/ClassLength
6
6
  module RuboCop
7
7
  # This class represents the configuration of the RuboCop application
8
8
  # and all its cops. A Config is associated with a YAML configuration
@@ -27,7 +27,7 @@ module RuboCop
27
27
  config
28
28
  end
29
29
 
30
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
30
+ # rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
31
31
  def initialize(hash = RuboCop::ConfigLoader.default_configuration, loaded_path = nil)
32
32
  @loaded_path = loaded_path
33
33
  @for_cop = Hash.new do |h, cop|
@@ -72,7 +72,6 @@ module RuboCop
72
72
  @badge_config_cache = {}.compare_by_identity
73
73
  @clusivity_config_exists_cache = {}
74
74
  end
75
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
76
75
 
77
76
  def loaded_plugins
78
77
  @loaded_plugins ||= ConfigLoader.loaded_plugins
@@ -168,7 +167,11 @@ module RuboCop
168
167
  department_config = self[badge.department_name]
169
168
  cop_config = for_cop(badge.to_s)
170
169
  if department_config
171
- department_config.merge(cop_config)
170
+ merged_config = department_config.merge(cop_config)
171
+ if department_config['Exclude'] && cop_config['Exclude']
172
+ merged_config['Exclude'] = department_config['Exclude'] | cop_config['Exclude']
173
+ end
174
+ merged_config
172
175
  else
173
176
  cop_config
174
177
  end
@@ -209,6 +212,30 @@ module RuboCop
209
212
  for_all_cops['NewCops'] == 'enable'
210
213
  end
211
214
 
215
+ # Whether the given pending cop should be enabled, based on the `NewCops` setting of
216
+ # its department (if any) or of `AllCops`. A department may set `NewCops` to `enable`,
217
+ # `disable`, `pending`, or a version, in which case pending cops added in that version
218
+ # or earlier are enabled.
219
+ def enabled_new_cop?(qualified_cop_name)
220
+ setting = new_cops_setting_for(qualified_cop_name)
221
+
222
+ case setting.to_s
223
+ when 'enable' then true
224
+ when '', 'pending', 'disable' then false
225
+ else new_cops_version_covers?(setting, qualified_cop_name)
226
+ end
227
+ end
228
+
229
+ # Whether preview behavior is on, for cops that gate an unstable change
230
+ # behind it and for cops that are themselves `Enabled: preview`.
231
+ # `--preview` / `--no-preview` win over `AllCops: Preview`.
232
+ def preview?(options = {})
233
+ preview = options[:preview]
234
+ return preview unless preview.nil?
235
+
236
+ for_all_cops['Preview'] == true
237
+ end
238
+
212
239
  def active_support_extensions_enabled?
213
240
  for_all_cops['ActiveSupportExtensionsEnabled']
214
241
  end
@@ -217,6 +244,9 @@ module RuboCop
217
244
  for_all_cops['StringLiteralsFrozenByDefault']
218
245
  end
219
246
 
247
+ # Returns true if the file matches any include pattern. If a block is given, the block is called
248
+ # to determine if the pattern is relevant (true returned by the block) or should be skipped
249
+ # (false returned).
220
250
  def file_to_include?(file)
221
251
  relative_file_path = path_relative_to_config(file)
222
252
 
@@ -228,11 +258,9 @@ module RuboCop
228
258
  absolute_file_path = File.expand_path(file)
229
259
 
230
260
  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
261
+ next if block_given? && !yield(pattern)
262
+
263
+ match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
236
264
  end
237
265
  end
238
266
 
@@ -242,10 +270,7 @@ module RuboCop
242
270
  # `bundler-console` conveys `Bundler::Console`).
243
271
  return true if File.extname(file) == '.gemspec'
244
272
 
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
273
+ file_to_include?(file) { |pattern| /[A-Z]/.match?(pattern.to_s) }
249
274
  end
250
275
 
251
276
  # Returns true if there's a chance that an Include pattern matches hidden
@@ -286,7 +311,7 @@ module RuboCop
286
311
  loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
287
312
  File.expand_path(File.dirname(loaded_path))
288
313
  else
289
- Dir.pwd
314
+ PathUtil.pwd
290
315
  end
291
316
  end
292
317
 
@@ -328,6 +353,7 @@ module RuboCop
328
353
 
329
354
  cop_metadata = self[qualified_cop_name]
330
355
  next unless cop_metadata['Enabled'] == 'pending'
356
+ next if new_cops_covered?(qualified_cop_name)
331
357
 
332
358
  pending_cops << CopConfig.new(qualified_cop_name, cop_metadata)
333
359
  end
@@ -339,12 +365,26 @@ module RuboCop
339
365
  @gem_versions_in_target ||= read_gem_versions_from_target_lockfile
340
366
  end
341
367
 
368
+ # Returns the names of the target's gems that are sourced from a local path
369
+ # (i.e. `path:` dependencies and the project's own gem when the `Gemfile`
370
+ # uses `gemspec`), whose code therefore lives in the project itself.
371
+ # @returns [Array<String>, nil] The gem names, or nil without a lockfile.
372
+ def path_sourced_gems_in_target
373
+ @path_sourced_gems_in_target ||= read_path_sourced_gems_from_target_lockfile
374
+ end
375
+
342
376
  def inspect # :nodoc:
343
377
  "#<#{self.class.name}:#{object_id} @loaded_path=#{loaded_path}>"
344
378
  end
345
379
 
346
380
  private
347
381
 
382
+ def match_relative_or_absolute_path?(pattern, relative_file_path, absolute_file_path)
383
+ should_use_absolute_path = absolute?(pattern.to_s) || pattern.to_s.start_with?('..') ||
384
+ relative_file_path.start_with?('..')
385
+ match_path?(pattern, should_use_absolute_path ? absolute_file_path : relative_file_path)
386
+ end
387
+
348
388
  # @return [Float, nil] The Rails version as a `major.minor` Float.
349
389
  def target_rails_version_from_bundler_lock_file
350
390
  @target_rails_version_from_bundler_lock_file ||= read_rails_version_from_bundler_lock_file
@@ -377,6 +417,14 @@ module RuboCop
377
417
  Lockfile.new(lockfile_path).gem_versions
378
418
  end
379
419
 
420
+ # @returns [Array<String>, nil] The names of the gems sourced from a local path.
421
+ def read_path_sourced_gems_from_target_lockfile
422
+ lockfile_path = bundler_lock_file_path
423
+ return nil unless lockfile_path
424
+
425
+ Lockfile.new(lockfile_path).path_sourced_gem_names
426
+ end
427
+
380
428
  def enable_cop?(qualified_cop_name, cop_options)
381
429
  # If the cop is explicitly enabled or `Lint/Syntax`, the other checks can be skipped.
382
430
  return true if cop_options['Enabled'] == true || qualified_cop_name == 'Lint/Syntax'
@@ -395,6 +443,43 @@ module RuboCop
395
443
 
396
444
  self[cop_department.join('/')]
397
445
  end
446
+
447
+ # The effective `NewCops` setting for the given cop: the department-level
448
+ # setting if present, otherwise the `AllCops` setting.
449
+ def new_cops_setting_for(qualified_cop_name)
450
+ department = department_of(qualified_cop_name)
451
+ setting = department['NewCops'] if department
452
+
453
+ setting || for_all_cops['NewCops']
454
+ end
455
+
456
+ # Whether the cop's pending status is resolved by a `NewCops` setting,
457
+ # so that it should not appear in the pending cops warning.
458
+ # Unlike `enabled_new_cop?`, `disable` counts as covered.
459
+ def new_cops_covered?(qualified_cop_name)
460
+ setting = new_cops_setting_for(qualified_cop_name)
461
+
462
+ case setting.to_s
463
+ when 'enable', 'disable' then true
464
+ when '', 'pending' then false
465
+ else new_cops_version_covers?(setting, qualified_cop_name)
466
+ end
467
+ end
468
+
469
+ def new_cops_version_covers?(new_cops_version, qualified_cop_name)
470
+ cop_metadata = self[qualified_cop_name]
471
+ version_added = comparable_version(cop_metadata['VersionAdded']) if cop_metadata
472
+ pinned_version = comparable_version(new_cops_version)
473
+ return false if version_added.nil? || pinned_version.nil?
474
+
475
+ version_added <= pinned_version
476
+ end
477
+
478
+ # Returns a `Gem::Version` for values like `'1.19'` or `1.19`, and `nil`
479
+ # for non-version values like `'N/A'` or `'<<next>>'`.
480
+ def comparable_version(value)
481
+ value = value.to_s
482
+ Gem::Version.new(value) if value.match?(/\A\d/) && Gem::Version.correct?(value)
483
+ end
398
484
  end
399
485
  end
400
- # rubocop:enable Metrics/ClassLength
@@ -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
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'erb'
4
4
  require 'yaml'
5
+ require_relative 'cache_config'
5
6
  require_relative 'config_finder'
6
7
 
7
8
  module RuboCop
@@ -23,25 +24,34 @@ module RuboCop
23
24
  include FileFinder
24
25
 
25
26
  attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
26
- :ignore_unrecognized_cops
27
- attr_writer :default_configuration
27
+ :enabled_by_default, :disabled_by_default, :ignore_unrecognized_cops,
28
+ :preview
29
+ attr_writer :default_configuration, :cache_root
28
30
  attr_reader :loaded_plugins, :loaded_features
29
31
 
30
32
  alias debug? debug
31
33
  alias ignore_parent_exclusion? ignore_parent_exclusion
32
34
 
35
+ def cache_root(cache_root_override = nil)
36
+ @cache_root ||= CacheConfig.root_dir_from_toplevel_config(cache_root_override)
37
+ end
38
+
33
39
  def clear_options
34
40
  @debug = nil
35
41
  @loaded_plugins = Set.new
36
42
  @loaded_features = Set.new
37
43
  @disable_pending_cops = nil
38
44
  @enable_pending_cops = nil
45
+ @preview = nil
46
+ @enabled_by_default = nil
47
+ @disabled_by_default = nil
39
48
  @ignore_parent_exclusion = nil
40
49
  @ignore_unrecognized_cops = nil
50
+ @cache_root = nil
41
51
  FileFinder.root_level = nil
42
52
  end
43
53
 
44
- # rubocop:disable Metrics/AbcSize
54
+ # rubocop:disable-next Metrics/AbcSize
45
55
  def load_file(file, check: true)
46
56
  path = file_path(file)
47
57
 
@@ -65,7 +75,6 @@ module RuboCop
65
75
 
66
76
  Config.create(hash, path, check: check)
67
77
  end
68
- # rubocop:enable Metrics/AbcSize
69
78
 
70
79
  def load_yaml_configuration(absolute_path)
71
80
  file_contents = read_file(absolute_path)
@@ -115,7 +124,7 @@ module RuboCop
115
124
  end
116
125
 
117
126
  def configuration_from_file(config_file, check: true)
118
- return default_configuration if config_file == DEFAULT_FILE
127
+ return apply_default_overrides(default_configuration) if config_file == DEFAULT_FILE
119
128
 
120
129
  config = load_file(config_file, check: check)
121
130
  config.validate_after_resolution if check
@@ -150,31 +159,23 @@ module RuboCop
150
159
  # When testing a plugin using `rubocop/rspec/support`, the plugin is loaded automatically,
151
160
  # so this API is usually not needed. It is intended to be used only when implementing tests
152
161
  # that do not use `rubocop/rspec/support`.
153
- # rubocop:disable Metrics/MethodLength
154
162
  def inject_defaults!(config_yml_path)
155
163
  if Pathname(config_yml_path).directory?
156
- # TODO: Since the warning noise is expected to be high until some time after the release,
157
- # warnings will only be issued when `RUBYOPT=-w` is specified.
158
- # To proceed step by step, the next step is to remove `$VERBOSE` and always issue warning.
159
- # Eventually, `project_root` will no longer be accepted.
160
- if $VERBOSE
161
- warn Rainbow(<<~MESSAGE).yellow, uplevel: 1
162
- Use config YAML file path instead of project root directory.
163
- e.g., `path/to/config/default.yml`
164
- MESSAGE
165
- end
166
- # NOTE: For compatibility.
167
- project_root = config_yml_path
168
- path = File.join(project_root, 'config', 'default.yml')
169
- config = load_file(path)
170
- else
171
- hash = ConfigLoader.load_yaml_configuration(config_yml_path.to_s)
172
- config = Config.new(hash, config_yml_path).tap(&:make_excludes_absolute)
164
+ warn Rainbow(<<~MESSAGE).yellow, uplevel: 1
165
+ Use config YAML file path instead of project root directory.
166
+ e.g., `path/to/config/default.yml`
167
+ MESSAGE
168
+ raise ArgumentError,
169
+ 'Passing a project root directory to `inject_defaults!` is no longer supported.'
173
170
  end
174
171
 
175
- @default_configuration = ConfigLoader.merge_with_default(config, path)
172
+ path = config_yml_path.to_s
173
+ hash = ConfigLoader.load_yaml_configuration(path)
174
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
175
+
176
+ @default_configuration =
177
+ ConfigLoader.merge_with_default(config, path, resolve_preview: false)
176
178
  end
177
- # rubocop:enable Metrics/MethodLength
178
179
 
179
180
  # Returns the path RuboCop inferred as the root of the project. No file
180
181
  # searches will go past this directory.
@@ -189,8 +190,29 @@ module RuboCop
189
190
  end
190
191
 
191
192
  # Merges the given configuration with the default one.
192
- def merge_with_default(config, config_file, unset_nil: true)
193
- resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
193
+ def merge_with_default(config, config_file, unset_nil: true, resolve_preview: true)
194
+ resolver.merge_with_default(
195
+ config, config_file, unset_nil: unset_nil, resolve_preview: resolve_preview
196
+ )
197
+ end
198
+
199
+ # Applies CLI overrides for `AllCops/EnabledByDefault` and
200
+ # `AllCops/DisabledByDefault` to the given configuration. Used when the
201
+ # configuration would otherwise be returned without going through
202
+ # `merge_with_default` (e.g. there is no user-supplied `.rubocop.yml`).
203
+ # Used when there is no configuration file, so the defaults are the whole
204
+ # configuration and still need the same treatment `merge_with_default`
205
+ # would have given them.
206
+ def apply_default_overrides(config)
207
+ hash = resolver.apply_preview_defaults(config, preview == true)
208
+
209
+ unless @enabled_by_default.nil? && @disabled_by_default.nil?
210
+ hash = hash.transform_values do |params|
211
+ params.is_a?(Hash) ? params.merge('Enabled' => !@disabled_by_default) : params
212
+ end
213
+ end
214
+
215
+ Config.new(hash, config.loaded_path)
194
216
  end
195
217
 
196
218
  # @api private
@@ -37,22 +37,24 @@ module RuboCop
37
37
 
38
38
  def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
39
39
  inherited_files = Array(hash['inherit_from'])
40
- base_configs(path, inherited_files, file)
41
- .each_with_index.reverse_each do |base_config, index|
40
+ base_configs = base_configs(path, inherited_files, file)
41
+ preview = inherited_preview?(hash, base_configs)
42
+ base_configs.each_with_index.reverse_each do |base_config, index|
42
43
  override_department_setting_for_cops(base_config, hash)
43
44
  override_enabled_for_disabled_departments(base_config, hash)
44
45
 
45
46
  base_config.each do |k, v|
46
47
  next unless v.is_a?(Hash)
47
48
 
49
+ only_base_has_include = v.key?('Include') && !hash.dig(k, 'Include')
48
50
  if hash.key?(k)
49
51
  v = merge(v, hash[k],
50
52
  cop_name: k, file: file, debug: debug,
51
53
  inherited_file: inherited_files[index],
52
- inherit_mode: determine_inherit_mode(hash, k))
54
+ inherit_mode: determine_inherit_mode(hash, k, preview))
53
55
  end
54
56
  hash[k] = v
55
- fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
57
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if only_base_has_include
56
58
  end
57
59
  end
58
60
  end
@@ -91,22 +93,30 @@ module RuboCop
91
93
  # only cops from user configuration are enabled. If
92
94
  # AllCops:EnabledByDefault is true, it changes the Enabled params so that
93
95
  # only cops explicitly disabled in user configuration are disabled.
94
- def merge_with_default(config, config_file, unset_nil:)
95
- default_configuration = ConfigLoader.default_configuration
96
-
97
- disabled_by_default = config.for_all_cops['DisabledByDefault']
98
- enabled_by_default = config.for_all_cops['EnabledByDefault']
96
+ # When the `--disable-all-cops` or `--enable-all-cops` CLI option is given,
97
+ # it takes precedence over the configuration values.
98
+ #
99
+ # With `resolve_preview: false` the `Preview` sections of the default
100
+ # configuration are left in place and preview is treated as off. That is
101
+ # what extending the default configuration itself needs: preview gets
102
+ # applied later, when a project configuration is resolved against it.
103
+ def merge_with_default(config, config_file, unset_nil:, resolve_preview: true)
104
+ base_defaults, preview = defaults_with_preview(config, resolve_preview)
105
+ default_configuration = base_defaults
106
+ disabled_by_default, enabled_by_default = resolve_default_overrides(config)
99
107
 
100
108
  if disabled_by_default || enabled_by_default
101
- default_configuration = transform(default_configuration) do |params|
109
+ default_configuration = transform(base_defaults) do |params|
102
110
  params.merge('Enabled' => !disabled_by_default)
103
111
  end
104
112
  end
105
113
 
106
- config = handle_disabled_by_default(config, default_configuration) if disabled_by_default
114
+ if disabled_by_default
115
+ config = handle_disabled_by_default(config, default_configuration, base_defaults)
116
+ end
107
117
  override_enabled_for_disabled_departments(default_configuration, config)
108
118
 
109
- opts = { inherit_mode: config['inherit_mode'] || {}, unset_nil: unset_nil }
119
+ opts = { inherit_mode: inherit_mode_for_default(config, preview), unset_nil: unset_nil }
110
120
  Config.new(merge(default_configuration, config, **opts), config_file)
111
121
  end
112
122
 
@@ -114,7 +124,7 @@ module RuboCop
114
124
  # with the addition that any value that is a hash, and occurs in both
115
125
  # arguments, will also be merged. And so on.
116
126
  #
117
- # rubocop:disable Metrics/AbcSize
127
+ # rubocop:disable-next Metrics/AbcSize
118
128
  def merge(base_hash, derived_hash, **opts)
119
129
  result = base_hash.merge(derived_hash)
120
130
  keys_appearing_in_both = base_hash.keys & derived_hash.keys
@@ -131,7 +141,6 @@ module RuboCop
131
141
  end
132
142
  result
133
143
  end
134
- # rubocop:enable Metrics/AbcSize
135
144
 
136
145
  # An `Enabled: true` setting in user configuration for a cop overrides an
137
146
  # `Enabled: false` setting for its department.
@@ -166,8 +175,63 @@ module RuboCop
166
175
  end
167
176
  end
168
177
 
178
+ # A cop's entry in the default configuration may carry a `Preview` section
179
+ # with the defaults it is expected to adopt in the next major release. Under
180
+ # `Preview` those replace the current defaults. The section is dropped either
181
+ # way, so the resolved configuration only ever shows what is in effect.
182
+ def apply_preview_defaults(default_configuration, preview)
183
+ transform(default_configuration) do |params|
184
+ next params unless params['Preview'].is_a?(Hash)
185
+
186
+ params = params.dup
187
+ preview_params = params.delete('Preview')
188
+ preview ? params.merge(preview_params) : params
189
+ end
190
+ end
191
+
169
192
  private
170
193
 
194
+ def defaults_with_preview(config, resolve_preview)
195
+ defaults = ConfigLoader.default_configuration
196
+ return [defaults, false] unless resolve_preview
197
+
198
+ preview = preview?(config)
199
+ [apply_preview_defaults(defaults, preview), preview]
200
+ end
201
+
202
+ def inherit_mode_for_default(config, preview)
203
+ with_preview_exclude_merge(config['inherit_mode'] || {}, preview)
204
+ end
205
+
206
+ # Under `Preview`, `Exclude` is merged rather than replaced, so that excluding
207
+ # one directory does not silently drop the excludes it would have inherited -
208
+ # from the default configuration or from a file named in `inherit_from`. An
209
+ # explicit `inherit_mode` still wins, in either direction.
210
+ def with_preview_exclude_merge(mode, preview)
211
+ return mode unless preview
212
+ return mode if Array(mode['override']).include?('Exclude')
213
+ return mode if Array(mode['merge']).include?('Exclude')
214
+
215
+ mode.merge('merge' => Array(mode['merge']) + ['Exclude'])
216
+ end
217
+
218
+ # `config` has already been through `handle_disabled_by_default` by this
219
+ # point, which returns a plain hash, so read `AllCops` directly rather than
220
+ # going through `Config#for_all_cops`.
221
+ def preview?(config)
222
+ return ConfigLoader.preview unless ConfigLoader.preview.nil?
223
+
224
+ (config['AllCops'] || {})['Preview'] == true
225
+ end
226
+
227
+ def resolve_default_overrides(config)
228
+ if ConfigLoader.disabled_by_default || ConfigLoader.enabled_by_default
229
+ [ConfigLoader.disabled_by_default, ConfigLoader.enabled_by_default]
230
+ else
231
+ [config.for_all_cops['DisabledByDefault'], config.for_all_cops['EnabledByDefault']]
232
+ end
233
+ end
234
+
171
235
  def disabled?(hash, department)
172
236
  hash[department].is_a?(Hash) && hash[department]['Enabled'] == false
173
237
  end
@@ -199,10 +263,21 @@ module RuboCop
199
263
  "the same parameter in #{opts[:inherited_file]}"
200
264
  end
201
265
 
202
- def determine_inherit_mode(hash, key)
266
+ # The `AllCops: Preview` in effect once inheritance is resolved: the file
267
+ # itself wins, then the files it inherits from, last one first. It has to be
268
+ # known before merging, since the keys are merged in whatever order they
269
+ # appear and `AllCops` may well come after the cops whose `Exclude` it affects.
270
+ def inherited_preview?(hash, base_configs)
271
+ all_cops = [hash, *base_configs.reverse].map { |config| config['AllCops'] }.find do |params|
272
+ params.is_a?(Hash) && params.key?('Preview')
273
+ end
274
+ preview?('AllCops' => all_cops)
275
+ end
276
+
277
+ def determine_inherit_mode(hash, key, preview)
203
278
  cop_cfg = hash[key]
204
279
  local_inherit = cop_cfg['inherit_mode'] if cop_cfg.is_a?(Hash)
205
- local_inherit || hash['inherit_mode'] || {}
280
+ with_preview_exclude_merge(local_inherit || hash['inherit_mode'] || {}, preview)
206
281
  end
207
282
 
208
283
  def should_union?(derived_hash, base_hash, root_mode, key)
@@ -246,7 +321,7 @@ module RuboCop
246
321
  def inherited_file(path, inherit_from, file)
247
322
  if PathUtil.remote_file?(inherit_from)
248
323
  # A remote configuration, e.g. `inherit_from: http://example.com/rubocop.yml`.
249
- RemoteConfig.new(inherit_from, File.dirname(path))
324
+ RemoteConfig.new(inherit_from, ConfigLoader.cache_root)
250
325
  elsif Pathname.new(inherit_from).absolute?
251
326
  # An absolute path to a config, e.g. `inherit_from: /Users/me/rubocop.yml`.
252
327
  # The path may come from `inherit_gem` option, where a gem name is expanded
@@ -256,7 +331,7 @@ module RuboCop
256
331
  elsif file.is_a?(RemoteConfig)
257
332
  # A path relative to a URL, e.g. `inherit_from: configs/default.yml`
258
333
  # in a config included with `inherit_from: http://example.com/rubocop.yml`
259
- file.inherit_from_remote(inherit_from, path)
334
+ file.inherit_from_remote(inherit_from)
260
335
  else
261
336
  # A local relative path, e.g. `inherit_from: default.yml`
262
337
  print 'Inheriting ' if ConfigLoader.debug?
@@ -268,7 +343,7 @@ module RuboCop
268
343
  file.is_a?(RemoteConfig)
269
344
  end
270
345
 
271
- def handle_disabled_by_default(config, new_default_configuration)
346
+ def handle_disabled_by_default(config, new_default_configuration, base_defaults)
272
347
  department_config = config.to_hash.reject { |cop| cop.include?('/') }
273
348
  department_config.each do |dept, dept_params|
274
349
  next unless dept_params['Enabled']
@@ -277,7 +352,7 @@ module RuboCop
277
352
  next unless cop.start_with?("#{dept}/")
278
353
 
279
354
  # Retain original default configuration for cops in the department.
280
- params['Enabled'] = ConfigLoader.default_configuration[cop]['Enabled']
355
+ params['Enabled'] = base_defaults[cop]['Enabled']
281
356
  end
282
357
  end
283
358
 
@@ -20,7 +20,8 @@ module RuboCop
20
20
  rule_message + "\n(obsolete configuration found in #{smart_loaded_path}, please update it)"
21
21
  end
22
22
 
23
- # Cop rules currently can only be failures, not warnings
23
+ # Failure by default; rules that accept `severity: warning` say so
24
+ # themselves.
24
25
  def warning?
25
26
  false
26
27
  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
@@ -20,15 +20,23 @@ module RuboCop
20
20
 
21
21
  if reason
22
22
  "#{base} since #{reason.chomp}."
23
- elsif alternatives
23
+ elsif alternatives.any?
24
24
  "#{base}. Please use #{to_sentence(alternatives, connector: 'and/or')} instead."
25
25
  else
26
26
  "#{base}."
27
27
  end
28
28
  end
29
29
 
30
+ def warning?
31
+ severity == 'warning'
32
+ end
33
+
30
34
  private
31
35
 
36
+ def severity
37
+ metadata['severity']
38
+ end
39
+
32
40
  def reason
33
41
  metadata['reason']
34
42
  end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  'changed_parameters' => ChangedParameter,
16
16
  'changed_enforced_styles' => ChangedEnforcedStyles
17
17
  }.freeze
18
- LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant
18
+ LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant -- a cache, written to at runtime
19
19
  private_constant :LOAD_RULES_CACHE
20
20
 
21
21
  attr_reader :rules, :warnings
@@ -36,7 +36,7 @@ module RuboCop
36
36
  end
37
37
 
38
38
  def force_default_config!
39
- @options_config = ConfigLoader.default_configuration
39
+ @options_config = ConfigLoader.apply_default_overrides(ConfigLoader.default_configuration)
40
40
  end
41
41
 
42
42
  def unvalidated
@@ -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,