rubocop 1.31.1 → 1.52.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (475) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +5 -5
  4. data/config/default.yml +362 -54
  5. data/config/obsoletion.yml +23 -1
  6. data/exe/rubocop +1 -1
  7. data/lib/rubocop/arguments_env.rb +17 -0
  8. data/lib/rubocop/arguments_file.rb +17 -0
  9. data/lib/rubocop/cache_config.rb +29 -0
  10. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +9 -2
  11. data/lib/rubocop/cli/command/execute_runner.rb +14 -9
  12. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  13. data/lib/rubocop/cli/command/suggest_extensions.rb +61 -16
  14. data/lib/rubocop/cli.rb +56 -9
  15. data/lib/rubocop/comment_config.rb +60 -1
  16. data/lib/rubocop/config.rb +48 -20
  17. data/lib/rubocop/config_finder.rb +68 -0
  18. data/lib/rubocop/config_loader.rb +46 -68
  19. data/lib/rubocop/config_loader_resolver.rb +11 -12
  20. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  21. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  22. data/lib/rubocop/config_obsoletion.rb +9 -4
  23. data/lib/rubocop/config_validator.rb +1 -1
  24. data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
  25. data/lib/rubocop/cop/badge.rb +9 -4
  26. data/lib/rubocop/cop/base.rb +116 -84
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/commissioner.rb +19 -6
  29. data/lib/rubocop/cop/cop.rb +54 -34
  30. data/lib/rubocop/cop/corrector.rb +31 -11
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  32. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  33. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  34. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  35. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +23 -7
  36. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  37. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
  38. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  39. data/lib/rubocop/cop/gemspec/dependency_version.rb +17 -19
  40. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  42. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  43. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  44. data/lib/rubocop/cop/generator.rb +5 -2
  45. data/lib/rubocop/cop/internal_affairs/cop_description.rb +38 -12
  46. data/lib/rubocop/cop/internal_affairs/create_empty_file.rb +37 -0
  47. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +111 -0
  48. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
  50. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  51. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
  52. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  54. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  55. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  56. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  57. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  58. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  59. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
  60. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +60 -0
  61. data/lib/rubocop/cop/internal_affairs.rb +9 -0
  62. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  63. data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
  64. data/lib/rubocop/cop/layout/block_end_newline.rb +31 -9
  65. data/lib/rubocop/cop/layout/class_structure.rb +37 -27
  66. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  67. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  68. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  69. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  70. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  71. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  72. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -2
  73. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  74. data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
  75. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  76. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -6
  77. data/lib/rubocop/cop/layout/first_argument_indentation.rb +15 -4
  78. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +6 -5
  79. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +35 -8
  80. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -5
  81. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +36 -1
  82. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +57 -8
  83. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -19
  84. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
  85. data/lib/rubocop/cop/layout/heredoc_indentation.rb +8 -11
  86. data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
  87. data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
  88. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  89. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  90. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +80 -12
  91. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +18 -8
  92. data/lib/rubocop/cop/layout/line_length.rb +8 -1
  93. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +31 -1
  94. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  95. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -1
  96. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +29 -1
  97. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +39 -2
  98. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +77 -0
  99. data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -10
  100. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  101. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -3
  103. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  105. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +22 -20
  108. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -0
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +27 -9
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +30 -3
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
  112. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +34 -0
  113. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +10 -6
  114. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  115. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  116. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -5
  117. data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
  118. data/lib/rubocop/cop/legacy/corrector.rb +1 -1
  119. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +40 -8
  120. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  121. data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
  122. data/lib/rubocop/cop/lint/constant_resolution.rb +5 -1
  123. data/lib/rubocop/cop/lint/debugger.rb +27 -31
  124. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +66 -110
  125. data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
  126. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  127. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  128. data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
  129. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  130. data/lib/rubocop/cop/lint/duplicate_methods.rb +48 -18
  131. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +26 -9
  132. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
  133. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  134. data/lib/rubocop/cop/lint/empty_block.rb +3 -7
  135. data/lib/rubocop/cop/lint/empty_class.rb +3 -1
  136. data/lib/rubocop/cop/lint/empty_conditional_body.rb +110 -2
  137. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  138. data/lib/rubocop/cop/lint/erb_new_arguments.rb +12 -13
  139. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  140. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +15 -17
  141. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  142. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  143. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  144. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  145. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  146. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  147. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  148. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +48 -2
  149. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
  150. data/lib/rubocop/cop/lint/missing_super.rb +34 -2
  151. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  152. data/lib/rubocop/cop/lint/nested_method_definition.rb +53 -9
  153. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  154. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +68 -28
  155. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  156. data/lib/rubocop/cop/lint/number_conversion.rb +28 -6
  157. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  158. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  159. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -6
  160. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -2
  161. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
  162. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  163. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  164. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +49 -9
  165. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -6
  166. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
  167. data/lib/rubocop/cop/lint/redundant_require_statement.rb +48 -10
  168. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -0
  169. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  170. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  171. data/lib/rubocop/cop/lint/redundant_with_index.rb +14 -11
  172. data/lib/rubocop/cop/lint/redundant_with_object.rb +13 -12
  173. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  174. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  175. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  176. data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
  177. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  178. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +41 -8
  179. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  180. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  181. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +6 -6
  182. data/lib/rubocop/cop/lint/shadowed_exception.rb +21 -22
  183. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +28 -3
  184. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  185. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  186. data/lib/rubocop/cop/lint/to_enum_arguments.rb +13 -3
  187. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  188. data/lib/rubocop/cop/lint/unreachable_loop.rb +12 -6
  189. data/lib/rubocop/cop/lint/unused_method_argument.rb +6 -1
  190. data/lib/rubocop/cop/lint/useless_access_modifier.rb +17 -12
  191. data/lib/rubocop/cop/lint/useless_assignment.rb +59 -1
  192. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  193. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  194. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +15 -5
  195. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  196. data/lib/rubocop/cop/lint/void.rb +92 -21
  197. data/lib/rubocop/cop/metrics/abc_size.rb +4 -2
  198. data/lib/rubocop/cop/metrics/block_length.rb +16 -11
  199. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  200. data/lib/rubocop/cop/metrics/class_length.rb +11 -5
  201. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  202. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  203. data/lib/rubocop/cop/metrics/method_length.rb +17 -11
  204. data/lib/rubocop/cop/metrics/module_length.rb +10 -5
  205. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  206. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  207. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -8
  208. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +9 -6
  209. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  210. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  211. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  212. data/lib/rubocop/cop/mixin/allowed_methods.rb +23 -2
  213. data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
  214. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  215. data/lib/rubocop/cop/mixin/annotation_comment.rb +14 -7
  216. data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -1
  217. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  218. data/lib/rubocop/cop/mixin/comments_help.rb +29 -7
  219. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  220. data/lib/rubocop/cop/mixin/def_node.rb +2 -7
  221. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  222. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
  223. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  224. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  225. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  226. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +152 -12
  227. data/lib/rubocop/cop/mixin/hash_transform_method.rb +13 -9
  228. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -2
  229. data/lib/rubocop/cop/mixin/method_complexity.rb +13 -16
  230. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  231. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +7 -14
  232. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -6
  233. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  234. data/lib/rubocop/cop/mixin/percent_array.rb +58 -1
  235. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  236. data/lib/rubocop/cop/mixin/range_help.rb +22 -5
  237. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  238. data/lib/rubocop/cop/mixin/rescue_node.rb +5 -3
  239. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  240. data/lib/rubocop/cop/mixin/statement_modifier.rb +18 -3
  241. data/lib/rubocop/cop/mixin/surrounding_space.rb +13 -11
  242. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -2
  243. data/lib/rubocop/cop/mixin/visibility_help.rb +40 -5
  244. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  245. data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
  246. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  247. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +3 -1
  248. data/lib/rubocop/cop/naming/constant_name.rb +3 -3
  249. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  250. data/lib/rubocop/cop/naming/inclusive_language.rb +28 -6
  251. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +22 -7
  252. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  253. data/lib/rubocop/cop/naming/predicate_name.rb +31 -2
  254. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  255. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  256. data/lib/rubocop/cop/registry.rb +73 -45
  257. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  258. data/lib/rubocop/cop/style/access_modifier_declarations.rb +92 -3
  259. data/lib/rubocop/cop/style/accessor_grouping.rb +50 -20
  260. data/lib/rubocop/cop/style/alias.rb +9 -1
  261. data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -5
  262. data/lib/rubocop/cop/style/array_intersect.rb +111 -0
  263. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  264. data/lib/rubocop/cop/style/attr.rb +11 -1
  265. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  266. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  267. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  268. data/lib/rubocop/cop/style/block_delimiters.rb +44 -10
  269. data/lib/rubocop/cop/style/case_equality.rb +40 -10
  270. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  271. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  272. data/lib/rubocop/cop/style/class_and_module_children.rb +9 -16
  273. data/lib/rubocop/cop/style/class_equality_comparison.rb +72 -12
  274. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  275. data/lib/rubocop/cop/style/collection_compact.rb +27 -5
  276. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  277. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  278. data/lib/rubocop/cop/style/combinable_loops.rb +29 -7
  279. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  280. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  281. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  282. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  283. data/lib/rubocop/cop/style/concat_array_literals.rb +94 -0
  284. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -14
  285. data/lib/rubocop/cop/style/copyright.rb +6 -3
  286. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  287. data/lib/rubocop/cop/style/dir.rb +1 -1
  288. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  289. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  290. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
  291. data/lib/rubocop/cop/style/documentation.rb +22 -10
  292. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  293. data/lib/rubocop/cop/style/double_negation.rb +4 -2
  294. data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
  295. data/lib/rubocop/cop/style/each_with_object.rb +40 -9
  296. data/lib/rubocop/cop/style/empty_block_parameter.rb +2 -2
  297. data/lib/rubocop/cop/style/empty_else.rb +37 -0
  298. data/lib/rubocop/cop/style/empty_heredoc.rb +73 -0
  299. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +2 -2
  300. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  301. data/lib/rubocop/cop/style/endless_method.rb +1 -1
  302. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  303. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  304. data/lib/rubocop/cop/style/explicit_block_argument.rb +5 -1
  305. data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
  306. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  307. data/lib/rubocop/cop/style/file_read.rb +3 -3
  308. data/lib/rubocop/cop/style/file_write.rb +1 -1
  309. data/lib/rubocop/cop/style/for.rb +2 -0
  310. data/lib/rubocop/cop/style/format_string_token.rb +25 -6
  311. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  312. data/lib/rubocop/cop/style/guard_clause.rb +127 -38
  313. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +1 -0
  314. data/lib/rubocop/cop/style/hash_each_methods.rb +36 -21
  315. data/lib/rubocop/cop/style/hash_except.rb +27 -16
  316. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  317. data/lib/rubocop/cop/style/hash_syntax.rb +26 -2
  318. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  319. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  320. data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
  321. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  322. data/lib/rubocop/cop/style/if_unless_modifier.rb +112 -16
  323. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +29 -2
  324. data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
  325. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  326. data/lib/rubocop/cop/style/inverse_methods.rb +15 -11
  327. data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
  328. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  329. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  330. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  331. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  332. data/lib/rubocop/cop/style/map_to_set.rb +64 -0
  333. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +41 -26
  334. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  335. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +48 -41
  336. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +21 -2
  337. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  338. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  339. data/lib/rubocop/cop/style/min_max.rb +3 -3
  340. data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
  341. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  342. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  343. data/lib/rubocop/cop/style/module_function.rb +30 -8
  344. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  345. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  346. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  347. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  348. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  349. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
  350. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  351. data/lib/rubocop/cop/style/negated_if_else_condition.rb +17 -10
  352. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
  353. data/lib/rubocop/cop/style/next.rb +3 -5
  354. data/lib/rubocop/cop/style/nil_lambda.rb +4 -4
  355. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  356. data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
  357. data/lib/rubocop/cop/style/numeric_predicate.rb +43 -9
  358. data/lib/rubocop/cop/style/object_then.rb +5 -0
  359. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  360. data/lib/rubocop/cop/style/operator_method_call.rb +67 -0
  361. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  362. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  363. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  364. data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
  365. data/lib/rubocop/cop/style/proc.rb +4 -1
  366. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  367. data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
  368. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  369. data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
  370. data/lib/rubocop/cop/style/redundant_condition.rb +41 -8
  371. data/lib/rubocop/cop/style/redundant_conditional.rb +0 -4
  372. data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
  373. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +45 -0
  374. data/lib/rubocop/cop/style/redundant_each.rb +116 -0
  375. data/lib/rubocop/cop/style/redundant_fetch_block.rb +7 -5
  376. data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
  377. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  378. data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
  379. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  380. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  381. data/lib/rubocop/cop/style/redundant_parentheses.rb +22 -24
  382. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  383. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +9 -3
  384. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  385. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +21 -4
  386. data/lib/rubocop/cop/style/redundant_return.rb +7 -0
  387. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  388. data/lib/rubocop/cop/style/redundant_sort.rb +24 -9
  389. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  390. data/lib/rubocop/cop/style/redundant_string_escape.rb +183 -0
  391. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  392. data/lib/rubocop/cop/style/require_order.rb +139 -0
  393. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -4
  394. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  395. data/lib/rubocop/cop/style/safe_navigation.rb +41 -10
  396. data/lib/rubocop/cop/style/select_by_regexp.rb +23 -5
  397. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  398. data/lib/rubocop/cop/style/semicolon.rb +63 -5
  399. data/lib/rubocop/cop/style/signal_exception.rb +8 -6
  400. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  401. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  402. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  403. data/lib/rubocop/cop/style/sole_nested_conditional.rb +20 -9
  404. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  405. data/lib/rubocop/cop/style/static_class.rb +32 -1
  406. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  407. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  408. data/lib/rubocop/cop/style/string_literals.rb +1 -5
  409. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  410. data/lib/rubocop/cop/style/symbol_array.rb +6 -5
  411. data/lib/rubocop/cop/style/symbol_proc.rb +42 -10
  412. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
  413. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  414. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  415. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  416. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  417. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  418. data/lib/rubocop/cop/style/trivial_accessors.rb +4 -1
  419. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  420. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  421. data/lib/rubocop/cop/style/word_array.rb +59 -5
  422. data/lib/rubocop/cop/style/yoda_condition.rb +13 -6
  423. data/lib/rubocop/cop/style/yoda_expression.rb +90 -0
  424. data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
  425. data/lib/rubocop/cop/team.rb +63 -56
  426. data/lib/rubocop/cop/util.rb +44 -8
  427. data/lib/rubocop/cop/variable_force/assignment.rb +34 -2
  428. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  429. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  430. data/lib/rubocop/cop/variable_force/variable_table.rb +6 -4
  431. data/lib/rubocop/cop/variable_force.rb +19 -30
  432. data/lib/rubocop/cops_documentation_generator.rb +45 -15
  433. data/lib/rubocop/directive_comment.rb +4 -4
  434. data/lib/rubocop/ext/comment.rb +18 -0
  435. data/lib/rubocop/ext/processed_source.rb +2 -0
  436. data/lib/rubocop/ext/range.rb +15 -0
  437. data/lib/rubocop/ext/regexp_node.rb +1 -1
  438. data/lib/rubocop/ext/regexp_parser.rb +1 -1
  439. data/lib/rubocop/feature_loader.rb +94 -0
  440. data/lib/rubocop/file_patterns.rb +43 -0
  441. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  442. data/lib/rubocop/formatter/disabled_config_formatter.rb +26 -9
  443. data/lib/rubocop/formatter/html_formatter.rb +4 -4
  444. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  445. data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
  446. data/lib/rubocop/formatter/offense_count_formatter.rb +8 -5
  447. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  448. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  449. data/lib/rubocop/formatter/worst_offenders_formatter.rb +6 -3
  450. data/lib/rubocop/formatter.rb +4 -1
  451. data/lib/rubocop/options.rb +55 -22
  452. data/lib/rubocop/path_util.rb +50 -22
  453. data/lib/rubocop/rake_task.rb +5 -1
  454. data/lib/rubocop/result_cache.rb +26 -24
  455. data/lib/rubocop/rspec/cop_helper.rb +26 -3
  456. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  457. data/lib/rubocop/rspec/shared_contexts.rb +31 -14
  458. data/lib/rubocop/rspec/support.rb +17 -2
  459. data/lib/rubocop/runner.rb +73 -18
  460. data/lib/rubocop/server/cache.rb +48 -2
  461. data/lib/rubocop/server/cli.rb +62 -19
  462. data/lib/rubocop/server/client_command/base.rb +1 -1
  463. data/lib/rubocop/server/client_command/exec.rb +8 -2
  464. data/lib/rubocop/server/client_command/start.rb +6 -1
  465. data/lib/rubocop/server/core.rb +42 -10
  466. data/lib/rubocop/server/helper.rb +1 -1
  467. data/lib/rubocop/server/server_command/exec.rb +1 -1
  468. data/lib/rubocop/server/socket_reader.rb +5 -1
  469. data/lib/rubocop/server.rb +1 -1
  470. data/lib/rubocop/target_finder.rb +1 -1
  471. data/lib/rubocop/target_ruby.rb +5 -5
  472. data/lib/rubocop/version.rb +17 -7
  473. data/lib/rubocop.rb +49 -9
  474. metadata +65 -36
  475. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'digest/sha1'
4
- require 'find'
5
4
  require 'etc'
5
+ require 'find'
6
6
  require 'zlib'
7
+ require_relative 'cache_config'
7
8
 
8
9
  module RuboCop
9
10
  # Provides functionality for caching RuboCop runs.
@@ -13,6 +14,12 @@ module RuboCop
13
14
  fix_layout autocorrect safe_autocorrect autocorrect_all
14
15
  cache fail_fast stdin parallel].freeze
15
16
 
17
+ DL_EXTENSIONS = ::RbConfig::CONFIG
18
+ .values_at('DLEXT', 'DLEXT2')
19
+ .reject { |ext| !ext || ext.empty? }
20
+ .map { |ext| ".#{ext}" }
21
+ .freeze
22
+
16
23
  # Remove old files so that the cache doesn't grow too big. When the
17
24
  # threshold MaxFilesInCache has been exceeded, the oldest 50% of all the
18
25
  # files in the cache are removed. The reason for removing so much is that
@@ -46,7 +53,7 @@ module RuboCop
46
53
  def remove_oldest_files(files, dirs, cache_root, verbose)
47
54
  # Add 1 to half the number of files, so that we remove the file if
48
55
  # there's only 1 left.
49
- remove_count = 1 + (files.length / 2)
56
+ remove_count = (files.length / 2) + 1
50
57
  puts "Removing the #{remove_count} oldest files from #{cache_root}" if verbose
51
58
  sorted = files.sort_by { |path| File.mtime(path) }
52
59
  remove_files(sorted, dirs, remove_count)
@@ -67,34 +74,19 @@ module RuboCop
67
74
  end
68
75
 
69
76
  def self.cache_root(config_store)
70
- root = ENV.fetch('RUBOCOP_CACHE_ROOT', nil)
71
- root ||= config_store.for_pwd.for_all_cops['CacheRootDirectory']
72
- root ||= if ENV.key?('XDG_CACHE_HOME')
73
- # Include user ID in the path to make sure the user has write
74
- # access.
75
- File.join(ENV.fetch('XDG_CACHE_HOME'), Process.uid.to_s)
76
- else
77
- # On FreeBSD, the /home path is a symbolic link to /usr/home
78
- # and the $HOME environment variable returns the /home path.
79
- #
80
- # As $HOME is a built-in environment variable, FreeBSD users
81
- # always get a warning message.
82
- #
83
- # To avoid raising warn log messages on FreeBSD, we retrieve
84
- # the real path of the home folder.
85
- File.join(File.realpath(Dir.home), '.cache')
86
- end
87
- File.join(root, 'rubocop_cache')
77
+ CacheConfig.root_dir do
78
+ config_store.for_pwd.for_all_cops['CacheRootDirectory']
79
+ end
88
80
  end
89
81
 
90
82
  def self.allow_symlinks_in_cache_location?(config_store)
91
83
  config_store.for_pwd.for_all_cops['AllowSymlinksInCacheRootDirectory']
92
84
  end
93
85
 
94
- attr :path
86
+ attr_reader :path
95
87
 
96
88
  def initialize(file, team, options, config_store, cache_root = nil)
97
- cache_root ||= options[:cache_root]
89
+ cache_root ||= File.join(options[:cache_root], 'rubocop_cache') if options[:cache_root]
98
90
  cache_root ||= ResultCache.cache_root(config_store)
99
91
  @allow_symlinks_in_cache_location =
100
92
  ResultCache.allow_symlinks_in_cache_location?(config_store)
@@ -188,14 +180,24 @@ module RuboCop
188
180
  .select { |path| File.file?(path) }
189
181
  .sort!
190
182
  .each do |path|
191
- content = File.binread(path)
192
- digest << Zlib.crc32(content).to_s # mtime not reliable
183
+ digest << digest(path)
193
184
  end
194
185
  digest << RuboCop::Version::STRING << RuboCop::AST::Version::STRING
195
186
  digest.hexdigest
196
187
  end
197
188
  end
198
189
 
190
+ def digest(path)
191
+ content = if path.end_with?(*DL_EXTENSIONS)
192
+ # Shared libraries often contain timestamps of when
193
+ # they were compiled and other non-stable data.
194
+ File.basename(path)
195
+ else
196
+ File.binread(path) # mtime not reliable
197
+ end
198
+ Zlib.crc32(content).to_s
199
+ end
200
+
199
201
  def rubocop_extra_features
200
202
  lib_root = File.join(File.dirname(__FILE__), '..')
201
203
  exe_root = File.join(lib_root, '..', 'exe')
@@ -6,7 +6,7 @@ require 'tempfile'
6
6
  module CopHelper
7
7
  extend RSpec::SharedContext
8
8
 
9
- let(:ruby_version) { 2.6 }
9
+ let(:ruby_version) { RuboCop::TargetRuby::DEFAULT_VERSION }
10
10
  let(:rails_version) { false }
11
11
 
12
12
  def inspect_source(source, file = nil)
@@ -28,7 +28,30 @@ module CopHelper
28
28
  file = file.path
29
29
  end
30
30
 
31
- RuboCop::ProcessedSource.new(source, ruby_version, file)
31
+ processed_source = RuboCop::ProcessedSource.new(source, ruby_version, file)
32
+ processed_source.config = configuration
33
+ processed_source.registry = registry
34
+ processed_source
35
+ end
36
+
37
+ def configuration
38
+ @configuration ||= if defined?(config)
39
+ config
40
+ else
41
+ RuboCop::Config.new({}, "#{Dir.pwd}/.rubocop.yml")
42
+ end
43
+ end
44
+
45
+ def registry
46
+ @registry ||= begin
47
+ keys = configuration.keys
48
+ cops =
49
+ keys.map { |directive| RuboCop::Cop::Registry.global.find_cops_by_directive(directive) }
50
+ .flatten
51
+ cops << cop_class if defined?(cop_class) && !cops.include?(cop_class)
52
+ cops.compact!
53
+ RuboCop::Cop::Registry.new(cops)
54
+ end
32
55
  end
33
56
 
34
57
  def autocorrect_source_file(source)
@@ -46,7 +69,7 @@ module CopHelper
46
69
  end
47
70
 
48
71
  def _investigate(cop, processed_source)
49
- team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
72
+ team = RuboCop::Cop::Team.new([cop], configuration, raise_error: true)
50
73
  report = team.investigate(processed_source)
51
74
  @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
52
75
  report.offenses.reject(&:disabled?)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  #
7
7
  # This mixin makes it easier to specify strict offense expectations
8
8
  # in a declarative and visual fashion. Just type out the code that
9
- # should generate a offense, annotate code by writing '^'s
9
+ # should generate an offense, annotate code by writing '^'s
10
10
  # underneath each character that should be highlighted, and follow
11
11
  # the carets with a string (separated by a space) that is the
12
12
  # message of the offense. You can include multiple offenses in
@@ -126,7 +126,7 @@ module RuboCop
126
126
  @offenses
127
127
  end
128
128
 
129
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
129
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
130
130
  def expect_correction(correction, loop: true, source: nil)
131
131
  if source
132
132
  expected_annotations = parse_annotations(source, raise_error: false)
@@ -138,6 +138,8 @@ module RuboCop
138
138
 
139
139
  source = @processed_source.raw_source
140
140
 
141
+ raise 'Use `expect_no_corrections` if the code will not change' if correction == source
142
+
141
143
  iteration = 0
142
144
  new_source = loop do
143
145
  iteration += 1
@@ -157,11 +159,11 @@ module RuboCop
157
159
  _investigate(cop, @processed_source)
158
160
  end
159
161
 
160
- raise 'Use `expect_no_corrections` if the code will not change' if new_source == source
162
+ raise 'Expected correction but no corrections were made' if new_source == source
161
163
 
162
164
  expect(new_source).to eq(correction)
163
165
  end
164
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
166
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
165
167
 
166
168
  def expect_no_corrections
167
169
  raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'tmpdir'
4
4
 
5
- RSpec.shared_context 'isolated environment', :isolated_environment do
5
+ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLength
6
6
  around do |example|
7
7
  Dir.mktmpdir do |tmpdir|
8
8
  original_home = Dir.home
@@ -36,9 +36,22 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ if RuboCop.const_defined?(:Server)
41
+ around do |example|
42
+ RuboCop::Server::Cache.cache_root_path = nil
43
+ RuboCop::Server::Cache.instance_variable_set(:@project_dir_cache_key, nil)
44
+ begin
45
+ example.run
46
+ ensure
47
+ RuboCop::Server::Cache.cache_root_path = nil
48
+ RuboCop::Server::Cache.instance_variable_set(:@project_dir_cache_key, nil)
49
+ end
50
+ end
51
+ end
39
52
  end
40
53
 
41
- RSpec.shared_context 'maintain registry', :restore_registry do
54
+ RSpec.shared_context 'maintain registry' do
42
55
  around(:each) { |example| RuboCop::Cop::Registry.with_temporary_global { example.run } }
43
56
 
44
57
  def stub_cop_class(name, inherit: RuboCop::Cop::Base, &block)
@@ -49,7 +62,7 @@ RSpec.shared_context 'maintain registry', :restore_registry do
49
62
  end
50
63
 
51
64
  # This context assumes nothing and defines `cop`, among others.
52
- RSpec.shared_context 'config', :config do # rubocop:disable Metrics/BlockLength
65
+ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
53
66
  ### Meant to be overridden at will
54
67
 
55
68
  let(:cop_class) do
@@ -116,46 +129,50 @@ RSpec.shared_context 'mock console output' do
116
129
  end
117
130
  end
118
131
 
119
- RSpec.shared_context 'ruby 2.0', :ruby20 do
132
+ RSpec.shared_context 'ruby 2.0' do
120
133
  let(:ruby_version) { 2.0 }
121
134
  end
122
135
 
123
- RSpec.shared_context 'ruby 2.1', :ruby21 do
136
+ RSpec.shared_context 'ruby 2.1' do
124
137
  let(:ruby_version) { 2.1 }
125
138
  end
126
139
 
127
- RSpec.shared_context 'ruby 2.2', :ruby22 do
140
+ RSpec.shared_context 'ruby 2.2' do
128
141
  let(:ruby_version) { 2.2 }
129
142
  end
130
143
 
131
- RSpec.shared_context 'ruby 2.3', :ruby23 do
144
+ RSpec.shared_context 'ruby 2.3' do
132
145
  let(:ruby_version) { 2.3 }
133
146
  end
134
147
 
135
- RSpec.shared_context 'ruby 2.4', :ruby24 do
148
+ RSpec.shared_context 'ruby 2.4' do
136
149
  let(:ruby_version) { 2.4 }
137
150
  end
138
151
 
139
- RSpec.shared_context 'ruby 2.5', :ruby25 do
152
+ RSpec.shared_context 'ruby 2.5' do
140
153
  let(:ruby_version) { 2.5 }
141
154
  end
142
155
 
143
- RSpec.shared_context 'ruby 2.6', :ruby26 do
156
+ RSpec.shared_context 'ruby 2.6' do
144
157
  let(:ruby_version) { 2.6 }
145
158
  end
146
159
 
147
- RSpec.shared_context 'ruby 2.7', :ruby27 do
160
+ RSpec.shared_context 'ruby 2.7' do
148
161
  let(:ruby_version) { 2.7 }
149
162
  end
150
163
 
151
- RSpec.shared_context 'ruby 3.0', :ruby30 do
164
+ RSpec.shared_context 'ruby 3.0' do
152
165
  let(:ruby_version) { 3.0 }
153
166
  end
154
167
 
155
- RSpec.shared_context 'ruby 3.1', :ruby31 do
168
+ RSpec.shared_context 'ruby 3.1' do
156
169
  let(:ruby_version) { 3.1 }
157
170
  end
158
171
 
159
- RSpec.shared_context 'ruby 3.2', :ruby32 do
172
+ RSpec.shared_context 'ruby 3.2' do
160
173
  let(:ruby_version) { 3.2 }
161
174
  end
175
+
176
+ RSpec.shared_context 'ruby 3.3' do
177
+ let(:ruby_version) { 3.3 }
178
+ end
@@ -3,12 +3,27 @@
3
3
  # Require this file to load code that supports testing using RSpec.
4
4
 
5
5
  require_relative 'cop_helper'
6
- require_relative 'host_environment_simulation_helper'
7
- require_relative 'shared_contexts'
8
6
  require_relative 'expect_offense'
7
+ require_relative 'host_environment_simulation_helper'
9
8
  require_relative 'parallel_formatter'
9
+ require_relative 'shared_contexts'
10
10
 
11
11
  RSpec.configure do |config|
12
12
  config.include CopHelper
13
13
  config.include HostEnvironmentSimulatorHelper
14
+ config.include_context 'config', :config
15
+ config.include_context 'isolated environment', :isolated_environment
16
+ config.include_context 'maintain registry', :restore_registry
17
+ config.include_context 'ruby 2.0', :ruby20
18
+ config.include_context 'ruby 2.1', :ruby21
19
+ config.include_context 'ruby 2.2', :ruby22
20
+ config.include_context 'ruby 2.3', :ruby23
21
+ config.include_context 'ruby 2.4', :ruby24
22
+ config.include_context 'ruby 2.5', :ruby25
23
+ config.include_context 'ruby 2.6', :ruby26
24
+ config.include_context 'ruby 2.7', :ruby27
25
+ config.include_context 'ruby 3.0', :ruby30
26
+ config.include_context 'ruby 3.1', :ruby31
27
+ config.include_context 'ruby 3.2', :ruby32
28
+ config.include_context 'ruby 3.3', :ruby33
14
29
  end
@@ -24,9 +24,35 @@ module RuboCop
24
24
  end
25
25
  end
26
26
 
27
+ class << self
28
+ # @return [Array<#call>]
29
+ def ruby_extractors
30
+ @ruby_extractors ||= [default_ruby_extractor]
31
+ end
32
+
33
+ private
34
+
35
+ # @return [#call]
36
+ def default_ruby_extractor
37
+ lambda do |processed_source|
38
+ [
39
+ {
40
+ offset: 0,
41
+ processed_source: processed_source
42
+ }
43
+ ]
44
+ end
45
+ end
46
+ end
47
+
27
48
  # @api private
28
49
  MAX_ITERATIONS = 200
29
50
 
51
+ # @api private
52
+ REDUNDANT_COP_DISABLE_DIRECTIVE_RULES = %w[
53
+ Lint/RedundantCopDisableDirective RedundantCopDisableDirective Lint
54
+ ].freeze
55
+
30
56
  attr_reader :errors, :warnings
31
57
  attr_writer :aborting
32
58
 
@@ -63,8 +89,16 @@ module RuboCop
63
89
  # Warms up the RuboCop cache by forking a suitable number of RuboCop
64
90
  # instances that each inspects its allotted group of files.
65
91
  def warm_cache(target_files)
92
+ saved_options = @options.dup
93
+ if target_files.length <= 1
94
+ puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug]
95
+ return
96
+ end
66
97
  puts 'Running parallel inspection' if @options[:debug]
98
+ %i[autocorrect safe_autocorrect].each { |opt| @options[opt] = false }
67
99
  Parallel.each(target_files) { |target_file| file_offenses(target_file) }
100
+ ensure
101
+ @options = saved_options
68
102
  end
69
103
 
70
104
  def find_target_files(paths)
@@ -186,7 +220,9 @@ module RuboCop
186
220
  end
187
221
 
188
222
  def check_for_redundant_disables?(source)
189
- !source.disabled_line_ranges.empty? && !filtered_run?
223
+ return false if source.disabled_line_ranges.empty? || except_redundant_cop_disable_directive?
224
+
225
+ !@options[:only]
190
226
  end
191
227
 
192
228
  def redundant_cop_disable_directive(file)
@@ -197,8 +233,8 @@ module RuboCop
197
233
  yield cop if cop.relevant_file?(file)
198
234
  end
199
235
 
200
- def filtered_run?
201
- @options[:except] || @options[:only]
236
+ def except_redundant_cop_disable_directive?
237
+ @options[:except] && (@options[:except] & REDUNDANT_COP_DISABLE_DIRECTIVE_RULES).any?
202
238
  end
203
239
 
204
240
  def file_started(file)
@@ -304,10 +340,25 @@ module RuboCop
304
340
  end
305
341
 
306
342
  def inspect_file(processed_source, team = mobilize_team(processed_source))
307
- report = team.investigate(processed_source)
308
- @errors.concat(team.errors)
309
- @warnings.concat(team.warnings)
310
- [report.offenses, team.updated_source_file?]
343
+ extracted_ruby_sources = extract_ruby_sources(processed_source)
344
+ offenses = extracted_ruby_sources.flat_map do |extracted_ruby_source|
345
+ report = team.investigate(
346
+ extracted_ruby_source[:processed_source],
347
+ offset: extracted_ruby_source[:offset],
348
+ original: processed_source
349
+ )
350
+ @errors.concat(team.errors)
351
+ @warnings.concat(team.warnings)
352
+ report.offenses
353
+ end
354
+ [offenses, team.updated_source_file?]
355
+ end
356
+
357
+ def extract_ruby_sources(processed_source)
358
+ self.class.ruby_extractors.find do |ruby_extractor|
359
+ result = ruby_extractor.call(processed_source)
360
+ break result if result
361
+ end
311
362
  end
312
363
 
313
364
  def mobilize_team(processed_source)
@@ -415,17 +466,21 @@ module RuboCop
415
466
  end
416
467
 
417
468
  def get_processed_source(file)
418
- ruby_version = @config_store.for_file(file).target_ruby_version
419
-
420
- if @options[:stdin]
421
- ProcessedSource.new(@options[:stdin], ruby_version, file)
422
- else
423
- begin
424
- ProcessedSource.from_file(file, ruby_version)
425
- rescue Errno::ENOENT
426
- raise RuboCop::Error, "No such file or directory: #{file}"
427
- end
428
- end
469
+ config = @config_store.for_file(file)
470
+ ruby_version = config.target_ruby_version
471
+
472
+ processed_source = if @options[:stdin]
473
+ ProcessedSource.new(@options[:stdin], ruby_version, file)
474
+ else
475
+ begin
476
+ ProcessedSource.from_file(file, ruby_version)
477
+ rescue Errno::ENOENT
478
+ raise RuboCop::Error, "No such file or directory: #{file}"
479
+ end
480
+ end
481
+ processed_source.config = config
482
+ processed_source.registry = mobilized_cop_classes(config)
483
+ processed_source
429
484
  end
430
485
 
431
486
  # A Cop::Team instance is stateful and may change when inspecting.
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
+ require_relative '../cache_config'
5
+ require_relative '../config_finder'
4
6
 
5
7
  #
6
8
  # This code is based on https://github.com/fohte/rubocop-daemon.
@@ -19,6 +21,8 @@ module RuboCop
19
21
  GEMFILE_NAMES = %w[Gemfile gems.rb].freeze
20
22
 
21
23
  class << self
24
+ attr_accessor :cache_root_path
25
+
22
26
  # Searches for Gemfile or gems.rb in the current dir or any parent dirs
23
27
  def project_dir
24
28
  current_dir = Dir.pwd
@@ -38,12 +42,50 @@ module RuboCop
38
42
  end
39
43
 
40
44
  def dir
41
- cache_path = File.expand_path('~/.cache/rubocop_cache/server')
42
45
  Pathname.new(File.join(cache_path, project_dir_cache_key)).tap do |d|
43
46
  d.mkpath unless d.exist?
44
47
  end
45
48
  end
46
49
 
50
+ def cache_path
51
+ cache_root_dir = if cache_root_path
52
+ File.join(cache_root_path, 'rubocop_cache')
53
+ else
54
+ cache_root_dir_from_config
55
+ end
56
+
57
+ File.expand_path(File.join(cache_root_dir, 'server'))
58
+ end
59
+
60
+ # rubocop:disable Metrics/MethodLength
61
+ def cache_root_dir_from_config
62
+ CacheConfig.root_dir do
63
+ # `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
64
+ # so that only the necessary `CacheRootDirectory` can be obtained.
65
+ config_path = ConfigFinder.find_config_path(Dir.pwd)
66
+ file_contents = File.read(config_path)
67
+
68
+ # Returns early if `CacheRootDirectory` is not used before requiring `erb` or `yaml`.
69
+ next unless file_contents.include?('CacheRootDirectory')
70
+
71
+ require 'erb'
72
+ yaml_code = ERB.new(file_contents).result
73
+
74
+ require 'yaml'
75
+ config_yaml = YAML.safe_load(
76
+ yaml_code, permitted_classes: [Regexp, Symbol], aliases: true
77
+ )
78
+
79
+ # For compatibility with Ruby 3.0 or lower.
80
+ if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
81
+ config_yaml == false ? nil : config_yaml
82
+ end
83
+
84
+ config_yaml&.dig('AllCops', 'CacheRootDirectory')
85
+ end
86
+ end
87
+ # rubocop:enable Metrics/MethodLength
88
+
47
89
  def port_path
48
90
  dir.join('port')
49
91
  end
@@ -68,9 +110,13 @@ module RuboCop
68
110
  dir.join('version')
69
111
  end
70
112
 
113
+ def stderr_path
114
+ dir.join('stderr')
115
+ end
116
+
71
117
  def pid_running?
72
118
  Process.kill(0, pid_path.read.to_i) == 1
73
- rescue Errno::ESRCH
119
+ rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES
74
120
  false
75
121
  end
76
122
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'optparse'
4
- require 'rainbow'
3
+ require_relative '../arguments_env'
4
+ require_relative '../arguments_file'
5
5
 
6
6
  #
7
7
  # This code is based on https://github.com/fohte/rubocop-daemon.
@@ -22,9 +22,16 @@ module RuboCop
22
22
  STATUS_ERROR = 2
23
23
 
24
24
  SERVER_OPTIONS = %w[
25
- --server --no-server --server-status --restart-server --start-server --stop-server
25
+ --server
26
+ --no-server
27
+ --server-status
28
+ --restart-server
29
+ --start-server
30
+ --stop-server
31
+ --no-detach
26
32
  ].freeze
27
33
  EXCLUSIVE_OPTIONS = (SERVER_OPTIONS - %w[--server --no-server]).freeze
34
+ NO_DETACH_OPTIONS = %w[--server --start-server --restart-server].freeze
28
35
 
29
36
  def initialize
30
37
  @exit = false
@@ -37,34 +44,53 @@ module RuboCop
37
44
  return STATUS_SUCCESS
38
45
  end
39
46
 
40
- deleted_server_arguments = delete_server_argument_from(argv)
47
+ Cache.cache_root_path = fetch_cache_root_path_from(argv)
41
48
 
42
- if deleted_server_arguments.size >= 2
43
- return error("#{deleted_server_arguments.join(', ')} cannot be specified together.")
49
+ process_arguments(argv)
50
+ end
51
+
52
+ def exit?
53
+ @exit
54
+ end
55
+
56
+ private
57
+
58
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
59
+ def process_arguments(argv)
60
+ server_arguments = delete_server_argument_from(argv)
61
+
62
+ detach = !server_arguments.delete('--no-detach')
63
+
64
+ if server_arguments.size >= 2
65
+ return error("#{server_arguments.join(', ')} cannot be specified together.")
44
66
  end
45
67
 
46
- server_command = deleted_server_arguments.first
68
+ server_command = server_arguments.first
47
69
 
48
- if EXCLUSIVE_OPTIONS.include?(server_command) && argv.count >= 2
49
- return error("#{server_command} cannot be combined with other options.")
70
+ unless detach || NO_DETACH_OPTIONS.include?(server_command)
71
+ return error("#{server_command} cannot be combined with --no-detach.")
50
72
  end
51
73
 
52
- run_command(server_command)
74
+ if EXCLUSIVE_OPTIONS.include?(server_command) && argv.count > allowed_option_count
75
+ return error("#{server_command} cannot be combined with #{argv[0]}.")
76
+ end
53
77
 
54
- STATUS_SUCCESS
55
- end
78
+ if server_command.nil?
79
+ server_command = ArgumentsEnv.read_as_arguments.delete('--server') ||
80
+ ArgumentsFile.read_as_arguments.delete('--server')
81
+ end
56
82
 
57
- def exit?
58
- @exit
59
- end
83
+ run_command(server_command, detach: detach)
60
84
 
61
- private
85
+ STATUS_SUCCESS
86
+ end
87
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
62
88
 
63
89
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength:
64
- def run_command(server_command)
90
+ def run_command(server_command, detach:)
65
91
  case server_command
66
92
  when '--server'
67
- Server::ClientCommand::Start.new.run unless Server.running?
93
+ Server::ClientCommand::Start.new(detach: detach).run unless Server.running?
68
94
  when '--no-server'
69
95
  Server::ClientCommand::Stop.new.run if Server.running?
70
96
  when '--restart-server'
@@ -72,7 +98,7 @@ module RuboCop
72
98
  Server::ClientCommand::Restart.new.run
73
99
  when '--start-server'
74
100
  @exit = true
75
- Server::ClientCommand::Start.new.run
101
+ Server::ClientCommand::Start.new(detach: detach).run
76
102
  when '--stop-server'
77
103
  @exit = true
78
104
  Server::ClientCommand::Stop.new.run
@@ -83,6 +109,17 @@ module RuboCop
83
109
  end
84
110
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength:
85
111
 
112
+ def fetch_cache_root_path_from(arguments)
113
+ cache_root = arguments.detect { |argument| argument.start_with?('--cache-root') }
114
+ return unless cache_root
115
+
116
+ if cache_root.start_with?('--cache-root=')
117
+ cache_root.split('=')[1]
118
+ else
119
+ arguments[arguments.index(cache_root) + 1]
120
+ end
121
+ end
122
+
86
123
  def delete_server_argument_from(all_arguments)
87
124
  SERVER_OPTIONS.each_with_object([]) do |server_option, server_arguments|
88
125
  server_arguments << all_arguments.delete(server_option)
@@ -93,7 +130,13 @@ module RuboCop
93
130
  (argv & SERVER_OPTIONS).any?
94
131
  end
95
132
 
133
+ def allowed_option_count
134
+ Cache.cache_root_path ? 2 : 1
135
+ end
136
+
96
137
  def error(message)
138
+ require 'rainbow'
139
+
97
140
  @exit = true
98
141
  warn Rainbow(message).red
99
142