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
@@ -24,7 +24,7 @@ module RuboCop
24
24
  include FileFinder
25
25
 
26
26
  attr_accessor :debug, :auto_gen_config, :ignore_parent_exclusion,
27
- :options_config
27
+ :options_config, :disable_pending_cops, :enable_pending_cops
28
28
  attr_writer :default_configuration
29
29
 
30
30
  alias debug? debug
@@ -36,7 +36,7 @@ module RuboCop
36
36
  FileFinder.root_level = nil
37
37
  end
38
38
 
39
- def load_file(file)
39
+ def load_file(file) # rubocop:disable Metrics/AbcSize
40
40
  path = File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
41
41
 
42
42
  hash = load_yaml_configuration(path)
@@ -46,6 +46,7 @@ module RuboCop
46
46
 
47
47
  add_missing_namespaces(path, hash)
48
48
 
49
+ resolver.override_department_setting_for_cops({}, hash)
49
50
  resolver.resolve_inheritance_from_gems(hash)
50
51
  resolver.resolve_inheritance(path, hash, file, debug?)
51
52
 
@@ -55,7 +56,10 @@ module RuboCop
55
56
  end
56
57
 
57
58
  def add_missing_namespaces(path, hash)
58
- hash.keys.each do |key|
59
+ # Using `hash.each_key` will cause the
60
+ # `can't add a new key into hash during iteration` error
61
+ hash_keys = hash.keys
62
+ hash_keys.each do |key|
59
63
  q = Cop::Cop.qualified_cop_name(key, path)
60
64
  next if q == key
61
65
 
@@ -76,28 +80,35 @@ module RuboCop
76
80
  # user's home directory is checked. If there's no .rubocop.yml
77
81
  # there either, the path to the default file is returned.
78
82
  def configuration_file_for(target_dir)
79
- find_project_dotfile(target_dir) ||
80
- find_user_dotfile ||
81
- find_user_xdg_config ||
82
- DEFAULT_FILE
83
+ find_project_dotfile(target_dir) || find_user_dotfile ||
84
+ find_user_xdg_config || DEFAULT_FILE
83
85
  end
84
86
 
85
87
  def configuration_from_file(config_file)
86
- config = load_file(config_file)
87
- return config if config_file == DEFAULT_FILE
88
+ return ConfigLoader.default_configuration if config_file == DEFAULT_FILE
88
89
 
90
+ config = load_file(config_file)
89
91
  if ignore_parent_exclusion?
90
92
  print 'Ignoring AllCops/Exclude from parent folders' if debug?
91
93
  else
92
94
  add_excludes_from_files(config, config_file)
93
95
  end
94
- merge_with_default(config, config_file)
96
+
97
+ merge_with_default(config, config_file).tap do |merged_config|
98
+ unless possible_new_cops?(config)
99
+ warn_on_pending_cops(merged_config.pending_cops)
100
+ end
101
+ end
102
+ end
103
+
104
+ def possible_new_cops?(config)
105
+ disable_pending_cops || enable_pending_cops ||
106
+ config.disabled_new_cops? || config.enabled_new_cops?
95
107
  end
96
108
 
97
109
  def add_excludes_from_files(config, config_file)
98
- found_files =
99
- find_files_upwards(DOTFILE, config_file) +
100
- [find_user_dotfile, find_user_xdg_config].compact
110
+ found_files = find_files_upwards(DOTFILE, config_file) +
111
+ [find_user_dotfile, find_user_xdg_config].compact
101
112
 
102
113
  return if found_files.empty?
103
114
  return if PathUtil.relative_path(found_files.last) ==
@@ -114,6 +125,22 @@ module RuboCop
114
125
  end
115
126
  end
116
127
 
128
+ def warn_on_pending_cops(pending_cops)
129
+ return if pending_cops.empty?
130
+
131
+ warn Rainbow('The following cops were added to RuboCop, but are not ' \
132
+ 'configured. Please set Enabled to either `true` or ' \
133
+ '`false` in your `.rubocop.yml` file:').yellow
134
+
135
+ pending_cops.each do |cop|
136
+ version = cop.metadata['VersionAdded'] || 'N/A'
137
+
138
+ warn Rainbow(" - #{cop.name} (#{version})").yellow
139
+ end
140
+
141
+ warn Rainbow('For more information: https://docs.rubocop.org/en/latest/versioning/').yellow
142
+ end
143
+
117
144
  # Merges the given configuration with the default one. If
118
145
  # AllCops:DisabledByDefault is true, it changes the Enabled params so
119
146
  # that only cops from user configuration are enabled.
@@ -180,7 +207,9 @@ module RuboCop
180
207
  def write_config_file(file_name, file_string, rubocop_yml_contents)
181
208
  File.open(file_name, 'w') do |f|
182
209
  f.write "inherit_from:#{file_string}\n"
183
- f.write "\n#{rubocop_yml_contents}" if rubocop_yml_contents =~ /\S/
210
+ if /\S/.match?(rubocop_yml_contents)
211
+ f.write "\n#{rubocop_yml_contents}"
212
+ end
184
213
  end
185
214
  end
186
215
 
@@ -189,7 +218,10 @@ module RuboCop
189
218
  end
190
219
 
191
220
  def load_yaml_configuration(absolute_path)
192
- yaml_code = read_file(absolute_path)
221
+ file_contents = read_file(absolute_path)
222
+ yaml_code = Dir.chdir(File.dirname(absolute_path)) do
223
+ ERB.new(file_contents).result
224
+ end
193
225
  check_duplication(yaml_code, absolute_path)
194
226
  hash = yaml_safe_load(yaml_code, absolute_path) || {}
195
227
 
@@ -199,8 +231,6 @@ module RuboCop
199
231
  raise(TypeError, "Malformed configuration in #{absolute_path}")
200
232
  end
201
233
 
202
- check_cop_config_value(hash)
203
-
204
234
  hash
205
235
  end
206
236
 
@@ -215,29 +245,12 @@ module RuboCop
215
245
  "#{smart_path}:#{line1}: " \
216
246
  "`#{value}` is concealed by line #{line2}"
217
247
  else
218
- "#{smart_path}: " \
219
- "`#{value}` is concealed by duplicate"
248
+ "#{smart_path}: `#{value}` is concealed by duplicate"
220
249
  end
221
250
  warn Rainbow(message).yellow
222
251
  end
223
252
  end
224
253
 
225
- def check_cop_config_value(hash, parent = nil)
226
- hash.each do |key, value|
227
- check_cop_config_value(value, key) if value.is_a?(Hash)
228
-
229
- next unless %w[Enabled
230
- Safe
231
- SafeAutoCorrect
232
- AutoCorrect].include?(key) && value.is_a?(String)
233
-
234
- abort(
235
- "Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow}" \
236
- " is supposed to be a boolean and #{Rainbow(value).yellow} is not."
237
- )
238
- end
239
- end
240
-
241
254
  # Read the specified file, or exit with a friendly, concise message on
242
255
  # stderr. Care is taken to use the standard OS exit code for a "file not
243
256
  # found" error.
@@ -250,17 +263,14 @@ module RuboCop
250
263
 
251
264
  def yaml_safe_load(yaml_code, filename)
252
265
  if defined?(SafeYAML) && SafeYAML.respond_to?(:load)
253
- SafeYAML.load(yaml_code, filename,
254
- whitelisted_tags: %w[!ruby/regexp])
266
+ SafeYAML.load(yaml_code, filename, whitelisted_tags: %w[!ruby/regexp])
255
267
  # Ruby 2.6+
256
268
  elsif Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
257
- YAML.safe_load(
258
- yaml_code,
259
- permitted_classes: [Regexp, Symbol],
260
- permitted_symbols: [],
261
- aliases: true,
262
- filename: filename
263
- )
269
+ YAML.safe_load(yaml_code,
270
+ permitted_classes: [Regexp, Symbol],
271
+ permitted_symbols: [],
272
+ aliases: true,
273
+ filename: filename)
264
274
  else
265
275
  YAML.safe_load(yaml_code, [Regexp, Symbol], [], true, filename)
266
276
  end
@@ -17,10 +17,12 @@ module RuboCop
17
17
  end
18
18
  end
19
19
 
20
+ # rubocop:disable Metrics/MethodLength
20
21
  def resolve_inheritance(path, hash, file, debug)
21
22
  inherited_files = Array(hash['inherit_from'])
22
23
  base_configs(path, inherited_files, file)
23
24
  .reverse.each_with_index do |base_config, index|
25
+ override_department_setting_for_cops(base_config, hash)
24
26
  base_config.each do |k, v|
25
27
  next unless v.is_a?(Hash)
26
28
 
@@ -34,6 +36,7 @@ module RuboCop
34
36
  end
35
37
  end
36
38
  end
39
+ # rubocop:enable Metrics/MethodLength
37
40
 
38
41
  def resolve_inheritance_from_gems(hash)
39
42
  gems = hash.delete('inherit_gem')
@@ -100,8 +103,32 @@ module RuboCop
100
103
  end
101
104
  # rubocop:enable Metrics/AbcSize
102
105
 
106
+ # An `Enabled: true` setting in user configuration for a cop overrides an
107
+ # `Enabled: false` setting for its department.
108
+ def override_department_setting_for_cops(base_hash, derived_hash)
109
+ derived_hash.each_key do |key|
110
+ next unless key =~ %r{(.*)/.*}
111
+
112
+ department = Regexp.last_match(1)
113
+ next unless disabled?(derived_hash, department) ||
114
+ disabled?(base_hash, department)
115
+
116
+ # The `override_department` setting for the `Enabled` parameter is an
117
+ # internal setting that's not documented in the manual. It will cause a
118
+ # cop to be enabled later, when logic surrounding enabled/disabled it
119
+ # run, even though its department is disabled.
120
+ if derived_hash[key]['Enabled']
121
+ derived_hash[key]['Enabled'] = 'override_department'
122
+ end
123
+ end
124
+ end
125
+
103
126
  private
104
127
 
128
+ def disabled?(hash, department)
129
+ hash[department] && hash[department]['Enabled'] == false
130
+ end
131
+
105
132
  def duplicate_setting?(base_hash, derived_hash, key, inherited_file)
106
133
  return false if inherited_file.nil? # Not inheritance resolving merge
107
134
  return false if inherited_file.start_with?('..') # Legitimate override
@@ -181,7 +208,7 @@ module RuboCop
181
208
  end
182
209
 
183
210
  def transform(config)
184
- Hash[config.map { |cop, params| [cop, yield(params)] }]
211
+ config.transform_values { |params| yield(params) }
185
212
  end
186
213
 
187
214
  def gem_config_path(gem_name, relative_config_path)
@@ -4,22 +4,41 @@ module RuboCop
4
4
  # This class handles obsolete configuration.
5
5
  class ConfigObsoletion
6
6
  RENAMED_COPS = {
7
+ 'Layout/AlignArguments' => 'Layout/ArgumentAlignment',
8
+ 'Layout/AlignArray' => 'Layout/ArrayAlignment',
9
+ 'Layout/AlignHash' => 'Layout/HashAlignment',
10
+ 'Layout/AlignParameters' => 'Layout/ParameterAlignment',
11
+ 'Layout/IndentArray' => 'Layout/FirstArrayElementIndentation',
12
+ 'Layout/IndentAssignment' => 'Layout/AssignmentIndentation',
13
+ 'Layout/IndentFirstArgument' => 'Layout/FirstArgumentIndentation',
14
+ 'Layout/IndentFirstArrayElement' => 'Layout/FirstArrayElementIndentation',
15
+ 'Layout/IndentFirstHashElement' => 'Layout/FirstHashElementIndentation',
16
+ 'Layout/IndentFirstParameter' => 'Layout/FirstParameterIndentation',
17
+ 'Layout/IndentHash' => 'Layout/FirstHashElementIndentation',
18
+ 'Layout/IndentHeredoc' => 'Layout/HeredocIndentation',
19
+ 'Layout/LeadingBlankLines' => 'Layout/LeadingEmptyLines',
20
+ 'Layout/Tab' => 'Layout/IndentationStyle',
21
+ 'Layout/TrailingBlankLines' => 'Layout/TrailingEmptyLines',
22
+ 'Lint/DuplicatedKey' => 'Lint/DuplicateHashKey',
23
+ 'Lint/EndInMethod' => 'Style/EndBlock',
24
+ 'Lint/HandleExceptions' => 'Lint/SuppressedException',
25
+ 'Lint/MultipleCompare' => 'Lint/MultipleComparison',
26
+ 'Lint/StringConversionInInterpolation' => 'Lint/RedundantStringCoercion',
7
27
  'Lint/UnneededCopDisableDirective' => 'Lint/RedundantCopDisableDirective',
8
28
  'Lint/UnneededCopEnableDirective' => 'Lint/RedundantCopEnableDirective',
9
29
  'Lint/UnneededRequireStatement' => 'Lint/RedundantRequireStatement',
10
30
  'Lint/UnneededSplatExpansion' => 'Lint/RedundantSplatExpansion',
11
- 'Style/SingleSpaceBeforeFirstArg' => 'Layout/SpaceBeforeFirstArg',
12
- 'Style/MethodCallParentheses' => 'Style/MethodCallWithoutArgsParentheses',
31
+ 'Naming/UncommunicativeBlockParamName' => 'Naming/BlockParameterName',
32
+ 'Naming/UncommunicativeMethodParamName' => 'Naming/MethodParameterName',
13
33
  'Style/DeprecatedHashMethods' => 'Style/PreferredHashMethods',
34
+ 'Style/MethodCallParentheses' => 'Style/MethodCallWithoutArgsParentheses',
14
35
  'Style/OpMethod' => 'Naming/BinaryOperatorParameterName',
36
+ 'Style/SingleSpaceBeforeFirstArg' => 'Layout/SpaceBeforeFirstArg',
15
37
  'Style/UnneededCapitalW' => 'Style/RedundantCapitalW',
16
38
  'Style/UnneededCondition' => 'Style/RedundantCondition',
17
39
  'Style/UnneededInterpolation' => 'Style/RedundantInterpolation',
18
40
  'Style/UnneededPercentQ' => 'Style/RedundantPercentQ',
19
- 'Style/UnneededSort' => 'Style/RedundantSort',
20
- 'Layout/FirstParameterIndentation' => 'Layout/IndentFirstArgument',
21
- 'Layout/IndentArray' => 'Layout/IndentFirstArrayElement',
22
- 'Layout/IndentHash' => 'Layout/IndentFirstHashElement'
41
+ 'Style/UnneededSort' => 'Style/RedundantSort'
23
42
  }.map do |old_name, new_name|
24
43
  [old_name, "The `#{old_name}` cop has been renamed to `#{new_name}`."]
25
44
  end
@@ -31,7 +50,7 @@ module RuboCop
31
50
  Style/VariableName Style/VariableNumber
32
51
  Style/AccessorMethodName Style/AsciiIdentifiers],
33
52
  'Layout' => %w[Lint/BlockAlignment Lint/EndAlignment
34
- Lint/DefEndAlignment],
53
+ Lint/DefEndAlignment Metrics/LineLength],
35
54
  'Lint' => 'Style/FlipFlop'
36
55
  }.map do |new_department, old_names|
37
56
  Array(old_names).map do |old_name|
@@ -41,9 +60,10 @@ module RuboCop
41
60
  end
42
61
 
43
62
  REMOVED_COPS = {
44
- 'Rails/DefaultScope' => nil,
45
63
  'Layout/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
46
64
  'Layout/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
65
+ 'Lint/RescueWithoutErrorClass' => 'Style/RescueStandardError',
66
+ 'Rails/DefaultScope' => nil,
47
67
  'Style/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
48
68
  'Style/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
49
69
  'Style/TrailingComma' => 'Style/TrailingCommaInArguments, ' \
@@ -52,7 +72,7 @@ module RuboCop
52
72
  'Style/TrailingCommaInLiteral' => 'Style/TrailingCommaInArrayLiteral ' \
53
73
  'and/or ' \
54
74
  'Style/TrailingCommaInHashLiteral',
55
- 'Lint/RescueWithoutErrorClass' => 'Style/RescueStandardError'
75
+ 'Style/BracesAroundHashParameters' => nil
56
76
  }.map do |old_name, other_cops|
57
77
  if other_cops
58
78
  more = ". Please use #{other_cops} instead".gsub(%r{[A-Z]\w+/\w+},
@@ -97,13 +117,13 @@ module RuboCop
97
117
  cops: 'Style/IfUnlessModifier',
98
118
  parameters: 'MaxLineLength',
99
119
  alternative: '`Style/IfUnlessModifier: MaxLineLength` has been ' \
100
- 'removed. Use `Metrics/LineLength: Max` instead'
120
+ 'removed. Use `Layout/LineLength: Max` instead'
101
121
  },
102
122
  {
103
123
  cops: 'Style/WhileUntilModifier',
104
124
  parameters: 'MaxLineLength',
105
125
  alternative: '`Style/WhileUntilModifier: MaxLineLength` has been ' \
106
- 'removed. Use `Metrics/LineLength: Max` instead'
126
+ 'removed. Use `Layout/LineLength: Max` instead'
107
127
  },
108
128
  {
109
129
  cops: 'AllCops',
@@ -140,6 +160,42 @@ module RuboCop
140
160
  parameters: 'SafeMode',
141
161
  alternative: '`SafeMode` has been removed. ' \
142
162
  'Use `SafeAutoCorrect` instead.'
163
+ },
164
+ {
165
+ cops: 'Bundler/GemComment',
166
+ parameters: 'Whitelist',
167
+ alternative: '`Whitelist` has been renamed to `IgnoredGems`.'
168
+ },
169
+ {
170
+ cops: %w[
171
+ Lint/SafeNavigationChain Lint/SafeNavigationConsistency
172
+ Style/NestedParenthesizedCalls Style/SafeNavigation
173
+ Style/TrivialAccessors
174
+ ],
175
+ parameters: 'Whitelist',
176
+ alternative: '`Whitelist` has been renamed to `AllowedMethods`.'
177
+ },
178
+ {
179
+ cops: 'Style/IpAddresses',
180
+ parameters: 'Whitelist',
181
+ alternative: '`Whitelist` has been renamed to `AllowedAddresses`.'
182
+ },
183
+ {
184
+ cops: 'Naming/HeredocDelimiterNaming',
185
+ parameters: 'Blacklist',
186
+ alternative: '`Blacklist` has been renamed to `ForbiddenDelimiters`.'
187
+ },
188
+ {
189
+ cops: 'Naming/PredicateName',
190
+ parameters: 'NamePrefixBlacklist',
191
+ alternative: '`NamePrefixBlacklist` has been renamed to ' \
192
+ '`ForbiddenPrefixes`.'
193
+ },
194
+ {
195
+ cops: 'Naming/PredicateName',
196
+ parameters: 'NameWhitelist',
197
+ alternative: '`NameWhitelist` has been renamed to ' \
198
+ '`AllowedMethods`.'
143
199
  }
144
200
  ].freeze
145
201
 
@@ -13,26 +13,22 @@ module RuboCop
13
13
  INTERNAL_PARAMS = %w[Description StyleGuide
14
14
  VersionAdded VersionChanged VersionRemoved
15
15
  Reference Safe SafeAutoCorrect].freeze
16
+ NEW_COPS_VALUES = %w[pending disable enable].freeze
16
17
 
17
- # 2.3 is the oldest officially supported Ruby version.
18
- DEFAULT_RUBY_VERSION = 2.3
19
- KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
20
- OBSOLETE_RUBIES = {
21
- 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
22
- }.freeze
23
- RUBY_VERSION_FILENAME = '.ruby-version'
24
-
25
- def_delegators :@config,
26
- :smart_loaded_path, :for_all_cops, :find_file_upwards,
27
- :base_dir_for_path_parameters, :bundler_lock_file_path
18
+ def_delegators :@config, :smart_loaded_path, :for_all_cops
28
19
 
29
20
  def initialize(config)
30
21
  @config = config
31
22
  @config_obsoletion = ConfigObsoletion.new(config)
23
+ @target_ruby = TargetRuby.new(config)
32
24
  end
33
25
 
26
+ # rubocop:disable Metrics/AbcSize
34
27
  def validate
35
- # Don't validate RuboCop's own files. Avoids infinite recursion.
28
+ check_cop_config_value(@config)
29
+ reject_conflicting_safe_settings
30
+
31
+ # Don't validate RuboCop's own files further. Avoids infinite recursion.
36
32
  return if @config.internal?
37
33
 
38
34
  valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
@@ -41,32 +37,18 @@ module RuboCop
41
37
 
42
38
  @config_obsoletion.reject_obsolete_cops_and_parameters
43
39
 
44
- warn_about_unrecognized_cops(invalid_cop_names)
40
+ alert_about_unrecognized_cops(invalid_cop_names)
45
41
  check_target_ruby
42
+ validate_new_cops_parameter
46
43
  validate_parameter_names(valid_cop_names)
47
44
  validate_enforced_styles(valid_cop_names)
48
45
  validate_syntax_cop
49
46
  reject_mutually_exclusive_defaults
50
47
  end
48
+ # rubocop:enable Metrics/AbcSize
51
49
 
52
50
  def target_ruby_version
53
- @target_ruby_version ||= begin
54
- if for_all_cops['TargetRubyVersion']
55
- @target_ruby_version_source = :rubocop_yml
56
-
57
- for_all_cops['TargetRubyVersion'].to_f
58
- elsif target_ruby_version_from_version_file
59
- @target_ruby_version_source = :ruby_version_file
60
-
61
- target_ruby_version_from_version_file
62
- elsif target_ruby_version_from_bundler_lock_file
63
- @target_ruby_version_source = :bundler_lock_file
64
-
65
- target_ruby_version_from_bundler_lock_file
66
- else
67
- DEFAULT_RUBY_VERSION
68
- end
69
- end
51
+ target_ruby.version
70
52
  end
71
53
 
72
54
  def validate_section_presence(name)
@@ -78,25 +60,30 @@ module RuboCop
78
60
 
79
61
  private
80
62
 
63
+ attr_reader :target_ruby
64
+
81
65
  def check_target_ruby
82
- return if KNOWN_RUBIES.include?(target_ruby_version)
66
+ return if target_ruby.supported?
67
+
68
+ source = target_ruby.source
69
+ last_version = target_ruby.rubocop_version_with_support
83
70
 
84
- msg = if OBSOLETE_RUBIES.include?(target_ruby_version)
71
+ msg = if last_version
85
72
  "RuboCop found unsupported Ruby version #{target_ruby_version} " \
86
- "in #{target_ruby_source}. #{target_ruby_version}-compatible " \
87
- 'analysis was dropped after version ' \
88
- "#{OBSOLETE_RUBIES[target_ruby_version]}."
73
+ "in #{source}. #{target_ruby_version}-compatible " \
74
+ "analysis was dropped after version #{last_version}."
89
75
  else
90
76
  'RuboCop found unknown Ruby version ' \
91
- "#{target_ruby_version.inspect} in #{target_ruby_source}."
77
+ "#{target_ruby_version.inspect} in #{source}."
92
78
  end
93
79
 
94
- msg += "\nSupported versions: #{KNOWN_RUBIES.join(', ')}"
80
+ msg += "\nSupported versions: #{TargetRuby.supported_versions.join(', ')}"
95
81
 
96
82
  raise ValidationError, msg
97
83
  end
98
84
 
99
- def warn_about_unrecognized_cops(invalid_cop_names)
85
+ def alert_about_unrecognized_cops(invalid_cop_names)
86
+ unknown_cops = []
100
87
  invalid_cop_names.each do |name|
101
88
  # There could be a custom cop with this name. If so, don't warn
102
89
  next if Cop::Cop.registry.contains_cop_matching?([name])
@@ -106,9 +93,10 @@ module RuboCop
106
93
  # to do so than to pass the value around to various methods.
107
94
  next if name == 'inherit_mode'
108
95
 
109
- warn Rainbow("Warning: unrecognized cop #{name} found in " \
110
- "#{smart_loaded_path}").yellow
96
+ unknown_cops << "unrecognized cop #{name} found in " \
97
+ "#{smart_loaded_path}"
111
98
  end
99
+ raise ValidationError, unknown_cops.join(', ') if unknown_cops.any?
112
100
  end
113
101
 
114
102
  def validate_syntax_cop
@@ -123,13 +111,23 @@ module RuboCop
123
111
  'It\'s not possible to disable this cop.'
124
112
  end
125
113
 
114
+ def validate_new_cops_parameter
115
+ new_cop_parameter = @config.for_all_cops['NewCops']
116
+ return if new_cop_parameter.nil? ||
117
+ NEW_COPS_VALUES.include?(new_cop_parameter)
118
+
119
+ message = "invalid #{new_cop_parameter} for `NewCops` found in" \
120
+ "#{smart_loaded_path}\n" \
121
+ "Valid choices are: #{NEW_COPS_VALUES.join(', ')}"
122
+
123
+ raise ValidationError, message
124
+ end
125
+
126
126
  def validate_parameter_names(valid_cop_names)
127
127
  valid_cop_names.each do |name|
128
128
  validate_section_presence(name)
129
129
  each_invalid_parameter(name) do |param, supported_params|
130
- # FIXME: Remove .to_s, which works around a JRuby bug:
131
- # https://github.com/jruby/jruby/issues/5935
132
- warn Rainbow(<<~MESSAGE).yellow.to_s
130
+ warn Rainbow(<<~MESSAGE).yellow
133
131
  Warning: #{name} does not support #{param} parameter.
134
132
 
135
133
  Supported parameters are:
@@ -178,71 +176,48 @@ module RuboCop
178
176
  formats.all? { |format| valid.include?(format) }
179
177
  end
180
178
 
181
- def target_ruby_source
182
- case @target_ruby_version_source
183
- when :ruby_version_file
184
- "`#{RUBY_VERSION_FILENAME}`"
185
- when :bundler_lock_file
186
- "`#{bundler_lock_file_path}`"
187
- when :rubocop_yml
188
- "`TargetRubyVersion` parameter (in #{smart_loaded_path})"
189
- end
190
- end
179
+ def reject_mutually_exclusive_defaults
180
+ disabled_by_default = for_all_cops['DisabledByDefault']
181
+ enabled_by_default = for_all_cops['EnabledByDefault']
182
+ return unless disabled_by_default && enabled_by_default
191
183
 
192
- def ruby_version_file
193
- @ruby_version_file ||=
194
- find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
184
+ msg = 'Cops cannot be both enabled by default and disabled by default'
185
+ raise ValidationError, msg
195
186
  end
196
187
 
197
- def target_ruby_version_from_version_file
198
- file = ruby_version_file
199
- return unless file && File.file?(file)
188
+ def reject_conflicting_safe_settings
189
+ @config.each do |name, cop_config|
190
+ next unless cop_config.is_a?(Hash)
191
+ next unless cop_config['Safe'] == false &&
192
+ cop_config['SafeAutoCorrect'] == true
200
193
 
201
- @target_ruby_version_from_version_file ||=
202
- File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
203
- md[:version].to_f
204
- end
194
+ msg = 'Unsafe cops cannot have a safe auto-correction ' \
195
+ "(section #{name} in #{smart_loaded_path})"
196
+ raise ValidationError, msg
197
+ end
205
198
  end
206
199
 
207
- def target_ruby_version_from_bundler_lock_file
208
- @target_ruby_version_from_bundler_lock_file ||=
209
- read_ruby_version_from_bundler_lock_file
210
- end
211
-
212
- def read_ruby_version_from_bundler_lock_file
213
- lock_file_path = bundler_lock_file_path
214
- return nil unless lock_file_path
215
-
216
- in_ruby_section = false
217
- File.foreach(lock_file_path) do |line|
218
- # If ruby is in Gemfile.lock or gems.lock, there should be two lines
219
- # towards the bottom of the file that look like:
220
- # RUBY VERSION
221
- # ruby W.X.YpZ
222
- # We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
223
- # extra logic to make sure we only start looking once we've seen the
224
- # "RUBY VERSION" line.
225
- in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
226
- next unless in_ruby_section
227
-
228
- # We currently only allow this feature to work with MRI ruby. If jruby
229
- # (or something else) is used by the project, it's lock file will have a
230
- # line that looks like:
231
- # RUBY VERSION
232
- # ruby W.X.YpZ (jruby x.x.x.x)
233
- # The regex won't match in this situation.
234
- result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
235
- return result.captures.first.to_f if result
200
+ def check_cop_config_value(hash, parent = nil)
201
+ hash.each do |key, value|
202
+ check_cop_config_value(value, key) if value.is_a?(Hash)
203
+
204
+ next unless %w[Enabled
205
+ Safe
206
+ SafeAutoCorrect
207
+ AutoCorrect].include?(key) && value.is_a?(String)
208
+
209
+ next if key == 'Enabled' &&
210
+ %w[pending override_department].include?(value)
211
+
212
+ raise ValidationError, msg_not_boolean(parent, key, value)
236
213
  end
237
214
  end
238
215
 
239
- def reject_mutually_exclusive_defaults
240
- disabled_by_default = for_all_cops['DisabledByDefault']
241
- enabled_by_default = for_all_cops['EnabledByDefault']
242
- return unless disabled_by_default && enabled_by_default
243
-
244
- msg = 'Cops cannot be both enabled by default and disabled by default'
245
- raise ValidationError, msg
216
+ # FIXME: Handling colors in exception messages like this is ugly.
217
+ def msg_not_boolean(parent, key, value)
218
+ "#{Rainbow('').reset}" \
219
+ "Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow}" \
220
+ " is supposed to be a boolean and #{Rainbow(value).yellow} is not."
246
221
  end
247
222
  end
248
223
  end
@@ -24,15 +24,18 @@ module RuboCop
24
24
  @options[:disable_uncorrectable] == true
25
25
  end
26
26
 
27
+ def safe_autocorrect?
28
+ cop_config.fetch('Safe', true) &&
29
+ cop_config.fetch('SafeAutoCorrect', true)
30
+ end
31
+
27
32
  def autocorrect_enabled?
28
33
  # allow turning off autocorrect on a cop by cop basis
29
34
  return true unless cop_config
30
35
 
31
36
  return false if cop_config['AutoCorrect'] == false
32
37
 
33
- if @options.fetch(:safe_auto_correct, false)
34
- return cop_config.fetch('SafeAutoCorrect', true)
35
- end
38
+ return safe_autocorrect? if @options.fetch(:safe_auto_correct, false)
36
39
 
37
40
  true
38
41
  end
@@ -76,7 +79,7 @@ module RuboCop
76
79
  end
77
80
 
78
81
  def max_line_length
79
- config.for_cop('Metrics/LineLength')['Max'] || 80
82
+ config.for_cop('Layout/LineLength')['Max'] || 80
80
83
  end
81
84
 
82
85
  def disable_offense_at_end_of_line(range, eol_comment)