rubocop 1.59.0 → 1.65.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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -4
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +93 -17
  7. data/lib/rubocop/cached_data.rb +11 -3
  8. data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  11. data/lib/rubocop/cli.rb +10 -1
  12. data/lib/rubocop/config.rb +36 -12
  13. data/lib/rubocop/config_finder.rb +12 -2
  14. data/lib/rubocop/config_loader.rb +1 -2
  15. data/lib/rubocop/config_loader_resolver.rb +9 -3
  16. data/lib/rubocop/config_obsoletion.rb +1 -1
  17. data/lib/rubocop/config_validator.rb +14 -7
  18. data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
  19. data/lib/rubocop/cop/base.rb +63 -16
  20. data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
  21. data/lib/rubocop/cop/cop.rb +22 -4
  22. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  23. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  24. data/lib/rubocop/cop/documentation.rb +16 -6
  25. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  26. data/lib/rubocop/cop/force.rb +12 -0
  27. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  28. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  29. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  30. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  31. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  32. data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
  33. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  34. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
  35. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  36. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  37. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  38. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  39. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  40. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  41. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  42. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  43. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  44. data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
  45. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  46. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -1
  47. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  49. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
  50. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  51. data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  54. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  55. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  56. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  57. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
  58. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  59. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  60. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  61. data/lib/rubocop/cop/lint/boolean_symbol.rb +0 -2
  62. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  63. data/lib/rubocop/cop/lint/debugger.rb +27 -6
  64. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  65. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  66. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  67. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
  68. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
  69. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  70. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  71. data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
  72. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  73. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  74. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  75. data/lib/rubocop/cop/lint/ensure_return.rb +1 -6
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
  77. data/lib/rubocop/cop/lint/float_comparison.rb +3 -1
  78. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  79. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  80. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +15 -12
  81. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  82. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  83. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  84. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
  85. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +0 -4
  86. data/lib/rubocop/cop/lint/loop.rb +6 -12
  87. data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
  88. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  89. data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
  90. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  91. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  92. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  93. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  94. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  95. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  96. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
  97. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  98. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
  99. data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
  100. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  101. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  102. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  103. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  104. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +0 -4
  105. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  106. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  107. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
  108. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  109. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
  110. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  111. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  112. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  113. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  114. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -5
  115. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  116. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  117. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  118. data/lib/rubocop/cop/lint/void.rb +11 -1
  119. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  120. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
  121. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  122. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  123. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  124. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  125. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  126. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  127. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
  128. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  129. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  130. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  131. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  132. data/lib/rubocop/cop/naming/block_forwarding.rb +32 -5
  133. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  134. data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
  135. data/lib/rubocop/cop/naming/predicate_name.rb +54 -28
  136. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
  137. data/lib/rubocop/cop/registry.rb +1 -1
  138. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  139. data/lib/rubocop/cop/security/open.rb +2 -2
  140. data/lib/rubocop/cop/style/access_modifier_declarations.rb +50 -0
  141. data/lib/rubocop/cop/style/alias.rb +1 -0
  142. data/lib/rubocop/cop/style/arguments_forwarding.rb +89 -17
  143. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  144. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  145. data/lib/rubocop/cop/style/collection_compact.rb +14 -5
  146. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  147. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
  148. data/lib/rubocop/cop/style/copyright.rb +31 -21
  149. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  150. data/lib/rubocop/cop/style/documentation.rb +24 -24
  151. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  152. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  153. data/lib/rubocop/cop/style/eval_with_location.rb +15 -23
  154. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
  155. data/lib/rubocop/cop/style/file_read.rb +2 -5
  156. data/lib/rubocop/cop/style/file_write.rb +2 -5
  157. data/lib/rubocop/cop/style/for.rb +2 -0
  158. data/lib/rubocop/cop/style/format_string.rb +9 -9
  159. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  160. data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
  161. data/lib/rubocop/cop/style/hash_except.rb +8 -5
  162. data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
  163. data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
  164. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  165. data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
  166. data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
  167. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
  168. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  169. data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
  170. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  171. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +18 -5
  172. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  173. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  174. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  175. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
  176. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  177. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  178. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  179. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  180. data/lib/rubocop/cop/style/object_then.rb +5 -3
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  182. data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
  183. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  184. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  185. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  186. data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
  187. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  188. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  189. data/lib/rubocop/cop/style/redundant_condition.rb +0 -1
  190. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
  191. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  192. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  193. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  194. data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -2
  195. data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
  196. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  197. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
  198. data/lib/rubocop/cop/style/redundant_return.rb +6 -0
  199. data/lib/rubocop/cop/style/require_order.rb +1 -1
  200. data/lib/rubocop/cop/style/sample.rb +1 -3
  201. data/lib/rubocop/cop/style/send.rb +4 -4
  202. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
  203. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  204. data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
  205. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  206. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  207. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  208. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  209. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  210. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  211. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  212. data/lib/rubocop/cop/team.rb +13 -0
  213. data/lib/rubocop/cop/util.rb +7 -1
  214. data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
  215. data/lib/rubocop/cop/variable_force.rb +13 -1
  216. data/lib/rubocop/cops_documentation_generator.rb +16 -4
  217. data/lib/rubocop/core_ext/string.rb +2 -6
  218. data/lib/rubocop/directive_comment.rb +10 -8
  219. data/lib/rubocop/ext/regexp_node.rb +18 -35
  220. data/lib/rubocop/ext/regexp_parser.rb +4 -21
  221. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  222. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  223. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  224. data/lib/rubocop/formatter/html_formatter.rb +32 -10
  225. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  226. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  227. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  228. data/lib/rubocop/formatter.rb +1 -1
  229. data/lib/rubocop/lockfile.rb +56 -7
  230. data/lib/rubocop/lsp/logger.rb +1 -1
  231. data/lib/rubocop/lsp/routes.rb +12 -15
  232. data/lib/rubocop/lsp/runtime.rb +1 -1
  233. data/lib/rubocop/lsp/server.rb +7 -2
  234. data/lib/rubocop/lsp/severity.rb +1 -1
  235. data/lib/rubocop/lsp.rb +36 -0
  236. data/lib/rubocop/magic_comment.rb +1 -1
  237. data/lib/rubocop/options.rb +17 -12
  238. data/lib/rubocop/path_util.rb +6 -2
  239. data/lib/rubocop/rake_task.rb +1 -1
  240. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  241. data/lib/rubocop/rspec/expect_offense.rb +16 -8
  242. data/lib/rubocop/rspec/shared_contexts.rb +73 -16
  243. data/lib/rubocop/rspec/support.rb +3 -0
  244. data/lib/rubocop/runner.rb +14 -3
  245. data/lib/rubocop/server/cache.rb +11 -2
  246. data/lib/rubocop/server/client_command/exec.rb +2 -3
  247. data/lib/rubocop/server/client_command/start.rb +1 -1
  248. data/lib/rubocop/server/core.rb +4 -0
  249. data/lib/rubocop/server/server_command/exec.rb +0 -1
  250. data/lib/rubocop/target_finder.rb +84 -78
  251. data/lib/rubocop/target_ruby.rb +82 -80
  252. data/lib/rubocop/version.rb +19 -4
  253. data/lib/rubocop.rb +9 -0
  254. metadata +18 -11
  255. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -27,7 +27,10 @@ module RuboCop
27
27
  class VariableForce < Force # rubocop:disable Metrics/ClassLength
28
28
  VARIABLE_ASSIGNMENT_TYPE = :lvasgn
29
29
  REGEXP_NAMED_CAPTURE_TYPE = :match_with_lvasgn
30
- VARIABLE_ASSIGNMENT_TYPES = [VARIABLE_ASSIGNMENT_TYPE, REGEXP_NAMED_CAPTURE_TYPE].freeze
30
+ PATTERN_MATCH_VARIABLE_TYPE = :match_var
31
+ VARIABLE_ASSIGNMENT_TYPES = [
32
+ VARIABLE_ASSIGNMENT_TYPE, REGEXP_NAMED_CAPTURE_TYPE, PATTERN_MATCH_VARIABLE_TYPE
33
+ ].freeze
31
34
 
32
35
  ARGUMENT_DECLARATION_TYPES = [
33
36
  :arg, :optarg, :restarg,
@@ -112,6 +115,7 @@ module RuboCop
112
115
  NODE_HANDLER_METHOD_NAMES = [
113
116
  [VARIABLE_ASSIGNMENT_TYPE, :process_variable_assignment],
114
117
  [REGEXP_NAMED_CAPTURE_TYPE, :process_regexp_named_captures],
118
+ [PATTERN_MATCH_VARIABLE_TYPE, :process_pattern_match_variable],
115
119
  [MULTIPLE_ASSIGNMENT_TYPE, :process_variable_multiple_assignment],
116
120
  [VARIABLE_REFERENCE_TYPE, :process_variable_referencing],
117
121
  [RESCUE_TYPE, :process_rescue],
@@ -175,6 +179,14 @@ module RuboCop
175
179
  skip_children!
176
180
  end
177
181
 
182
+ def process_pattern_match_variable(node)
183
+ name = node.children.first
184
+
185
+ variable_table.declare_variable(name, node) unless variable_table.variable_exist?(name)
186
+
187
+ skip_children!
188
+ end
189
+
178
190
  def regexp_captured_names(node)
179
191
  regexp = node.to_regexp
180
192
 
@@ -97,7 +97,9 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
97
97
  'Version Changed'
98
98
  ]
99
99
  autocorrect = if cop.support_autocorrect?
100
- "Yes#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}"
100
+ context = cop.new.always_autocorrect? ? 'Always' : 'Command-line only'
101
+
102
+ "#{context}#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}"
101
103
  else
102
104
  'No'
103
105
  end
@@ -251,9 +253,18 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
251
253
  "\ninclude::../partials/#{filename}[]\n"
252
254
  end
253
255
 
256
+ # rubocop:disable Metrics/MethodLength
254
257
  def print_cops_of_department(department)
255
258
  selected_cops = cops_of_department(department)
256
- content = +"= #{department}\n"
259
+ content = +<<~HEADER
260
+ ////
261
+ Do NOT edit this file by hand directly, as it is automatically generated.
262
+
263
+ Please make any necessary changes to the cop documentation within the source files themselves.
264
+ ////
265
+
266
+ = #{department}
267
+ HEADER
257
268
  selected_cops.each { |cop| content << print_cop_with_doc(cop) }
258
269
  content << footer_for_department(department)
259
270
  file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
@@ -262,11 +273,12 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
262
273
  file.write("#{content.strip}\n")
263
274
  end
264
275
  end
276
+ # rubocop:enable Metrics/MethodLength
265
277
 
266
278
  def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
267
279
  cop_config = config.for_cop(cop)
268
280
  non_display_keys = %w[
269
- Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
281
+ AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
270
282
  VersionChanged
271
283
  ]
272
284
  pars = cop_config.reject { |k| non_display_keys.include? k }
@@ -294,7 +306,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
294
306
  filename = "#{department_to_basename(department)}.adoc"
295
307
  content = +"=== Department xref:#{filename}[#{type_title}]\n\n"
296
308
  cops_of_department(department).each do |cop|
297
- anchor = cop.cop_name.sub('/', '').downcase
309
+ anchor = cop.cop_name.delete('/').downcase
298
310
  content << "* xref:#{filename}##{anchor}[#{cop.cop_name}]\n"
299
311
  end
300
312
 
@@ -9,12 +9,8 @@ class String
9
9
  # @return [Boolean] true is the string is blank, false otherwise
10
10
  #
11
11
  # @example
12
- # ''.blank? #=> true
13
- #
14
- # @example
15
- # ' '.blank? #=> true
16
- #
17
- # @example
12
+ # ''.blank? #=> true
13
+ # ' '.blank? #=> true
18
14
  # ' test'.blank? #=> false
19
15
  def blank?
20
16
  empty? || lstrip.empty?
@@ -6,9 +6,11 @@ module RuboCop
6
6
  # cops it contains.
7
7
  class DirectiveComment
8
8
  # @api private
9
- REDUNDANT_DIRECTIVE_COP_DEPARTMENT = 'Lint'
9
+ LINT_DEPARTMENT = 'Lint'
10
10
  # @api private
11
- REDUNDANT_DIRECTIVE_COP = "#{REDUNDANT_DIRECTIVE_COP_DEPARTMENT}/RedundantCopDisableDirective"
11
+ LINT_REDUNDANT_DIRECTIVE_COP = "#{LINT_DEPARTMENT}/RedundantCopDisableDirective"
12
+ # @api private
13
+ LINT_SYNTAX_COP = "#{LINT_DEPARTMENT}/Syntax"
12
14
  # @api private
13
15
  COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
14
16
  # @api private
@@ -118,9 +120,10 @@ module RuboCop
118
120
  end
119
121
 
120
122
  def parsed_cop_names
121
- splitted_cops_string.map do |name|
123
+ cops = splitted_cops_string.map do |name|
122
124
  department?(name) ? cop_names_for_department(name) : name
123
125
  end.flatten
126
+ cops - [LINT_SYNTAX_COP]
124
127
  end
125
128
 
126
129
  def department?(name)
@@ -128,17 +131,16 @@ module RuboCop
128
131
  end
129
132
 
130
133
  def all_cop_names
131
- exclude_redundant_directive_cop(cop_registry.names)
134
+ exclude_lint_department_cops(cop_registry.names)
132
135
  end
133
136
 
134
137
  def cop_names_for_department(department)
135
138
  names = cop_registry.names_for_department(department)
136
- has_redundant_directive_cop = department == REDUNDANT_DIRECTIVE_COP_DEPARTMENT
137
- has_redundant_directive_cop ? exclude_redundant_directive_cop(names) : names
139
+ department == LINT_DEPARTMENT ? exclude_lint_department_cops(names) : names
138
140
  end
139
141
 
140
- def exclude_redundant_directive_cop(cops)
141
- cops - [REDUNDANT_DIRECTIVE_COP]
142
+ def exclude_lint_department_cops(cops)
143
+ cops - [LINT_REDUNDANT_DIRECTIVE_COP, LINT_SYNTAX_COP]
142
144
  end
143
145
  end
144
146
  end
@@ -15,49 +15,24 @@ module RuboCop
15
15
  # see `ext/regexp_parser`.
16
16
  attr_reader :parsed_tree
17
17
 
18
- if Gem::Version.new(Regexp::Parser::VERSION) >= Gem::Version.new('2.0')
19
- def assign_properties(*)
20
- super
18
+ def assign_properties(*)
19
+ super
21
20
 
22
- str = with_interpolations_blanked
23
- @parsed_tree = begin
24
- Regexp::Parser.parse(str, options: options)
25
- rescue StandardError
26
- nil
27
- end
28
- origin = loc.begin.end
29
- @parsed_tree&.each_expression(true) { |e| e.origin = origin }
30
- end
31
- # Please remove this `else` branch when support for regexp_parser 1.8 will be dropped.
32
- # It's for compatibility with regexp_parser 1.8 and will never be maintained.
33
- else
34
- def assign_properties(*)
35
- super
36
-
37
- str = with_interpolations_blanked
38
- begin
39
- @parsed_tree = Regexp::Parser.parse(str, options: options)
40
- rescue StandardError
41
- @parsed_tree = nil
42
- else
43
- origin = loc.begin.end
44
- source = @parsed_tree.to_s
45
- @parsed_tree.each_expression(true) do |e|
46
- e.origin = origin
47
- e.source = source
48
- end
49
- end
21
+ str = with_interpolations_blanked
22
+ @parsed_tree = begin
23
+ Regexp::Parser.parse(str, options: options)
24
+ rescue StandardError
25
+ nil
50
26
  end
27
+ origin = loc.begin.end
28
+ @parsed_tree&.each_expression(true) { |e| e.origin = origin }
51
29
  end
52
30
 
53
31
  def each_capture(named: ANY)
54
32
  return enum_for(__method__, named: named) unless block_given?
55
33
 
56
34
  parsed_tree&.traverse do |event, exp, _index|
57
- yield(exp) if event == :enter &&
58
- named == exp.respond_to?(:name) &&
59
- exp.respond_to?(:capturing?) &&
60
- exp.capturing?
35
+ yield(exp) if named_capturing?(exp, event, named)
61
36
  end
62
37
 
63
38
  self
@@ -65,6 +40,14 @@ module RuboCop
65
40
 
66
41
  private
67
42
 
43
+ def named_capturing?(exp, event, named)
44
+ event == :enter &&
45
+ named == exp.respond_to?(:name) &&
46
+ !exp.text.start_with?('(?<=') &&
47
+ exp.respond_to?(:capturing?) &&
48
+ exp.capturing?
49
+ end
50
+
68
51
  def with_interpolations_blanked
69
52
  # Ignore the trailing regopt node
70
53
  children[0...-1].map do |child|
@@ -22,26 +22,9 @@ module RuboCop
22
22
  module Base
23
23
  attr_accessor :origin
24
24
 
25
- if Gem::Version.new(Regexp::Parser::VERSION) >= Gem::Version.new('2.0')
26
- # Shortcut to `loc.expression`
27
- def expression
28
- @expression ||= origin.adjust(begin_pos: ts, end_pos: ts + full_length)
29
- end
30
- # Please remove this `else` branch when support for regexp_parser 1.8 will be dropped.
31
- # It's for compatibility with regexp_parser 1.8 and will never be maintained.
32
- else
33
- attr_accessor :source
34
-
35
- def start_index
36
- # ts is a byte index; convert it to a character index
37
- @start_index ||= source.byteslice(0, ts).length
38
- end
39
-
40
- # Shortcut to `loc.expression`
41
- def expression
42
- end_pos = start_index + full_length
43
- @expression ||= origin.adjust(begin_pos: start_index, end_pos: end_pos)
44
- end
25
+ # Shortcut to `loc.expression`
26
+ def expression
27
+ @expression ||= origin.adjust(begin_pos: ts, end_pos: ts + full_length)
45
28
  end
46
29
 
47
30
  # @returns a location map like `parser` does, with:
@@ -69,8 +52,8 @@ module RuboCop
69
52
 
70
53
  body = expression.adjust(end_pos: -q.text.length)
71
54
  q.origin = origin
72
- q.source = source if q.respond_to?(:source=) # for regexp_parser 1.8
73
55
  q_loc = q.expression
56
+
74
57
  { body: body, quantifier: q_loc }
75
58
  end
76
59
  end
@@ -24,14 +24,10 @@ module RuboCop
24
24
  message: message(offense)
25
25
  )
26
26
 
27
- begin
28
- return unless valid_line?(offense)
27
+ return unless valid_line?(offense)
29
28
 
30
- report_line(offense.location)
31
- report_highlighted_area(offense.highlighted_area)
32
- rescue IndexError
33
- # range is not on a valid line; perhaps the source file is empty
34
- end
29
+ report_line(offense.location)
30
+ report_highlighted_area(offense.highlighted_area)
35
31
  end
36
32
 
37
33
  def valid_line?(offense)
@@ -30,7 +30,8 @@ module RuboCop
30
30
  @files_with_offenses ||= {}
31
31
  end
32
32
 
33
- def file_started(_file, _file_info)
33
+ def file_started(_file, options)
34
+ @config_for_pwd = options[:config_store].for_pwd
34
35
  @exclude_limit_option = @options[:exclude_limit]
35
36
  @exclude_limit = Integer(@exclude_limit_option ||
36
37
  RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS)
@@ -115,16 +116,24 @@ module RuboCop
115
116
  def set_max(cfg, cop_name)
116
117
  return unless cfg[:exclude_limit]
117
118
 
118
- # In case auto_gen_only_exclude is set, only modify the maximum if the
119
- # files are not excluded one by one.
120
- if !@options[:auto_gen_only_exclude] || @files_with_offenses[cop_name].size > @exclude_limit
121
- cfg.merge!(cfg[:exclude_limit])
122
- end
119
+ cfg.merge!(cfg[:exclude_limit]) if should_set_max?(cop_name)
123
120
 
124
121
  # Remove already used exclude_limit.
125
122
  cfg.reject! { |key| key == :exclude_limit }
126
123
  end
127
124
 
125
+ def should_set_max?(cop_name)
126
+ max_set_in_user_config =
127
+ @config_for_pwd.for_cop(cop_name)['Max'] != default_config(cop_name)['Max']
128
+
129
+ max_allowed = !max_set_in_user_config && !no_exclude_limit?
130
+ return false unless max_allowed
131
+
132
+ # In case auto_gen_only_exclude is set, only modify the maximum if the files are not
133
+ # excluded one by one.
134
+ !@options[:auto_gen_only_exclude] || @files_with_offenses[cop_name].size > @exclude_limit
135
+ end
136
+
128
137
  def output_cop_comments(output_buffer, cfg, cop_name, offense_count)
129
138
  output_buffer.puts "# Offense count: #{offense_count}" if show_offense_counts?
130
139
 
@@ -192,8 +201,8 @@ module RuboCop
192
201
  # 'Enabled' option will be put into file only if exclude
193
202
  # limit is exceeded.
194
203
  rejected_keys = ['Enabled']
195
- rejected_keys << 'EnforcedStyle' unless auto_gen_enforced_style?
196
- cfg.reject { |key| rejected_keys.include?(key) }
204
+ rejected_keys << /\AEnforcedStyle\w*/ unless auto_gen_enforced_style?
205
+ cfg.reject { |key| include_or_match?(rejected_keys, key) }
197
206
  end
198
207
 
199
208
  def output_offending_files(output_buffer, cfg, cop_name)
@@ -262,6 +271,12 @@ module RuboCop
262
271
  def no_exclude_limit?
263
272
  @options[:no_exclude_limit] == false
264
273
  end
274
+
275
+ # Returns true if the given arr include the given elm or if any of the
276
+ # given arr is a regexp that matches the given elm.
277
+ def include_or_match?(arr, elm)
278
+ arr.include?(elm) || arr.any? { |x| x.is_a?(Regexp) && x.match?(elm) }
279
+ end
265
280
  end
266
281
  end
267
282
  end
@@ -27,6 +27,7 @@ module RuboCop
27
27
  '[t]ap' => 'TapFormatter',
28
28
  '[w]orst' => 'WorstOffendersFormatter'
29
29
  }.freeze
30
+ BUILTIN_FORMATTER_NAMES = BUILTIN_FORMATTERS_FOR_KEYS.keys.map { |key| key.delete('[]') }
30
31
 
31
32
  FORMATTER_APIS = %i[started finished].freeze
32
33
 
@@ -88,7 +89,12 @@ module RuboCop
88
89
  /^\[#{specified_key}\]/.match?(key) || specified_key == key.delete('[]')
89
90
  end
90
91
 
91
- raise %(No formatter for "#{specified_key}") if matching_keys.empty?
92
+ if matching_keys.empty?
93
+ similar_name = NameSimilarity.find_similar_name(specified_key, BUILTIN_FORMATTER_NAMES)
94
+ suggestion = %( Did you mean? "#{similar_name}") if similar_name
95
+
96
+ raise Rainbow(%(Formatter "#{specified_key}" not found.#{suggestion})).red
97
+ end
92
98
 
93
99
  raise %(Cannot determine formatter for "#{specified_key}") if matching_keys.size > 1
94
100
 
@@ -9,6 +9,7 @@ module RuboCop
9
9
  class HTMLFormatter < BaseFormatter
10
10
  ELLIPSES = '<span class="extra-code">...</span>'
11
11
  TEMPLATE_PATH = File.expand_path('../../../assets/output.html.erb', __dir__)
12
+ CSS_PATH = File.expand_path('../../../assets/output.css.erb', __dir__)
12
13
 
13
14
  Color = Struct.new(:red, :green, :blue, :alpha) do
14
15
  def to_s
@@ -50,8 +51,10 @@ module RuboCop
50
51
  context = ERBContext.new(files, summary)
51
52
 
52
53
  template = File.read(TEMPLATE_PATH, encoding: Encoding::UTF_8)
53
- erb = ERB.new(template, trim_mode: '-')
54
- html = erb.result(context.binding)
54
+ erb = ERB.new(template)
55
+ html = erb.result(context.binding).lines.map do |line|
56
+ line.match?(/\A\s*\z/) ? "\n" : line
57
+ end.join
55
58
 
56
59
  output.write html
57
60
  end
@@ -61,14 +64,6 @@ module RuboCop
61
64
  include PathUtil
62
65
  include TextUtil
63
66
 
64
- SEVERITY_COLORS = {
65
- refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
66
- convention: Color.new(0xED, 0x9C, 0x28, 1.0),
67
- warning: Color.new(0x96, 0x28, 0xEF, 1.0),
68
- error: Color.new(0xD2, 0x32, 0x2D, 1.0),
69
- fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
70
- }.freeze
71
-
72
67
  LOGO_IMAGE_PATH = File.expand_path('../../../assets/logo.png', __dir__)
73
68
 
74
69
  attr_reader :files, :summary
@@ -127,6 +122,33 @@ module RuboCop
127
122
  # https://github.com/ruby/base64/blob/v0.1.1/lib/base64.rb#L27-L40
128
123
  [image].pack('m')
129
124
  end
125
+
126
+ def render_css
127
+ context = CSSContext.new
128
+ template = File.read(CSS_PATH, encoding: Encoding::UTF_8)
129
+ erb = ERB.new(template, trim_mode: '-')
130
+ erb.result(context.binding).lines.map do |line|
131
+ line == "\n" ? line : " #{line}"
132
+ end.join
133
+ end
134
+ end
135
+
136
+ # This class provides helper methods used in the ERB CSS template.
137
+ class CSSContext
138
+ SEVERITY_COLORS = {
139
+ refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
140
+ convention: Color.new(0xED, 0x9C, 0x28, 1.0),
141
+ warning: Color.new(0x96, 0x28, 0xEF, 1.0),
142
+ error: Color.new(0xD2, 0x32, 0x2D, 1.0),
143
+ fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
144
+ }.freeze
145
+
146
+ # Make Kernel#binding public.
147
+ # rubocop:disable Lint/UselessMethodDefinition
148
+ def binding
149
+ super
150
+ end
151
+ # rubocop:enable Lint/UselessMethodDefinition
130
152
  end
131
153
  end
132
154
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require 'pathname'
5
4
 
6
5
  module RuboCop
7
6
  module Formatter
@@ -61,8 +61,7 @@ module RuboCop
61
61
 
62
62
  column_width = total_count.to_s.length + 2
63
63
  per_cop_counts.each do |cop_name, count|
64
- output.puts "#{count.to_s.ljust(column_width)}#{cop_name}" \
65
- "#{@style_guide_links[cop_name]}\n"
64
+ output.puts "#{count.to_s.ljust(column_width)}#{cop_information(cop_name)}"
66
65
  end
67
66
  output.puts '--'
68
67
  output.puts "#{total_count} Total in #{offending_files_count} files"
@@ -78,6 +77,17 @@ module RuboCop
78
77
  def total_offense_count(offense_counts)
79
78
  offense_counts.values.sum
80
79
  end
80
+
81
+ def cop_information(cop_name)
82
+ cop = RuboCop::Cop::Registry.global.find_by_cop_name(cop_name).new
83
+
84
+ if cop.correctable?
85
+ safety = cop.safe_autocorrect? ? 'Safe' : 'Unsafe'
86
+ correctable = Rainbow(" [#{safety} Correctable]").yellow
87
+ end
88
+
89
+ "#{cop_name}#{correctable}#{@style_guide_links[cop_name]}"
90
+ end
81
91
  end
82
92
  end
83
93
  end
@@ -53,14 +53,10 @@ module RuboCop
53
53
  message: message(offense)
54
54
  )
55
55
 
56
- begin
57
- return unless valid_line?(offense)
56
+ return unless valid_line?(offense)
58
57
 
59
- report_line(offense.location)
60
- report_highlighted_area(offense.highlighted_area)
61
- rescue IndexError
62
- # range is not on a valid line; perhaps the source file is empty
63
- end
58
+ report_line(offense.location)
59
+ report_highlighted_area(offense.highlighted_area)
64
60
  end
65
61
 
66
62
  def annotate_message(msg)
@@ -14,7 +14,7 @@ module RuboCop
14
14
  require_relative 'formatter/emacs_style_formatter'
15
15
  require_relative 'formatter/file_list_formatter'
16
16
  require_relative 'formatter/fuubar_style_formatter'
17
- require_relative 'formatter/git_hub_actions_formatter'
17
+ require_relative 'formatter/github_actions_formatter'
18
18
  require_relative 'formatter/html_formatter'
19
19
  require_relative 'formatter/json_formatter'
20
20
  require_relative 'formatter/junit_formatter'
@@ -1,18 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ begin
4
+ # We might not be running with `bundle exec`, so we need to pull in Bundler ourselves,
5
+ # in order to use `Bundler::LockfileParser`.
6
+ require 'bundler'
7
+ rescue LoadError
8
+ nil
9
+ end
10
+
3
11
  module RuboCop
4
12
  # Encapsulation of a lockfile for use when checking for gems.
5
13
  # Does not actually resolve gems, just parses the lockfile.
6
14
  # @api private
7
15
  class Lockfile
8
- # Gems that the bundle depends on
16
+ # @param [String, Pathname, nil] lockfile_path
17
+ def initialize(lockfile_path = nil)
18
+ lockfile_path ||= begin
19
+ ::Bundler.default_lockfile if bundler_lock_parser_defined?
20
+ rescue ::Bundler::GemfileNotFound
21
+ nil # We might not be a folder with a Gemfile, but that's okay.
22
+ end
23
+
24
+ @lockfile_path = lockfile_path
25
+ end
26
+
27
+ # Gems that the bundle directly depends on.
28
+ # @return [Array<Bundler::Dependency>, nil]
9
29
  def dependencies
10
30
  return [] unless parser
11
31
 
12
32
  parser.dependencies.values
13
33
  end
14
34
 
15
- # All activated gems, including transitive dependencies
35
+ # All activated gems, including transitive dependencies.
36
+ # @return [Array<Bundler::Dependency>, nil]
16
37
  def gems
17
38
  return [] unless parser
18
39
 
@@ -21,20 +42,48 @@ module RuboCop
21
42
  parser.dependencies.values.concat(parser.specs.flat_map(&:dependencies))
22
43
  end
23
44
 
45
+ # Returns the locked versions of gems from this lockfile.
46
+ # @param [Boolean] include_transitive_dependencies: When false, only direct dependencies
47
+ # are returned, i.e. those listed explicitly in the `Gemfile`.
48
+ # @returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems' names.
49
+ def gem_versions(include_transitive_dependencies: true)
50
+ return {} unless parser
51
+
52
+ all_gem_versions = parser.specs.to_h { |spec| [spec.name, spec.version] }
53
+
54
+ if include_transitive_dependencies
55
+ all_gem_versions
56
+ else
57
+ direct_dep_names = parser.dependencies.keys
58
+ all_gem_versions.slice(*direct_dep_names)
59
+ end
60
+ end
61
+
62
+ # Whether this lockfile includes the named gem, directly or indirectly.
63
+ # @param [String] name
64
+ # @return [Boolean]
24
65
  def includes_gem?(name)
25
66
  gems.any? { |gem| gem.name == name }
26
67
  end
27
68
 
28
69
  private
29
70
 
71
+ # @return [Bundler::LockfileParser, nil]
30
72
  def parser
31
- return unless defined?(Bundler) && Bundler.default_lockfile
32
73
  return @parser if defined?(@parser)
33
74
 
34
- lockfile = Bundler.read_file(Bundler.default_lockfile)
35
- @parser = lockfile ? Bundler::LockfileParser.new(lockfile) : nil
36
- rescue Bundler::BundlerError
37
- nil
75
+ @parser = if @lockfile_path && File.exist?(@lockfile_path) && bundler_lock_parser_defined?
76
+ begin
77
+ lockfile = ::Bundler.read_file(@lockfile_path)
78
+ ::Bundler::LockfileParser.new(lockfile) if lockfile
79
+ rescue ::Bundler::BundlerError
80
+ nil
81
+ end
82
+ end
83
+ end
84
+
85
+ def bundler_lock_parser_defined?
86
+ Object.const_defined?(:Bundler) && Bundler.const_defined?(:LockfileParser)
38
87
  end
39
88
  end
40
89
  end
@@ -10,7 +10,7 @@
10
10
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
11
  #
12
12
  module RuboCop
13
- module Lsp
13
+ module LSP
14
14
  # Log for Language Server Protocol of RuboCop.
15
15
  # @api private
16
16
  class Logger