rubocop 0.76.0 → 0.83.0

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 (289) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +6 -6
  4. data/config/default.yml +466 -306
  5. data/lib/rubocop/ast/builder.rb +45 -42
  6. data/lib/rubocop/ast/node/array_node.rb +13 -0
  7. data/lib/rubocop/ast/node/block_node.rb +7 -1
  8. data/lib/rubocop/ast/node/case_match_node.rb +56 -0
  9. data/lib/rubocop/ast/node/def_node.rb +11 -0
  10. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  11. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +8 -0
  12. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  13. data/lib/rubocop/ast/node/send_node.rb +4 -0
  14. data/lib/rubocop/ast/node.rb +13 -20
  15. data/lib/rubocop/ast/traversal.rb +29 -10
  16. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  17. data/lib/rubocop/cli/command/base.rb +33 -0
  18. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  19. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  20. data/lib/rubocop/cli/command/show_cops.rb +80 -0
  21. data/lib/rubocop/cli/command/version.rb +17 -0
  22. data/lib/rubocop/cli/command.rb +21 -0
  23. data/lib/rubocop/cli/environment.rb +21 -0
  24. data/lib/rubocop/cli.rb +20 -233
  25. data/lib/rubocop/comment_config.rb +6 -1
  26. data/lib/rubocop/config.rb +41 -11
  27. data/lib/rubocop/config_loader.rb +54 -44
  28. data/lib/rubocop/config_loader_resolver.rb +28 -1
  29. data/lib/rubocop/config_obsoletion.rb +67 -11
  30. data/lib/rubocop/config_validator.rb +74 -99
  31. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  32. data/lib/rubocop/cop/badge.rb +5 -5
  33. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  34. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +3 -3
  35. data/lib/rubocop/cop/cop.rb +21 -0
  36. data/lib/rubocop/cop/corrector.rb +48 -24
  37. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
  38. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -2
  39. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  40. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +3 -3
  41. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  42. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  43. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  44. data/lib/rubocop/cop/correctors/string_literal_corrector.rb +2 -2
  45. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  46. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  47. data/lib/rubocop/cop/generator.rb +6 -6
  48. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  49. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -1
  50. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  51. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  52. data/lib/rubocop/cop/layout/array_alignment.rb +82 -0
  53. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
  54. data/lib/rubocop/cop/layout/block_end_newline.rb +5 -3
  55. data/lib/rubocop/cop/layout/condition_position.rb +12 -2
  56. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  57. data/lib/rubocop/cop/layout/else_alignment.rb +8 -0
  58. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  59. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +68 -0
  60. data/lib/rubocop/cop/layout/end_of_line.rb +2 -2
  61. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  62. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +5 -5
  63. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +20 -14
  64. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  65. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  66. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +10 -6
  67. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  68. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +7 -7
  69. data/lib/rubocop/cop/layout/{tab.rb → indentation_style.rb} +48 -6
  70. data/lib/rubocop/cop/layout/leading_comment_space.rb +34 -3
  71. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  72. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +72 -110
  73. data/lib/rubocop/cop/layout/multiline_block_layout.rb +15 -6
  74. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  75. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  76. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  77. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +13 -4
  78. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +3 -3
  80. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  81. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +133 -0
  82. data/lib/rubocop/cop/layout/space_around_operators.rb +69 -9
  83. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -1
  86. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -2
  87. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  88. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +2 -2
  89. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  90. data/lib/rubocop/cop/layout/trailing_whitespace.rb +2 -2
  91. data/lib/rubocop/cop/lint/ambiguous_operator.rb +38 -0
  92. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +14 -0
  93. data/lib/rubocop/cop/lint/boolean_symbol.rb +12 -0
  94. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  95. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  96. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  97. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -5
  98. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  99. data/lib/rubocop/cop/lint/empty_when.rb +29 -6
  100. data/lib/rubocop/cop/lint/ensure_return.rb +18 -1
  101. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  102. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  103. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  104. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  105. data/lib/rubocop/cop/lint/interpolation_check.rb +1 -1
  106. data/lib/rubocop/cop/lint/literal_as_condition.rb +10 -13
  107. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  108. data/lib/rubocop/cop/lint/loop.rb +6 -4
  109. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +2 -2
  110. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  111. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  112. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +21 -9
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -2
  115. data/lib/rubocop/cop/lint/raise_exception.rb +75 -0
  116. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +4 -9
  117. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +13 -8
  118. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  119. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +2 -2
  120. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  121. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  122. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
  123. data/lib/rubocop/cop/lint/struct_new_override.rb +58 -0
  124. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +13 -29
  125. data/lib/rubocop/cop/lint/unified_integer.rb +0 -2
  126. data/lib/rubocop/cop/lint/unused_method_argument.rb +32 -6
  127. data/lib/rubocop/cop/lint/uri_regexp.rb +4 -4
  128. data/lib/rubocop/cop/lint/useless_access_modifier.rb +69 -23
  129. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -2
  130. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +5 -0
  131. data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
  132. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  133. data/lib/rubocop/cop/migration/department_name.rb +47 -6
  134. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  135. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  136. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +6 -1
  137. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -5
  138. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  139. data/lib/rubocop/cop/mixin/hash_transform_method.rb +178 -0
  140. data/lib/rubocop/cop/mixin/line_length_help.rb +89 -0
  141. data/lib/rubocop/cop/mixin/method_complexity.rb +5 -0
  142. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  143. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -1
  144. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  145. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -24
  146. data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
  147. data/lib/rubocop/cop/mixin/trailing_comma.rb +9 -13
  148. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  149. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  150. data/lib/rubocop/cop/naming/constant_name.rb +2 -1
  151. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +6 -6
  152. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  153. data/lib/rubocop/cop/naming/method_name.rb +26 -0
  154. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
  155. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  156. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  157. data/lib/rubocop/cop/offense.rb +11 -0
  158. data/lib/rubocop/cop/registry.rb +15 -3
  159. data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -6
  160. data/lib/rubocop/cop/style/alias.rb +5 -5
  161. data/lib/rubocop/cop/style/and_or.rb +5 -6
  162. data/lib/rubocop/cop/style/array_join.rb +2 -2
  163. data/lib/rubocop/cop/style/attr.rb +8 -0
  164. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  165. data/lib/rubocop/cop/style/case_equality.rb +24 -1
  166. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  167. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  168. data/lib/rubocop/cop/style/conditional_assignment.rb +10 -10
  169. data/lib/rubocop/cop/style/copyright.rb +1 -1
  170. data/lib/rubocop/cop/style/dir.rb +1 -1
  171. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +49 -0
  172. data/lib/rubocop/cop/style/documentation.rb +43 -5
  173. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +1 -1
  174. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  175. data/lib/rubocop/cop/style/each_with_object.rb +3 -3
  176. data/lib/rubocop/cop/style/empty_method.rb +1 -5
  177. data/lib/rubocop/cop/style/end_block.rb +6 -0
  178. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  179. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  180. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -3
  181. data/lib/rubocop/cop/style/exponential_notation.rb +119 -0
  182. data/lib/rubocop/cop/style/format_string.rb +2 -2
  183. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
  184. data/lib/rubocop/cop/style/guard_clause.rb +28 -4
  185. data/lib/rubocop/cop/style/hash_each_methods.rb +89 -0
  186. data/lib/rubocop/cop/style/hash_syntax.rb +3 -5
  187. data/lib/rubocop/cop/style/hash_transform_keys.rb +83 -0
  188. data/lib/rubocop/cop/style/hash_transform_values.rb +80 -0
  189. data/lib/rubocop/cop/style/if_unless_modifier.rb +61 -6
  190. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -0
  191. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  192. data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
  193. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  194. data/lib/rubocop/cop/style/lambda.rb +3 -2
  195. data/lib/rubocop/cop/style/lambda_call.rb +1 -21
  196. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  197. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  198. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  199. data/lib/rubocop/cop/style/mixin_grouping.rb +2 -2
  200. data/lib/rubocop/cop/style/module_function.rb +58 -12
  201. data/lib/rubocop/cop/style/multiline_if_modifier.rb +1 -1
  202. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  203. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  204. data/lib/rubocop/cop/style/multiline_when_then.rb +21 -2
  205. data/lib/rubocop/cop/style/mutable_constant.rb +2 -4
  206. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -9
  207. data/lib/rubocop/cop/style/next.rb +7 -7
  208. data/lib/rubocop/cop/style/nil_comparison.rb +1 -1
  209. data/lib/rubocop/cop/style/non_nil_check.rb +4 -4
  210. data/lib/rubocop/cop/style/not.rb +1 -1
  211. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  212. data/lib/rubocop/cop/style/numeric_literals.rb +8 -4
  213. data/lib/rubocop/cop/style/numeric_predicate.rb +5 -4
  214. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
  215. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  216. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  217. data/lib/rubocop/cop/style/or_assignment.rb +4 -3
  218. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  219. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  220. data/lib/rubocop/cop/style/perl_backrefs.rb +2 -2
  221. data/lib/rubocop/cop/style/proc.rb +1 -1
  222. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  223. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  224. data/lib/rubocop/cop/style/redundant_condition.rb +18 -6
  225. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
  226. data/lib/rubocop/cop/style/redundant_exception.rb +3 -3
  227. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  228. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
  229. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
  230. data/lib/rubocop/cop/style/redundant_return.rb +7 -15
  231. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  232. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  233. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  234. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  235. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  236. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  237. data/lib/rubocop/cop/style/slicing_with_range.rb +39 -0
  238. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  239. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -4
  240. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -1
  241. data/lib/rubocop/cop/style/symbol_array.rb +3 -3
  242. data/lib/rubocop/cop/style/symbol_literal.rb +2 -2
  243. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
  244. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +35 -22
  245. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +41 -0
  246. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +88 -0
  247. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +44 -0
  248. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  249. data/lib/rubocop/cop/style/trivial_accessors.rb +6 -6
  250. data/lib/rubocop/cop/style/unpack_first.rb +0 -4
  251. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -1
  252. data/lib/rubocop/cop/style/while_until_modifier.rb +2 -2
  253. data/lib/rubocop/cop/style/word_array.rb +1 -1
  254. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  255. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
  256. data/lib/rubocop/cop/team.rb +5 -0
  257. data/lib/rubocop/cop/util.rb +24 -0
  258. data/lib/rubocop/cop/variable_force/assignment.rb +1 -0
  259. data/lib/rubocop/cop/variable_force/scope.rb +1 -0
  260. data/lib/rubocop/cop/variable_force/variable.rb +1 -0
  261. data/lib/rubocop/cop/variable_force.rb +4 -1
  262. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  263. data/lib/rubocop/formatter/clang_style_formatter.rb +0 -2
  264. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  265. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  266. data/lib/rubocop/formatter/junit_formatter.rb +74 -0
  267. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  268. data/lib/rubocop/formatter/tap_formatter.rb +0 -2
  269. data/lib/rubocop/name_similarity.rb +12 -9
  270. data/lib/rubocop/node_pattern.rb +97 -11
  271. data/lib/rubocop/options.rb +26 -13
  272. data/lib/rubocop/processed_source.rb +1 -4
  273. data/lib/rubocop/rake_task.rb +1 -0
  274. data/lib/rubocop/result_cache.rb +23 -7
  275. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  276. data/lib/rubocop/rspec/expect_offense.rb +1 -1
  277. data/lib/rubocop/rspec/shared_contexts.rb +5 -4
  278. data/lib/rubocop/runner.rb +25 -4
  279. data/lib/rubocop/target_finder.rb +6 -4
  280. data/lib/rubocop/target_ruby.rb +151 -0
  281. data/lib/rubocop/version.rb +1 -1
  282. data/lib/rubocop.rb +53 -27
  283. metadata +73 -48
  284. data/lib/rubocop/cop/layout/align_array.rb +0 -39
  285. data/lib/rubocop/cop/lint/end_in_method.rb +0 -40
  286. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
  287. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
  288. data/lib/rubocop/formatter/disabled_lines_formatter.rb +0 -57
  289. data/lib/rubocop/string_util.rb +0 -14
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Generate a .rubocop.yml file in the current directory.
7
+ class InitDotfile < Base
8
+ DOTFILE = ConfigLoader::DOTFILE
9
+
10
+ self.command_name = :init
11
+
12
+ def run
13
+ path = File.expand_path(DOTFILE)
14
+
15
+ if File.exist?(DOTFILE)
16
+ warn Rainbow("#{DOTFILE} already exists at #{path}").red
17
+
18
+ STATUS_ERROR
19
+ else
20
+ description = <<~DESC
21
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
22
+ # configuration file. It makes it possible to enable/disable
23
+ # certain cops (checks) and to alter their behavior if they accept
24
+ # any parameters. The file can be placed either in your home
25
+ # directory or in some project directory.
26
+ #
27
+ # RuboCop will start looking for the configuration file in the directory
28
+ # where the inspected file is and continue its way up to the root directory.
29
+ #
30
+ # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
31
+ DESC
32
+
33
+ File.open(DOTFILE, 'w') do |f|
34
+ f.write(description)
35
+ end
36
+
37
+ puts "Writing new #{DOTFILE} to #{path}"
38
+
39
+ STATUS_SUCCESS
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Shows the given cops, or all cops by default, and their configurations
7
+ # for the current directory.
8
+ class ShowCops < Base
9
+ self.command_name = :show_cops
10
+
11
+ def initialize(env)
12
+ super
13
+
14
+ # Load the configs so the require()s are done for custom cops
15
+ @config = @config_store.for(Dir.pwd)
16
+ end
17
+
18
+ def run
19
+ print_available_cops
20
+ end
21
+
22
+ private
23
+
24
+ def print_available_cops
25
+ registry = Cop::Cop.registry
26
+ show_all = @options[:show_cops].empty?
27
+
28
+ if show_all
29
+ puts "# Available cops (#{registry.length}) " \
30
+ "+ config for #{Dir.pwd}: "
31
+ end
32
+
33
+ registry.departments.sort!.each do |department|
34
+ print_cops_of_department(registry, department, show_all)
35
+ end
36
+ end
37
+
38
+ def print_cops_of_department(registry, department, show_all)
39
+ selected_cops = if show_all
40
+ cops_of_department(registry, department)
41
+ else
42
+ selected_cops_of_department(registry, department)
43
+ end
44
+
45
+ if show_all
46
+ puts "# Department '#{department}' (#{selected_cops.length}):"
47
+ end
48
+
49
+ print_cop_details(selected_cops)
50
+ end
51
+
52
+ def print_cop_details(cops)
53
+ cops.each do |cop|
54
+ if cop.new(@config).support_autocorrect?
55
+ puts '# Supports --auto-correct'
56
+ end
57
+ puts "#{cop.cop_name}:"
58
+ puts config_lines(cop)
59
+ puts
60
+ end
61
+ end
62
+
63
+ def selected_cops_of_department(cops, department)
64
+ cops_of_department(cops, department).select do |cop|
65
+ @options[:show_cops].include?(cop.cop_name)
66
+ end
67
+ end
68
+
69
+ def cops_of_department(cops, department)
70
+ cops.with_department(department).sort!
71
+ end
72
+
73
+ def config_lines(cop)
74
+ cnf = @config.for_cop(cop)
75
+ cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Display version.
7
+ class Version < Base
8
+ self.command_name = :version
9
+
10
+ def run
11
+ puts RuboCop::Version.version(false) if @options[:version]
12
+ puts RuboCop::Version.version(true) if @options[:verbose_version]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ # Home of subcommands in the CLI.
6
+ module Command
7
+ class << self
8
+ # Find the command with a given name and run it in an environment.
9
+ def run(env, name)
10
+ class_for(name).new(env).run
11
+ end
12
+
13
+ private
14
+
15
+ def class_for(name)
16
+ Base.by_command_name(name)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ # Execution environment for a CLI command.
6
+ class Environment
7
+ attr_reader :options, :config_store, :paths
8
+
9
+ def initialize(options, config_store, paths)
10
+ @options = options
11
+ @config_store = config_store
12
+ @paths = paths
13
+ end
14
+
15
+ # Run a command in this environment.
16
+ def run(name)
17
+ Command.run(self, name)
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/rubocop/cli.rb CHANGED
@@ -1,20 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/ClassLength
4
3
  module RuboCop
5
4
  # The CLI is a class responsible of handling all the command line interface
6
5
  # logic.
7
6
  class CLI
8
- include Formatter::TextUtil
9
-
10
- PHASE_1 = 'Phase 1 of 2: run Metrics/LineLength cop'
11
- PHASE_2 = 'Phase 2 of 2: run all cops'
12
-
13
- PHASE_1_OVERRIDDEN = '(skipped because the default Metrics/LineLength:Max' \
14
- ' is overridden)'
15
- PHASE_1_DISABLED = '(skipped because Metrics/LineLength is ' \
16
- 'disabled)'
17
-
18
7
  STATUS_SUCCESS = 0
19
8
  STATUS_OFFENSES = 1
20
9
  STATUS_ERROR = 2
@@ -41,14 +30,15 @@ module RuboCop
41
30
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
42
31
  def run(args = ARGV)
43
32
  @options, paths = Options.new.parse(args)
33
+ @env = Environment.new(@options, @config_store, paths)
44
34
 
45
35
  if @options[:init]
46
- init_dotfile
36
+ run_command(:init)
47
37
  else
48
- validate_options_vs_config
49
38
  act_on_options
39
+ validate_options_vs_config
50
40
  apply_default_formatter
51
- execute_runners(paths)
41
+ execute_runners
52
42
  end
53
43
  rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
54
44
  warn e.message
@@ -71,113 +61,18 @@ module RuboCop
71
61
 
72
62
  private
73
63
 
74
- def execute_runners(paths)
75
- if @options[:auto_gen_config]
76
- reset_config_and_auto_gen_file
77
- line_length_contents = maybe_run_line_length_cop(paths)
78
- run_all_cops_auto_gen_config(line_length_contents, paths)
79
- else
80
- execute_runner(paths)
81
- end
82
- end
83
-
84
- def maybe_run_line_length_cop(paths)
85
- if !line_length_enabled?(@config_store.for(Dir.pwd))
86
- skip_line_length_cop(PHASE_1_DISABLED)
87
- elsif !same_max_line_length?(
88
- @config_store.for(Dir.pwd), ConfigLoader.default_configuration
89
- )
90
- skip_line_length_cop(PHASE_1_OVERRIDDEN)
91
- else
92
- run_line_length_cop_auto_gen_config(paths)
93
- end
94
- end
95
-
96
- def skip_line_length_cop(reason)
97
- puts Rainbow("#{PHASE_1} #{reason}").yellow
98
- ''
99
- end
100
-
101
- def line_length_enabled?(config)
102
- line_length_cop(config)['Enabled']
103
- end
104
-
105
- def same_max_line_length?(config1, config2)
106
- max_line_length(config1) == max_line_length(config2)
107
- end
108
-
109
- def max_line_length(config)
110
- line_length_cop(config)['Max']
111
- end
112
-
113
- def line_length_cop(config)
114
- config.for_cop('Metrics/LineLength')
64
+ def run_command(name)
65
+ @env.run(name)
115
66
  end
116
67
 
117
- # Do an initial run with only Metrics/LineLength so that cops that depend
118
- # on Metrics/LineLength:Max get the correct value for that parameter.
119
- def run_line_length_cop_auto_gen_config(paths)
120
- puts Rainbow(PHASE_1).yellow
121
- @options[:only] = ['Metrics/LineLength']
122
- execute_runner(paths)
123
- @options.delete(:only)
124
- @config_store = ConfigStore.new
125
- # Save the todo configuration of the LineLength cop.
126
- IO.read(ConfigLoader::AUTO_GENERATED_FILE)
127
- .lines
128
- .drop_while { |line| line.start_with?('#') }
129
- .join
130
- end
131
-
132
- def run_all_cops_auto_gen_config(line_length_contents, paths)
133
- puts Rainbow(PHASE_2).yellow
134
- result = execute_runner(paths)
135
- # This run was made with the current maximum length allowed, so append
136
- # the saved setting for LineLength.
137
- File.open(ConfigLoader::AUTO_GENERATED_FILE, 'a') do |f|
138
- f.write(line_length_contents)
139
- end
140
- result
141
- end
142
-
143
- def init_dotfile
144
- path = File.expand_path(ConfigLoader::DOTFILE)
145
-
146
- if File.exist?(ConfigLoader::DOTFILE)
147
- warn Rainbow("#{ConfigLoader::DOTFILE} already exists at #{path}").red
148
-
149
- STATUS_ERROR
68
+ def execute_runners
69
+ if @options[:auto_gen_config]
70
+ run_command(:auto_gen_config)
150
71
  else
151
- description = <<~DESC
152
- # The behavior of RuboCop can be controlled via the .rubocop.yml
153
- # configuration file. It makes it possible to enable/disable
154
- # certain cops (checks) and to alter their behavior if they accept
155
- # any parameters. The file can be placed either in your home
156
- # directory or in some project directory.
157
- #
158
- # RuboCop will start looking for the configuration file in the directory
159
- # where the inspected file is and continue its way up to the root directory.
160
- #
161
- # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
162
- DESC
163
-
164
- File.open(ConfigLoader::DOTFILE, 'w') do |f|
165
- f.write(description)
166
- end
167
-
168
- puts "Writing new #{ConfigLoader::DOTFILE} to #{path}"
169
-
170
- STATUS_SUCCESS
72
+ run_command(:execute_runner)
171
73
  end
172
74
  end
173
75
 
174
- def reset_config_and_auto_gen_file
175
- @config_store = ConfigStore.new
176
- @config_store.options_config = @options[:config] if @options[:config]
177
- File.open(ConfigLoader::AUTO_GENERATED_FILE, 'w') {}
178
- ConfigLoader.add_inheritance_from_auto_generated_file
179
- end
180
-
181
76
  def validate_options_vs_config
182
77
  if @options[:parallel] &&
183
78
  !@config_store.for(Dir.pwd).for_all_cops['UseCache']
@@ -188,10 +83,7 @@ module RuboCop
188
83
  end
189
84
 
190
85
  def act_on_options
191
- ConfigLoader.debug = @options[:debug]
192
- ConfigLoader.auto_gen_config = @options[:auto_gen_config]
193
- ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion]
194
- ConfigLoader.options_config = @options[:config]
86
+ set_options_to_config_loader
195
87
 
196
88
  @config_store.options_config = @options[:config] if @options[:config]
197
89
  @config_store.force_default_config! if @options[:force_default_config]
@@ -207,31 +99,20 @@ module RuboCop
207
99
  end
208
100
  end
209
101
 
210
- def execute_runner(paths)
211
- runner = Runner.new(@options, @config_store)
212
-
213
- all_passed = runner.run(paths)
214
- display_warning_summary(runner.warnings)
215
- display_error_summary(runner.errors)
216
- maybe_print_corrected_source
217
-
218
- all_pass_or_excluded = all_passed || @options[:auto_gen_config]
219
-
220
- if runner.aborting?
221
- STATUS_INTERRUPTED
222
- elsif all_pass_or_excluded && runner.errors.empty?
223
- STATUS_SUCCESS
224
- else
225
- STATUS_OFFENSES
226
- end
102
+ def set_options_to_config_loader
103
+ ConfigLoader.debug = @options[:debug]
104
+ ConfigLoader.auto_gen_config = @options[:auto_gen_config]
105
+ ConfigLoader.disable_pending_cops = @options[:disable_pending_cops]
106
+ ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
107
+ ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion]
108
+ ConfigLoader.options_config = @options[:config]
227
109
  end
228
110
 
229
111
  def handle_exiting_options
230
112
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
231
113
 
232
- puts RuboCop::Version.version(false) if @options[:version]
233
- puts RuboCop::Version.version(true) if @options[:verbose_version]
234
- print_available_cops if @options[:show_cops]
114
+ run_command(:version) if @options[:version] || @options[:verbose_version]
115
+ run_command(:show_cops) if @options[:show_cops]
235
116
  raise Finished
236
117
  end
237
118
 
@@ -247,100 +128,6 @@ module RuboCop
247
128
  end
248
129
  [[formatter, @options[:output_path]]]
249
130
  end
250
-
251
- return unless @options[:auto_gen_config]
252
-
253
- @options[:formatters] << [Formatter::DisabledConfigFormatter,
254
- ConfigLoader::AUTO_GENERATED_FILE]
255
- end
256
-
257
- def print_available_cops
258
- # Load the configs so the require()s are done for custom cops
259
- @config_store.for(Dir.pwd)
260
- registry = Cop::Cop.registry
261
- show_all = @options[:show_cops].empty?
262
-
263
- if show_all
264
- puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: "
265
- end
266
-
267
- registry.departments.sort!.each do |department|
268
- print_cops_of_department(registry, department, show_all)
269
- end
270
- end
271
-
272
- def print_cops_of_department(registry, department, show_all)
273
- selected_cops = if show_all
274
- cops_of_department(registry, department)
275
- else
276
- selected_cops_of_department(registry, department)
277
- end
278
-
279
- puts "# Department '#{department}' (#{selected_cops.length}):" if show_all
280
-
281
- print_cop_details(selected_cops)
282
- end
283
-
284
- def print_cop_details(cops)
285
- cops.each do |cop|
286
- puts '# Supports --auto-correct' if cop.new.support_autocorrect?
287
- puts "#{cop.cop_name}:"
288
- puts config_lines(cop)
289
- puts
290
- end
291
- end
292
-
293
- def selected_cops_of_department(cops, department)
294
- cops_of_department(cops, department).select do |cop|
295
- @options[:show_cops].include?(cop.cop_name)
296
- end
297
- end
298
-
299
- def cops_of_department(cops, department)
300
- cops.with_department(department).sort!
301
- end
302
-
303
- def config_lines(cop)
304
- cnf = @config_store.for(Dir.pwd).for_cop(cop)
305
- cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line }
306
- end
307
-
308
- def display_warning_summary(warnings)
309
- return if warnings.empty?
310
-
311
- warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow
312
-
313
- warnings.each { |warning| warn warning }
314
- end
315
-
316
- def display_error_summary(errors)
317
- return if errors.empty?
318
-
319
- warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red
320
-
321
- errors.each { |error| warn error }
322
-
323
- warn <<~WARNING
324
- Errors are usually caused by RuboCop bugs.
325
- Please, report your problems to RuboCop's issue tracker.
326
- #{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}
327
-
328
- Mention the following information in the issue report:
329
- #{RuboCop::Version.version(true)}
330
- WARNING
331
- end
332
-
333
- def maybe_print_corrected_source
334
- # If we are asked to autocorrect source code read from stdin, the only
335
- # reasonable place to write it is to stdout
336
- # Unfortunately, we also write other information to stdout
337
- # So a delimiter is needed for tools to easily identify where the
338
- # autocorrected source begins
339
- return unless @options[:stdin] && @options[:auto_correct]
340
-
341
- puts '=' * 20
342
- print @options[:stdin]
343
131
  end
344
132
  end
345
133
  end
346
- # rubocop:enable Metrics/ClassLength
@@ -113,7 +113,8 @@ module RuboCop
113
113
  def each_mentioned_cop
114
114
  each_directive do |comment, cop_names, disabled|
115
115
  comment_line_number = comment.loc.expression.line
116
- single_line = !comment_only_line?(comment_line_number)
116
+ single_line = !comment_only_line?(comment_line_number) ||
117
+ directive_on_comment_line?(comment)
117
118
 
118
119
  cop_names.each do |cop_name|
119
120
  yield qualified_cop_name(cop_name), disabled, comment_line_number,
@@ -122,6 +123,10 @@ module RuboCop
122
123
  end
123
124
  end
124
125
 
126
+ def directive_on_comment_line?(comment)
127
+ comment.text[1..-1].match(COMMENT_DIRECTIVE_REGEXP)
128
+ end
129
+
125
130
  def each_directive
126
131
  return if processed_source.comments.nil?
127
132
 
@@ -2,6 +2,9 @@
2
2
 
3
3
  require 'pathname'
4
4
 
5
+ # FIXME: Moving Rails department code to RuboCop Rails will remove
6
+ # the following rubocop:disable comment.
7
+ # rubocop:disable Metrics/ClassLength
5
8
  module RuboCop
6
9
  # This class represents the configuration of the RuboCop application
7
10
  # and all its cops. A Config is associated with a YAML configuration
@@ -13,6 +16,8 @@ module RuboCop
13
16
  include FileFinder
14
17
  extend Forwardable
15
18
 
19
+ CopConfig = Struct.new(:name, :metadata)
20
+
16
21
  DEFAULT_RAILS_VERSION = 5.0
17
22
  attr_reader :loaded_path
18
23
 
@@ -42,7 +47,7 @@ module RuboCop
42
47
  end
43
48
 
44
49
  def_delegators :@hash, :[], :[]=, :delete, :each, :key?, :keys, :each_key,
45
- :map, :merge, :to_h, :to_hash
50
+ :map, :merge, :to_h, :to_hash, :transform_values
46
51
  def_delegators :@validator, :validate, :target_ruby_version
47
52
 
48
53
  def to_s
@@ -111,11 +116,19 @@ module RuboCop
111
116
  @for_all_cops ||= self['AllCops'] || {}
112
117
  end
113
118
 
119
+ def disabled_new_cops?
120
+ for_all_cops['NewCops'] == 'disable'
121
+ end
122
+
123
+ def enabled_new_cops?
124
+ for_all_cops['NewCops'] == 'enable'
125
+ end
126
+
114
127
  def file_to_include?(file)
115
128
  relative_file_path = path_relative_to_config(file)
116
129
 
117
130
  # Optimization to quickly decide if the given file is hidden (on the top
118
- # level) and can not be matched by any pattern.
131
+ # level) and cannot be matched by any pattern.
119
132
  is_hidden = relative_file_path.start_with?('.') &&
120
133
  !relative_file_path.start_with?('..')
121
134
  return false if is_hidden && !possibly_include_hidden?
@@ -215,6 +228,18 @@ module RuboCop
215
228
  nil
216
229
  end
217
230
 
231
+ def pending_cops
232
+ keys.each_with_object([]) do |qualified_cop_name, pending_cops|
233
+ department = department_of(qualified_cop_name)
234
+ next if department && department['Enabled'] == false
235
+
236
+ cop_metadata = self[qualified_cop_name]
237
+ next unless cop_metadata['Enabled'] == 'pending'
238
+
239
+ pending_cops << CopConfig.new(qualified_cop_name, cop_metadata)
240
+ end
241
+ end
242
+
218
243
  private
219
244
 
220
245
  def target_rails_version_from_bundler_lock_file
@@ -235,17 +260,22 @@ module RuboCop
235
260
  end
236
261
 
237
262
  def enable_cop?(qualified_cop_name, cop_options)
238
- cop_department, cop_name = qualified_cop_name.split('/')
239
- department = cop_name.nil?
240
-
241
- unless department
242
- department_options = self[cop_department]
243
- if department_options && department_options['Enabled'] == false
244
- return false
245
- end
263
+ department = department_of(qualified_cop_name)
264
+ cop_enabled = cop_options.fetch('Enabled') do
265
+ !for_all_cops['DisabledByDefault']
246
266
  end
267
+ return true if cop_enabled == 'override_department'
268
+ return false if department && department['Enabled'] == false
269
+
270
+ cop_enabled
271
+ end
272
+
273
+ def department_of(qualified_cop_name)
274
+ cop_department, cop_name = qualified_cop_name.split('/')
275
+ return nil if cop_name.nil?
247
276
 
248
- cop_options.fetch('Enabled') { !for_all_cops['DisabledByDefault'] }
277
+ self[cop_department]
249
278
  end
250
279
  end
251
280
  end
281
+ # rubocop:enable Metrics/ClassLength