rubocop 0.49.1 → 0.52.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 (506) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -9
  3. data/bin/rubocop +1 -1
  4. data/config/default.yml +264 -118
  5. data/config/disabled.yml +13 -9
  6. data/config/enabled.yml +1156 -918
  7. data/lib/rubocop.rb +555 -489
  8. data/lib/rubocop/ast/builder.rb +6 -1
  9. data/lib/rubocop/ast/node.rb +68 -52
  10. data/lib/rubocop/ast/node/args_node.rb +15 -10
  11. data/lib/rubocop/ast/node/array_node.rb +10 -1
  12. data/lib/rubocop/ast/node/block_node.rb +9 -0
  13. data/lib/rubocop/ast/node/def_node.rb +71 -0
  14. data/lib/rubocop/ast/node/for_node.rb +8 -0
  15. data/lib/rubocop/ast/node/if_node.rb +10 -2
  16. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +16 -0
  17. data/lib/rubocop/ast/node/mixin/collection_node.rb +15 -0
  18. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +174 -0
  19. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +89 -0
  20. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +18 -31
  21. data/lib/rubocop/ast/node/regexp_node.rb +35 -0
  22. data/lib/rubocop/ast/node/send_node.rb +21 -150
  23. data/lib/rubocop/ast/node/str_node.rb +14 -0
  24. data/lib/rubocop/ast/node/super_node.rb +3 -24
  25. data/lib/rubocop/ast/node/symbol_node.rb +20 -0
  26. data/lib/rubocop/ast/node/yield_node.rb +21 -0
  27. data/lib/rubocop/ast/traversal.rb +7 -7
  28. data/lib/rubocop/cached_data.rb +1 -6
  29. data/lib/rubocop/cli.rb +59 -13
  30. data/lib/rubocop/comment_config.rb +2 -5
  31. data/lib/rubocop/config.rb +136 -29
  32. data/lib/rubocop/config_loader.rb +61 -104
  33. data/lib/rubocop/config_loader_resolver.rb +102 -4
  34. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  35. data/lib/rubocop/cop/bundler/duplicated_gem.rb +13 -11
  36. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +67 -0
  37. data/lib/rubocop/cop/bundler/ordered_gems.rb +7 -58
  38. data/lib/rubocop/cop/commissioner.rb +6 -3
  39. data/lib/rubocop/cop/cop.rb +11 -6
  40. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +102 -0
  41. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +97 -0
  42. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +87 -0
  43. data/lib/rubocop/cop/generator.rb +122 -25
  44. data/lib/rubocop/cop/internal_affairs.rb +6 -2
  45. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +46 -0
  46. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +16 -5
  47. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +54 -0
  48. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +59 -0
  49. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +71 -0
  50. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +3 -3
  51. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -10
  52. data/lib/rubocop/cop/layout/align_array.rb +2 -2
  53. data/lib/rubocop/cop/layout/align_hash.rb +18 -18
  54. data/lib/rubocop/cop/layout/align_parameters.rb +11 -23
  55. data/lib/rubocop/cop/layout/block_end_newline.rb +20 -6
  56. data/lib/rubocop/cop/layout/case_indentation.rb +15 -18
  57. data/lib/rubocop/cop/layout/class_structure.rb +306 -0
  58. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +7 -6
  59. data/lib/rubocop/cop/layout/comment_indentation.rb +42 -3
  60. data/lib/rubocop/cop/layout/dot_position.rb +31 -13
  61. data/lib/rubocop/cop/layout/else_alignment.rb +37 -17
  62. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +1 -1
  63. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -18
  64. data/lib/rubocop/cop/layout/empty_lines.rb +16 -2
  65. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +23 -6
  66. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +89 -0
  67. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -2
  68. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +4 -8
  69. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +30 -5
  70. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +10 -6
  71. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +5 -5
  72. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +22 -7
  73. data/lib/rubocop/cop/layout/end_of_line.rb +2 -2
  74. data/lib/rubocop/cop/layout/extra_spacing.rb +23 -26
  75. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +3 -3
  76. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +9 -3
  77. data/lib/rubocop/cop/layout/indent_array.rb +68 -21
  78. data/lib/rubocop/cop/layout/indent_hash.rb +71 -26
  79. data/lib/rubocop/cop/layout/indent_heredoc.rb +70 -35
  80. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -2
  81. data/lib/rubocop/cop/layout/indentation_width.rb +40 -27
  82. data/lib/rubocop/cop/layout/initial_indentation.rb +10 -7
  83. data/lib/rubocop/cop/layout/leading_comment_space.rb +32 -17
  84. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +47 -14
  85. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +12 -11
  86. data/lib/rubocop/cop/layout/multiline_block_layout.rb +19 -16
  87. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +46 -13
  88. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +29 -27
  89. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +7 -3
  90. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -0
  91. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +12 -4
  92. data/lib/rubocop/cop/layout/space_after_colon.rb +13 -6
  93. data/lib/rubocop/cop/layout/space_after_comma.rb +11 -1
  94. data/lib/rubocop/cop/layout/space_after_method_name.rb +8 -6
  95. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  96. data/lib/rubocop/cop/layout/space_after_semicolon.rb +8 -1
  97. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +32 -25
  98. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +28 -17
  99. data/lib/rubocop/cop/layout/space_around_keyword.rb +22 -16
  100. data/lib/rubocop/cop/layout/space_around_operators.rb +27 -14
  101. data/lib/rubocop/cop/layout/space_before_block_braces.rb +61 -12
  102. data/lib/rubocop/cop/layout/space_before_comma.rb +12 -1
  103. data/lib/rubocop/cop/layout/space_before_comment.rb +10 -5
  104. data/lib/rubocop/cop/layout/space_before_first_arg.rb +5 -4
  105. data/lib/rubocop/cop/layout/space_before_semicolon.rb +8 -1
  106. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +12 -14
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +235 -0
  108. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +4 -4
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +89 -18
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +62 -36
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +40 -3
  112. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +15 -15
  114. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +81 -0
  115. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +32 -17
  116. data/lib/rubocop/cop/layout/tab.rb +7 -4
  117. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +11 -9
  118. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  119. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +12 -19
  120. data/lib/rubocop/cop/lint/assignment_in_condition.rb +16 -2
  121. data/lib/rubocop/cop/lint/block_alignment.rb +42 -30
  122. data/lib/rubocop/cop/lint/boolean_symbol.rb +38 -0
  123. data/lib/rubocop/cop/lint/circular_argument_reference.rb +3 -14
  124. data/lib/rubocop/cop/lint/condition_position.rb +5 -1
  125. data/lib/rubocop/cop/lint/debugger.rb +18 -11
  126. data/lib/rubocop/cop/lint/def_end_alignment.rb +9 -14
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  128. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +3 -3
  129. data/lib/rubocop/cop/lint/duplicate_methods.rb +75 -5
  130. data/lib/rubocop/cop/lint/duplicated_key.rb +1 -1
  131. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  132. data/lib/rubocop/cop/lint/else_layout.rb +3 -3
  133. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  134. data/lib/rubocop/cop/lint/empty_expression.rb +1 -1
  135. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  136. data/lib/rubocop/cop/lint/empty_when.rb +1 -1
  137. data/lib/rubocop/cop/lint/end_alignment.rb +13 -14
  138. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  139. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  140. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -5
  141. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +36 -41
  142. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  143. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  144. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +25 -20
  145. data/lib/rubocop/cop/lint/inherit_exception.rb +16 -19
  146. data/lib/rubocop/cop/lint/interpolation_check.rb +37 -0
  147. data/lib/rubocop/cop/lint/{literal_in_condition.rb → literal_as_condition.rb} +21 -7
  148. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  149. data/lib/rubocop/cop/lint/loop.rb +1 -1
  150. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +81 -0
  151. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  152. data/lib/rubocop/cop/lint/nested_method_definition.rb +6 -8
  153. data/lib/rubocop/cop/lint/nested_percent_literal.rb +58 -0
  154. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  155. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  156. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +4 -3
  157. data/lib/rubocop/cop/lint/percent_string_array.rb +13 -22
  158. data/lib/rubocop/cop/lint/percent_symbol_array.rb +12 -12
  159. data/lib/rubocop/cop/lint/rand_one.rb +8 -2
  160. data/lib/rubocop/cop/lint/redundant_with_index.rb +80 -0
  161. data/lib/rubocop/cop/lint/redundant_with_object.rb +81 -0
  162. data/lib/rubocop/cop/lint/regexp_as_condition.rb +29 -0
  163. data/lib/rubocop/cop/lint/require_parentheses.rb +5 -3
  164. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  165. data/lib/rubocop/cop/lint/rescue_type.rb +18 -9
  166. data/lib/rubocop/cop/lint/return_in_void_context.rb +74 -0
  167. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
  168. data/lib/rubocop/cop/lint/script_permission.rb +8 -1
  169. data/lib/rubocop/cop/lint/shadowed_argument.rb +146 -0
  170. data/lib/rubocop/cop/lint/shadowed_exception.rb +37 -10
  171. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  172. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -7
  173. data/lib/rubocop/cop/lint/syntax.rb +23 -20
  174. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -1
  175. data/lib/rubocop/cop/lint/unified_integer.rb +5 -4
  176. data/lib/rubocop/cop/lint/unneeded_disable.rb +41 -16
  177. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +51 -0
  178. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +45 -19
  179. data/lib/rubocop/cop/lint/unreachable_code.rb +53 -8
  180. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  181. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +74 -0
  182. data/lib/rubocop/cop/lint/uri_regexp.rb +73 -0
  183. data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -16
  184. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  185. data/lib/rubocop/cop/lint/useless_comparison.rb +1 -1
  186. data/lib/rubocop/cop/lint/useless_setter_call.rb +15 -12
  187. data/lib/rubocop/cop/lint/void.rb +38 -27
  188. data/lib/rubocop/cop/message_annotator.rb +4 -2
  189. data/lib/rubocop/cop/metrics/abc_size.rb +2 -2
  190. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  191. data/lib/rubocop/cop/metrics/class_length.rb +3 -1
  192. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -1
  193. data/lib/rubocop/cop/metrics/line_length.rb +8 -5
  194. data/lib/rubocop/cop/metrics/method_length.rb +8 -3
  195. data/lib/rubocop/cop/metrics/module_length.rb +3 -1
  196. data/lib/rubocop/cop/metrics/parameter_lists.rb +14 -5
  197. data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -1
  198. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +3 -2
  199. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
  200. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  201. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
  202. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  203. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  204. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +14 -7
  205. data/lib/rubocop/cop/mixin/empty_parameter.rb +23 -0
  206. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +8 -4
  207. data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -3
  208. data/lib/rubocop/cop/mixin/first_element_line_break.rb +12 -3
  209. data/lib/rubocop/cop/mixin/heredoc.rb +28 -0
  210. data/lib/rubocop/cop/mixin/method_complexity.rb +33 -7
  211. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +74 -33
  212. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +34 -8
  213. data/lib/rubocop/cop/mixin/negative_conditional.rb +4 -1
  214. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +67 -0
  215. data/lib/rubocop/cop/mixin/parentheses.rb +12 -0
  216. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +4 -1
  217. data/lib/rubocop/cop/mixin/percent_array.rb +52 -0
  218. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +9 -8
  219. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -10
  220. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -17
  221. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  222. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  223. data/lib/rubocop/cop/mixin/surrounding_space.rb +95 -8
  224. data/lib/rubocop/cop/mixin/too_many_lines.rb +2 -2
  225. data/lib/rubocop/cop/mixin/trailing_comma.rb +25 -17
  226. data/lib/rubocop/cop/mixin/unused_argument.rb +6 -2
  227. data/lib/rubocop/cop/naming/accessor_method_name.rb +55 -0
  228. data/lib/rubocop/cop/{style → naming}/ascii_identifiers.rb +35 -2
  229. data/lib/rubocop/cop/{style/op_method.rb → naming/binary_operator_parameter_name.rb} +7 -6
  230. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +33 -0
  231. data/lib/rubocop/cop/naming/constant_name.rb +58 -0
  232. data/lib/rubocop/cop/{style → naming}/file_name.rb +28 -13
  233. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +62 -0
  234. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +59 -0
  235. data/lib/rubocop/cop/naming/method_name.rb +40 -0
  236. data/lib/rubocop/cop/naming/predicate_name.rb +101 -0
  237. data/lib/rubocop/cop/naming/variable_name.rb +50 -0
  238. data/lib/rubocop/cop/{style → naming}/variable_number.rb +11 -28
  239. data/lib/rubocop/cop/offense.rb +6 -1
  240. data/lib/rubocop/cop/performance/caller.rb +39 -11
  241. data/lib/rubocop/cop/performance/case_when_splat.rb +3 -7
  242. data/lib/rubocop/cop/performance/casecmp.rb +9 -8
  243. data/lib/rubocop/cop/performance/compare_with_block.rb +23 -13
  244. data/lib/rubocop/cop/performance/count.rb +7 -4
  245. data/lib/rubocop/cop/performance/detect.rb +9 -6
  246. data/lib/rubocop/cop/performance/double_start_end_with.rb +12 -20
  247. data/lib/rubocop/cop/performance/end_with.rb +6 -6
  248. data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
  249. data/lib/rubocop/cop/performance/flat_map.rb +5 -2
  250. data/lib/rubocop/cop/performance/hash_each_methods.rb +85 -40
  251. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +9 -6
  252. data/lib/rubocop/cop/performance/range_include.rb +3 -3
  253. data/lib/rubocop/cop/performance/redundant_block_call.rb +28 -28
  254. data/lib/rubocop/cop/performance/redundant_match.rb +13 -12
  255. data/lib/rubocop/cop/performance/redundant_merge.rb +44 -26
  256. data/lib/rubocop/cop/performance/redundant_sort_by.rb +9 -6
  257. data/lib/rubocop/cop/performance/regexp_match.rb +19 -10
  258. data/lib/rubocop/cop/performance/reverse_each.rb +1 -1
  259. data/lib/rubocop/cop/performance/sample.rb +1 -1
  260. data/lib/rubocop/cop/performance/size.rb +3 -3
  261. data/lib/rubocop/cop/performance/start_with.rb +6 -6
  262. data/lib/rubocop/cop/performance/string_replacement.rb +6 -6
  263. data/lib/rubocop/cop/performance/times_map.rb +32 -22
  264. data/lib/rubocop/cop/performance/unfreeze_string.rb +50 -0
  265. data/lib/rubocop/cop/performance/uri_default_parser.rb +47 -0
  266. data/lib/rubocop/cop/rails/action_filter.rb +23 -1
  267. data/lib/rubocop/cop/rails/active_support_aliases.rb +4 -5
  268. data/lib/rubocop/cop/rails/application_job.rb +5 -3
  269. data/lib/rubocop/cop/rails/application_record.rb +5 -3
  270. data/lib/rubocop/cop/rails/blank.rb +20 -17
  271. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +82 -0
  272. data/lib/rubocop/cop/rails/date.rb +7 -6
  273. data/lib/rubocop/cop/rails/delegate.rb +53 -29
  274. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +4 -4
  275. data/lib/rubocop/cop/rails/dynamic_find_by.rb +2 -2
  276. data/lib/rubocop/cop/rails/enum_uniqueness.rb +4 -4
  277. data/lib/rubocop/cop/rails/environment_comparison.rb +66 -0
  278. data/lib/rubocop/cop/rails/exit.rb +8 -1
  279. data/lib/rubocop/cop/rails/file_path.rb +8 -11
  280. data/lib/rubocop/cop/rails/find_by.rb +2 -1
  281. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  282. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +8 -1
  283. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +76 -0
  284. data/lib/rubocop/cop/rails/http_positional_arguments.rb +40 -44
  285. data/lib/rubocop/cop/rails/inverse_of.rb +96 -0
  286. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +112 -0
  287. data/lib/rubocop/cop/rails/not_null_column.rb +6 -6
  288. data/lib/rubocop/cop/rails/output.rb +11 -2
  289. data/lib/rubocop/cop/rails/output_safety.rb +16 -21
  290. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -10
  291. data/lib/rubocop/cop/rails/presence.rb +105 -0
  292. data/lib/rubocop/cop/rails/present.rb +14 -17
  293. data/lib/rubocop/cop/rails/read_write_attribute.rb +13 -13
  294. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +91 -0
  295. data/lib/rubocop/cop/rails/relative_date_constant.rb +11 -11
  296. data/lib/rubocop/cop/rails/request_referer.rb +3 -3
  297. data/lib/rubocop/cop/rails/reversible_migration.rb +36 -35
  298. data/lib/rubocop/cop/rails/safe_navigation.rb +7 -8
  299. data/lib/rubocop/cop/rails/save_bang.rb +19 -17
  300. data/lib/rubocop/cop/rails/scope_args.rb +2 -2
  301. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  302. data/lib/rubocop/cop/rails/time_zone.rb +3 -2
  303. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -2
  304. data/lib/rubocop/cop/rails/unknown_env.rb +63 -0
  305. data/lib/rubocop/cop/rails/validation.rb +8 -8
  306. data/lib/rubocop/cop/registry.rb +2 -1
  307. data/lib/rubocop/cop/security/eval.rb +4 -4
  308. data/lib/rubocop/cop/security/json_load.rb +7 -5
  309. data/lib/rubocop/cop/security/marshal_load.rb +8 -6
  310. data/lib/rubocop/cop/security/yaml_load.rb +4 -4
  311. data/lib/rubocop/cop/style/alias.rb +49 -27
  312. data/lib/rubocop/cop/style/and_or.rb +65 -45
  313. data/lib/rubocop/cop/style/array_join.rb +10 -1
  314. data/lib/rubocop/cop/style/ascii_comments.rb +24 -4
  315. data/lib/rubocop/cop/style/attr.rb +15 -5
  316. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +7 -5
  317. data/lib/rubocop/cop/style/bare_percent_literals.rb +31 -10
  318. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  319. data/lib/rubocop/cop/style/block_comments.rb +17 -3
  320. data/lib/rubocop/cop/style/block_delimiters.rb +82 -16
  321. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +68 -32
  322. data/lib/rubocop/cop/style/case_equality.rb +13 -1
  323. data/lib/rubocop/cop/style/character_literal.rb +10 -0
  324. data/lib/rubocop/cop/style/class_and_module_children.rb +8 -4
  325. data/lib/rubocop/cop/style/class_check.rb +29 -10
  326. data/lib/rubocop/cop/style/class_methods.rb +10 -9
  327. data/lib/rubocop/cop/style/class_vars.rb +5 -4
  328. data/lib/rubocop/cop/style/collection_methods.rb +5 -3
  329. data/lib/rubocop/cop/style/colon_method_call.rb +18 -2
  330. data/lib/rubocop/cop/style/colon_method_definition.rb +36 -0
  331. data/lib/rubocop/cop/style/command_literal.rb +90 -30
  332. data/lib/rubocop/cop/style/comment_annotation.rb +39 -11
  333. data/lib/rubocop/cop/style/commented_keyword.rb +84 -0
  334. data/lib/rubocop/cop/style/conditional_assignment.rb +41 -41
  335. data/lib/rubocop/cop/style/copyright.rb +27 -28
  336. data/lib/rubocop/cop/style/date_time.rb +44 -0
  337. data/lib/rubocop/cop/style/def_with_parentheses.rb +31 -5
  338. data/lib/rubocop/cop/style/dir.rb +48 -0
  339. data/lib/rubocop/cop/style/documentation.rb +17 -2
  340. data/lib/rubocop/cop/style/documentation_method.rb +2 -6
  341. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  342. data/lib/rubocop/cop/style/each_for_simple_loop.rb +8 -8
  343. data/lib/rubocop/cop/style/each_with_object.rb +6 -5
  344. data/lib/rubocop/cop/style/empty_block_parameter.rb +47 -0
  345. data/lib/rubocop/cop/style/empty_case_condition.rb +3 -3
  346. data/lib/rubocop/cop/style/empty_else.rb +55 -24
  347. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +43 -0
  348. data/lib/rubocop/cop/style/empty_literal.rb +25 -14
  349. data/lib/rubocop/cop/style/empty_method.rb +29 -25
  350. data/lib/rubocop/cop/style/encoding.rb +8 -51
  351. data/lib/rubocop/cop/style/end_block.rb +1 -1
  352. data/lib/rubocop/cop/style/eval_with_location.rb +146 -0
  353. data/lib/rubocop/cop/style/even_odd.rb +4 -2
  354. data/lib/rubocop/cop/style/extend_self.rb +92 -0
  355. data/lib/rubocop/cop/style/flip_flop.rb +13 -2
  356. data/lib/rubocop/cop/style/for.rb +6 -2
  357. data/lib/rubocop/cop/style/format_string.rb +33 -5
  358. data/lib/rubocop/cop/style/format_string_token.rb +17 -15
  359. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -6
  360. data/lib/rubocop/cop/style/global_vars.rb +12 -2
  361. data/lib/rubocop/cop/style/guard_clause.rb +6 -4
  362. data/lib/rubocop/cop/style/hash_syntax.rb +56 -56
  363. data/lib/rubocop/cop/style/identical_conditional_branches.rb +12 -8
  364. data/lib/rubocop/cop/style/if_inside_else.rb +11 -11
  365. data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -7
  366. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -2
  367. data/lib/rubocop/cop/style/if_with_semicolon.rb +10 -1
  368. data/lib/rubocop/cop/style/implicit_runtime_error.rb +7 -6
  369. data/lib/rubocop/cop/style/infinite_loop.rb +4 -4
  370. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  371. data/lib/rubocop/cop/style/inverse_methods.rb +24 -14
  372. data/lib/rubocop/cop/style/lambda.rb +45 -43
  373. data/lib/rubocop/cop/style/lambda_call.rb +37 -10
  374. data/lib/rubocop/cop/style/line_end_concatenation.rb +5 -5
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -19
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -4
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +20 -25
  379. data/lib/rubocop/cop/style/method_missing.rb +13 -26
  380. data/lib/rubocop/cop/style/min_max.rb +68 -0
  381. data/lib/rubocop/cop/style/missing_else.rb +20 -6
  382. data/lib/rubocop/cop/style/mixin_grouping.rb +31 -21
  383. data/lib/rubocop/cop/style/mixin_usage.rb +71 -0
  384. data/lib/rubocop/cop/style/module_function.rb +27 -11
  385. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  386. data/lib/rubocop/cop/style/multiline_if_modifier.rb +8 -4
  387. data/lib/rubocop/cop/style/multiline_if_then.rb +15 -13
  388. data/lib/rubocop/cop/style/multiline_memoization.rb +33 -17
  389. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  390. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  391. data/lib/rubocop/cop/style/mutable_constant.rb +11 -15
  392. data/lib/rubocop/cop/style/negated_if.rb +27 -31
  393. data/lib/rubocop/cop/style/negated_while.rb +1 -5
  394. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  395. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +26 -23
  396. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  397. data/lib/rubocop/cop/style/next.rb +41 -12
  398. data/lib/rubocop/cop/style/nil_comparison.rb +8 -8
  399. data/lib/rubocop/cop/style/non_nil_check.rb +41 -38
  400. data/lib/rubocop/cop/style/not.rb +15 -5
  401. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +8 -4
  402. data/lib/rubocop/cop/style/numeric_literals.rb +9 -9
  403. data/lib/rubocop/cop/style/numeric_predicate.rb +21 -21
  404. data/lib/rubocop/cop/style/one_line_conditional.rb +9 -4
  405. data/lib/rubocop/cop/style/option_hash.rb +11 -25
  406. data/lib/rubocop/cop/style/optional_arguments.rb +1 -2
  407. data/lib/rubocop/cop/style/or_assignment.rb +88 -0
  408. data/lib/rubocop/cop/style/parallel_assignment.rb +16 -16
  409. data/lib/rubocop/cop/style/parentheses_around_condition.rb +30 -13
  410. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +25 -4
  411. data/lib/rubocop/cop/style/percent_q_literals.rb +29 -8
  412. data/lib/rubocop/cop/style/perl_backrefs.rb +8 -1
  413. data/lib/rubocop/cop/style/preferred_hash_methods.rb +7 -11
  414. data/lib/rubocop/cop/style/proc.rb +10 -2
  415. data/lib/rubocop/cop/style/raise_args.rb +22 -29
  416. data/lib/rubocop/cop/style/random_with_offset.rb +160 -0
  417. data/lib/rubocop/cop/style/redundant_begin.rb +16 -5
  418. data/lib/rubocop/cop/style/redundant_conditional.rb +96 -0
  419. data/lib/rubocop/cop/style/redundant_exception.rb +4 -4
  420. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  421. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -12
  422. data/lib/rubocop/cop/style/redundant_return.rb +28 -15
  423. data/lib/rubocop/cop/style/redundant_self.rb +35 -27
  424. data/lib/rubocop/cop/style/regexp_literal.rb +88 -27
  425. data/lib/rubocop/cop/style/rescue_modifier.rb +12 -1
  426. data/lib/rubocop/cop/style/rescue_standard_error.rb +122 -0
  427. data/lib/rubocop/cop/style/return_nil.rb +89 -0
  428. data/lib/rubocop/cop/style/safe_navigation.rb +100 -48
  429. data/lib/rubocop/cop/style/self_assignment.rb +13 -13
  430. data/lib/rubocop/cop/style/semicolon.rb +19 -9
  431. data/lib/rubocop/cop/style/send.rb +10 -1
  432. data/lib/rubocop/cop/style/signal_exception.rb +104 -3
  433. data/lib/rubocop/cop/style/single_line_block_params.rb +16 -15
  434. data/lib/rubocop/cop/style/single_line_methods.rb +26 -18
  435. data/lib/rubocop/cop/style/special_global_vars.rb +19 -14
  436. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +23 -50
  437. data/lib/rubocop/cop/style/stderr_puts.rb +54 -0
  438. data/lib/rubocop/cop/style/string_hash_keys.rb +36 -0
  439. data/lib/rubocop/cop/style/string_literals.rb +26 -3
  440. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +16 -1
  441. data/lib/rubocop/cop/style/string_methods.rb +19 -8
  442. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  443. data/lib/rubocop/cop/style/symbol_array.rb +7 -35
  444. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  445. data/lib/rubocop/cop/style/symbol_proc.rb +11 -25
  446. data/lib/rubocop/cop/style/ternary_parentheses.rb +46 -51
  447. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +101 -0
  448. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +20 -6
  449. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +22 -7
  450. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +95 -0
  451. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +70 -24
  452. data/lib/rubocop/cop/style/trivial_accessors.rb +72 -65
  453. data/lib/rubocop/cop/style/unless_else.rb +16 -1
  454. data/lib/rubocop/cop/style/unneeded_capital_w.rb +18 -8
  455. data/lib/rubocop/cop/style/unneeded_interpolation.rb +15 -19
  456. data/lib/rubocop/cop/style/unneeded_percent_q.rb +14 -13
  457. data/lib/rubocop/cop/style/variable_interpolation.rb +23 -9
  458. data/lib/rubocop/cop/style/when_then.rb +14 -1
  459. data/lib/rubocop/cop/style/while_until_do.rb +27 -4
  460. data/lib/rubocop/cop/style/while_until_modifier.rb +26 -6
  461. data/lib/rubocop/cop/style/word_array.rb +9 -30
  462. data/lib/rubocop/cop/style/yoda_condition.rb +51 -22
  463. data/lib/rubocop/cop/style/zero_length_predicate.rb +44 -29
  464. data/lib/rubocop/cop/team.rb +16 -8
  465. data/lib/rubocop/cop/util.rb +43 -34
  466. data/lib/rubocop/cop/variable_force.rb +1 -1
  467. data/lib/rubocop/cop/variable_force/assignment.rb +4 -2
  468. data/lib/rubocop/cop/variable_force/scope.rb +1 -5
  469. data/lib/rubocop/cop/variable_force/variable.rb +1 -1
  470. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -4
  471. data/lib/rubocop/formatter/formatter_set.rb +3 -1
  472. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  473. data/lib/rubocop/formatter/json_formatter.rb +9 -3
  474. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -0
  475. data/lib/rubocop/formatter/quiet_formatter.rb +13 -0
  476. data/lib/rubocop/formatter/simple_text_formatter.rb +3 -3
  477. data/lib/rubocop/formatter/tap_formatter.rb +71 -0
  478. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -0
  479. data/lib/rubocop/node_pattern.rb +46 -29
  480. data/lib/rubocop/options.rb +13 -8
  481. data/lib/rubocop/path_util.rb +15 -3
  482. data/lib/rubocop/processed_source.rb +8 -9
  483. data/lib/rubocop/rake_task.rb +16 -23
  484. data/lib/rubocop/remote_config.rb +13 -1
  485. data/lib/rubocop/result_cache.rb +1 -0
  486. data/lib/rubocop/rspec/cop_helper.rb +10 -10
  487. data/lib/rubocop/rspec/expect_offense.rb +6 -8
  488. data/lib/rubocop/rspec/shared_contexts.rb +4 -8
  489. data/lib/rubocop/rspec/shared_examples.rb +8 -8
  490. data/lib/rubocop/rspec/support.rb +5 -5
  491. data/lib/rubocop/runner.rb +1 -1
  492. data/lib/rubocop/string_util.rb +2 -0
  493. data/lib/rubocop/token.rb +74 -0
  494. data/lib/rubocop/version.rb +1 -1
  495. metadata +118 -48
  496. data/lib/rubocop/cop/layout/space_inside_brackets.rb +0 -20
  497. data/lib/rubocop/cop/lint/invalid_character_literal.rb +0 -41
  498. data/lib/rubocop/cop/mixin/access_modifier_node.rb +0 -41
  499. data/lib/rubocop/cop/mixin/on_method_def.rb +0 -44
  500. data/lib/rubocop/cop/mixin/space_inside.rb +0 -76
  501. data/lib/rubocop/cop/style/accessor_method_name.rb +0 -45
  502. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +0 -29
  503. data/lib/rubocop/cop/style/constant_name.rb +0 -29
  504. data/lib/rubocop/cop/style/method_name.rb +0 -34
  505. data/lib/rubocop/cop/style/predicate_name.rb +0 -67
  506. data/lib/rubocop/cop/style/variable_name.rb +0 -39
@@ -16,88 +16,54 @@ module RuboCop
16
16
  AUTO_GENERATED_FILE = '.rubocop_todo.yml'.freeze
17
17
 
18
18
  class << self
19
- include ConfigLoaderResolver
20
-
21
- attr_accessor :debug, :auto_gen_config
19
+ attr_accessor :debug, :auto_gen_config, :ignore_parent_exclusion
22
20
  attr_writer :root_level # The upwards search is stopped at this level.
23
21
  attr_writer :default_configuration
24
22
 
25
23
  alias debug? debug
26
24
  alias auto_gen_config? auto_gen_config
25
+ alias ignore_parent_exclusion? ignore_parent_exclusion
27
26
 
28
27
  def clear_options
29
28
  @debug = @auto_gen_config = @root_level = nil
30
29
  end
31
30
 
32
- def load_file(path)
33
- path = File.absolute_path(path)
31
+ def load_file(file)
32
+ return if file.nil?
33
+ path = File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
34
+
34
35
  hash = load_yaml_configuration(path)
35
36
 
36
37
  # Resolve requires first in case they define additional cops
37
- resolve_requires(path, hash)
38
+ resolver.resolve_requires(path, hash)
38
39
 
39
40
  add_missing_namespaces(path, hash)
40
41
  target_ruby_version_to_f!(hash)
41
42
 
42
- resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
43
- resolve_inheritance(path, hash)
43
+ resolver.resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
44
+ resolver.resolve_inheritance(path, hash, file)
44
45
 
45
46
  hash.delete('inherit_from')
46
47
 
47
- create_config(hash, path)
48
- end
49
-
50
- def create_config(hash, path)
51
- config = Config.new(hash, path)
52
-
53
- config.deprecation_check do |deprecation_message|
54
- warn("#{path} - #{deprecation_message}")
55
- end
56
-
57
- config.validate
58
- config.make_excludes_absolute
59
- config
48
+ Config.create(hash, path)
60
49
  end
61
50
 
51
+ # rubocop:disable Performance/HashEachMethods
62
52
  def add_missing_namespaces(path, hash)
63
- hash.keys.each do |k|
64
- q = Cop::Cop.qualified_cop_name(k, path)
65
- next if q == k
53
+ hash.keys.each do |key|
54
+ q = Cop::Cop.qualified_cop_name(key, path)
55
+ next if q == key
66
56
 
67
- hash[q] = hash.delete(k)
57
+ hash[q] = hash.delete(key)
68
58
  end
69
59
  end
60
+ # rubocop:enable Performance/HashEachMethods
70
61
 
71
62
  # Return a recursive merge of two hashes. That is, a normal hash merge,
72
63
  # with the addition that any value that is a hash, and occurs in both
73
64
  # arguments, will also be merged. And so on.
74
65
  def merge(base_hash, derived_hash)
75
- result = base_hash.merge(derived_hash)
76
- keys_appearing_in_both = base_hash.keys & derived_hash.keys
77
- keys_appearing_in_both.each do |key|
78
- next unless base_hash[key].is_a?(Hash)
79
- result[key] = merge(base_hash[key], derived_hash[key])
80
- end
81
- result
82
- end
83
-
84
- def base_configs(path, inherit_from)
85
- configs = Array(inherit_from).compact.map do |f|
86
- if f =~ /\A#{URI::Parser.new.make_regexp(%w[http https])}\z/
87
- f = RemoteConfig.new(f, File.dirname(path)).file
88
- else
89
- f = File.expand_path(f, File.dirname(path))
90
-
91
- if auto_gen_config?
92
- next if f.include?(AUTO_GENERATED_FILE)
93
- end
94
-
95
- print 'Inheriting ' if debug?
96
- end
97
- load_file(f)
98
- end
99
-
100
- configs.compact
66
+ resolver.merge(base_hash, derived_hash)
101
67
  end
102
68
 
103
69
  # Returns the path of .rubocop.yml searching upwards in the
@@ -113,14 +79,21 @@ module RuboCop
113
79
  config = load_file(config_file)
114
80
  return config if config_file == DEFAULT_FILE
115
81
 
116
- found_files = config_files_in_path(config_file)
117
- if found_files.any? && found_files.last != config_file
118
- print 'AllCops/Exclude ' if debug?
119
- config.add_excludes_from_higher_level(load_file(found_files.last))
82
+ if ignore_parent_exclusion?
83
+ print 'Ignoring AllCops/Exclude from parent folders' if debug?
84
+ else
85
+ add_excludes_from_files(config, config_file)
120
86
  end
121
87
  merge_with_default(config, config_file)
122
88
  end
123
89
 
90
+ def add_excludes_from_files(config, config_file)
91
+ found_files = config_files_in_path(config_file)
92
+ return unless found_files.any? && found_files.last != config_file
93
+ print 'AllCops/Exclude ' if debug?
94
+ config.add_excludes_from_higher_level(load_file(found_files.last))
95
+ end
96
+
124
97
  def default_configuration
125
98
  @default_configuration ||= begin
126
99
  print 'Default ' if debug?
@@ -135,22 +108,7 @@ module RuboCop
135
108
  # so that only cops explicitly disabled in user configuration are
136
109
  # disabled.
137
110
  def merge_with_default(config, config_file)
138
- default_configuration = self.default_configuration
139
-
140
- disabled_by_default = config.for_all_cops['DisabledByDefault']
141
- enabled_by_default = config.for_all_cops['EnabledByDefault']
142
-
143
- if disabled_by_default || enabled_by_default
144
- default_configuration = transform(default_configuration) do |params|
145
- params.merge('Enabled' => !disabled_by_default)
146
- end
147
- end
148
-
149
- if disabled_by_default
150
- config = handle_disabled_by_default(config, default_configuration)
151
- end
152
-
153
- Config.new(merge(default_configuration, config), config_file)
111
+ resolver.merge_with_default(config, config_file)
154
112
  end
155
113
 
156
114
  def target_ruby_version_to_f!(hash)
@@ -160,40 +118,37 @@ module RuboCop
160
118
  hash['AllCops'][version] = hash['AllCops'][version].to_f
161
119
  end
162
120
 
163
- private
164
-
165
- def handle_disabled_by_default(config, new_default_configuration)
166
- department_config = config.to_hash.reject { |cop| cop.include?('/') }
167
- department_config.each do |dept, dept_params|
168
- # Rails is always disabled by default and the department's Enabled
169
- # flag works like the --rails command line option, which is that when
170
- # AllCops:DisabledByDefault is true, each Rails cop must still be
171
- # explicitly mentioned in user configuration in order to be enabled.
172
- next if dept == 'Rails'
121
+ def add_inheritance_from_auto_generated_file
122
+ file_string = " #{AUTO_GENERATED_FILE}"
173
123
 
174
- next unless dept_params['Enabled']
175
-
176
- new_default_configuration.each do |cop, params|
177
- next unless cop.start_with?(dept + '/')
178
-
179
- # Retain original default configuration for cops in the department.
180
- params['Enabled'] = default_configuration[cop]['Enabled']
181
- end
124
+ if File.exist?(DOTFILE)
125
+ files = Array(load_yaml_configuration(DOTFILE)['inherit_from'])
126
+ return if files.include?(AUTO_GENERATED_FILE)
127
+ files.unshift(AUTO_GENERATED_FILE)
128
+ file_string = "\n - " + files.join("\n - ") if files.size > 1
129
+ rubocop_yml_contents = IO.read(DOTFILE, encoding: Encoding::UTF_8)
130
+ .sub(/^inherit_from: *[.\w]+/, '')
131
+ .sub(/^inherit_from: *(\n *- *[.\w]+)+/, '')
182
132
  end
133
+ write_dotfile(file_string, rubocop_yml_contents)
134
+ puts "Added inheritance from `#{AUTO_GENERATED_FILE}` in `#{DOTFILE}`."
135
+ end
136
+
137
+ private
183
138
 
184
- transform(config) do |params|
185
- { 'Enabled' => true }.merge(params) # Set true if not set.
139
+ def write_dotfile(file_string, rubocop_yml_contents)
140
+ File.open(DOTFILE, 'w') do |f|
141
+ f.write "inherit_from:#{file_string}\n\n"
142
+ f.write rubocop_yml_contents if rubocop_yml_contents
186
143
  end
187
144
  end
188
145
 
189
- # Returns a new hash where the parameters of the given config hash have
190
- # been replaced by parameters returned by the given block.
191
- def transform(config)
192
- Hash[config.map { |cop, params| [cop, yield(params)] }]
146
+ def resolver
147
+ @resolver ||= ConfigLoaderResolver.new
193
148
  end
194
149
 
195
150
  def load_yaml_configuration(absolute_path)
196
- yaml_code = IO.read(absolute_path, encoding: Encoding::UTF_8)
151
+ yaml_code = read_file(absolute_path)
197
152
  hash = yaml_safe_load(yaml_code, absolute_path) || {}
198
153
 
199
154
  puts "configuration from #{absolute_path}" if debug?
@@ -205,6 +160,16 @@ module RuboCop
205
160
  hash
206
161
  end
207
162
 
163
+ # Read the specified file, or exit with a friendly, concise message on
164
+ # stderr. Care is taken to use the standard OS exit code for a "file not
165
+ # found" error.
166
+ def read_file(absolute_path)
167
+ IO.read(absolute_path, encoding: Encoding::UTF_8)
168
+ rescue Errno::ENOENT
169
+ warn(format('Configuration file not found: %s', absolute_path))
170
+ exit(Errno::ENOENT::Errno)
171
+ end
172
+
208
173
  def yaml_safe_load(yaml_code, filename)
209
174
  if YAML.respond_to?(:safe_load) # Ruby 2.1+
210
175
  if defined?(SafeYAML) && SafeYAML.respond_to?(:load)
@@ -218,14 +183,6 @@ module RuboCop
218
183
  end
219
184
  end
220
185
 
221
- def gem_config_path(gem_name, relative_config_path)
222
- spec = Gem::Specification.find_by_name(gem_name)
223
- return File.join(spec.gem_dir, relative_config_path)
224
- rescue Gem::LoadError => e
225
- raise Gem::LoadError,
226
- "Unable to find gem #{gem_name}; is the gem installed? #{e}"
227
- end
228
-
229
186
  def config_files_in_path(target)
230
187
  possible_config_files = dirs_to_search(target).map do |dir|
231
188
  File.join(dir, DOTFILE)
@@ -4,8 +4,8 @@ require 'yaml'
4
4
  require 'pathname'
5
5
 
6
6
  module RuboCop
7
- # A mixin to break up ConfigLoader
8
- module ConfigLoaderResolver
7
+ # A help class for ConfigLoader that handles configuration resolution.
8
+ class ConfigLoaderResolver
9
9
  def resolve_requires(path, hash)
10
10
  config_dir = File.dirname(path)
11
11
  Array(hash.delete('require')).each do |r|
@@ -17,8 +17,9 @@ module RuboCop
17
17
  end
18
18
  end
19
19
 
20
- def resolve_inheritance(path, hash)
21
- base_configs(path, hash['inherit_from']).reverse_each do |base_config|
20
+ def resolve_inheritance(path, hash, file)
21
+ base_configs(path, hash['inherit_from'], file)
22
+ .reverse_each do |base_config|
22
23
  base_config.each do |k, v|
23
24
  hash[k] = hash.key?(k) ? merge(v, hash[k]) : v if v.is_a?(Hash)
24
25
  end
@@ -39,5 +40,102 @@ module RuboCop
39
40
  end
40
41
  end
41
42
  end
43
+
44
+ # Merges the given configuration with the default one. If
45
+ # AllCops:DisabledByDefault is true, it changes the Enabled params so that
46
+ # only cops from user configuration are enabled. If
47
+ # AllCops::EnabledByDefault is true, it changes the Enabled params so that
48
+ # only cops explicitly disabled in user configuration are disabled.
49
+ def merge_with_default(config, config_file)
50
+ default_configuration = ConfigLoader.default_configuration
51
+
52
+ disabled_by_default = config.for_all_cops['DisabledByDefault']
53
+ enabled_by_default = config.for_all_cops['EnabledByDefault']
54
+
55
+ if disabled_by_default || enabled_by_default
56
+ default_configuration = transform(default_configuration) do |params|
57
+ params.merge('Enabled' => !disabled_by_default)
58
+ end
59
+ end
60
+
61
+ if disabled_by_default
62
+ config = handle_disabled_by_default(config, default_configuration)
63
+ end
64
+
65
+ Config.new(merge(default_configuration, config), config_file)
66
+ end
67
+
68
+ # Returns a new hash where the parameters of the given config hash have
69
+ # been replaced by parameters returned by the given block.
70
+ # Return a recursive merge of two hashes. That is, a normal hash merge,
71
+ # with the addition that any value that is a hash, and occurs in both
72
+ # arguments, will also be merged. And so on.
73
+ def merge(base_hash, derived_hash)
74
+ result = base_hash.merge(derived_hash)
75
+ keys_appearing_in_both = base_hash.keys & derived_hash.keys
76
+ keys_appearing_in_both.each do |key|
77
+ next unless base_hash[key].is_a?(Hash)
78
+ result[key] = merge(base_hash[key], derived_hash[key])
79
+ end
80
+ result
81
+ end
82
+
83
+ private
84
+
85
+ def base_configs(path, inherit_from, file)
86
+ configs = Array(inherit_from).compact.map do |f|
87
+ ConfigLoader.load_file(inherited_file(path, f, file))
88
+ end
89
+
90
+ configs.compact
91
+ end
92
+
93
+ def inherited_file(path, inherit_from, file)
94
+ regex = URI::DEFAULT_PARSER.make_regexp(%w[http https])
95
+ if inherit_from =~ /\A#{regex}\z/
96
+ RemoteConfig.new(inherit_from, File.dirname(path))
97
+ elsif file.is_a?(RemoteConfig)
98
+ file.inherit_from_remote(inherit_from, path)
99
+ else
100
+ print 'Inheriting ' if ConfigLoader.debug?
101
+ File.expand_path(inherit_from, File.dirname(path))
102
+ end
103
+ end
104
+
105
+ def handle_disabled_by_default(config, new_default_configuration)
106
+ department_config = config.to_hash.reject { |cop| cop.include?('/') }
107
+ department_config.each do |dept, dept_params|
108
+ # Rails is always disabled by default and the department's Enabled flag
109
+ # works like the --rails command line option, which is that when
110
+ # AllCops:DisabledByDefault is true, each Rails cop must still be
111
+ # explicitly mentioned in user configuration in order to be enabled.
112
+ next if dept == 'Rails'
113
+
114
+ next unless dept_params['Enabled']
115
+
116
+ new_default_configuration.each do |cop, params|
117
+ next unless cop.start_with?(dept + '/')
118
+
119
+ # Retain original default configuration for cops in the department.
120
+ params['Enabled'] = ConfigLoader.default_configuration[cop]['Enabled']
121
+ end
122
+ end
123
+
124
+ transform(config) do |params|
125
+ { 'Enabled' => true }.merge(params) # Set true if not set.
126
+ end
127
+ end
128
+
129
+ def transform(config)
130
+ Hash[config.map { |cop, params| [cop, yield(params)] }]
131
+ end
132
+
133
+ def gem_config_path(gem_name, relative_config_path)
134
+ spec = Gem::Specification.find_by_name(gem_name)
135
+ return File.join(spec.gem_dir, relative_config_path)
136
+ rescue Gem::LoadError => e
137
+ raise Gem::LoadError,
138
+ "Unable to find gem #{gem_name}; is the gem installed? #{e}"
139
+ end
42
140
  end
43
141
  end
@@ -13,7 +13,7 @@ module RuboCop
13
13
  end
14
14
 
15
15
  def support_autocorrect?
16
- respond_to?(:autocorrect, true)
16
+ respond_to?(:autocorrect)
17
17
  end
18
18
 
19
19
  def autocorrect_enabled?
@@ -26,8 +26,8 @@ module RuboCop
26
26
  # # good
27
27
  # gem 'rubocop', groups: [:development, :test]
28
28
  class DuplicatedGem < Cop
29
- MSG = 'Gem `%s` requirements already given on line %d ' \
30
- 'of the Gemfile.'.freeze
29
+ MSG = 'Gem `%<gem_name>s` requirements already given on line '\
30
+ '%<line_of_first_occurrence>d of the Gemfile.'.freeze
31
31
 
32
32
  def investigate(processed_source)
33
33
  return unless processed_source.ast
@@ -36,7 +36,7 @@ module RuboCop
36
36
  nodes[1..-1].each do |node|
37
37
  register_offense(
38
38
  node,
39
- node.method_args.first.to_a.first,
39
+ node.first_argument.to_a.first,
40
40
  nodes.first.loc.line
41
41
  )
42
42
  end
@@ -45,23 +45,25 @@ module RuboCop
45
45
 
46
46
  private
47
47
 
48
- def_node_search :gem_declarations, '(send nil :gem str ...)'
48
+ def_node_search :gem_declarations, '(send nil? :gem str ...)'
49
49
 
50
50
  def duplicated_gem_nodes
51
51
  gem_declarations(processed_source.ast)
52
- .group_by { |e| e.method_args.first }
53
- .keep_if { |_, nodes| nodes.length > 1 }
52
+ .group_by(&:first_argument)
54
53
  .values
54
+ .select { |nodes| nodes.size > 1 }
55
55
  end
56
56
 
57
57
  def register_offense(node, gem_name, line_of_first_occurrence)
58
58
  line_range = node.loc.column...node.loc.last_column
59
-
60
- add_offense(
61
- node,
62
- source_range(processed_source.buffer, node.loc.line, line_range),
63
- format(MSG, gem_name, line_of_first_occurrence)
59
+ offense_location =
60
+ source_range(processed_source.buffer, node.loc.line, line_range)
61
+ message = format(
62
+ MSG,
63
+ gem_name: gem_name,
64
+ line_of_first_occurrence: line_of_first_occurrence
64
65
  )
66
+ add_offense(node, location: offense_location, message: message)
65
67
  end
66
68
  end
67
69
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Bundler
6
+ # The symbol argument `:gemcutter`, `:rubygems` and `:rubyforge`
7
+ # are deprecated. So please change your source to URL string that
8
+ # 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
9
+ #
10
+ # This autocorrect will replace these symbols with 'https://rubygems.org'.
11
+ # Because it is secure, HTTPS request is strongly recommended. And in
12
+ # most use cases HTTPS will be fine.
13
+ #
14
+ # However, it don't replace all `sources` of `http://` with `https://`.
15
+ # For example, when specifying an internal gem server using HTTP on the
16
+ # intranet, a use case where HTTPS can not be specified was considered.
17
+ # Consider using HTTP only if you can not use HTTPS.
18
+ #
19
+ # @example
20
+ # # bad
21
+ # source :gemcutter
22
+ # source :rubygems
23
+ # source :rubyforge
24
+ #
25
+ # # good
26
+ # source 'https://rubygems.org' # strongly recommended
27
+ # source 'http://rubygems.org'
28
+ class InsecureProtocolSource < Cop
29
+ MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
30
+ 'are insecure. ' \
31
+ "Please change your source to 'https://rubygems.org' " \
32
+ "if possible, or 'http://rubygems.org' if not.".freeze
33
+
34
+ def_node_matcher :insecure_protocol_source?, <<-PATTERN
35
+ (send nil? :source
36
+ (sym ${:gemcutter :rubygems :rubyforge}))
37
+ PATTERN
38
+
39
+ def on_send(node)
40
+ insecure_protocol_source?(node) do |source|
41
+ message = format(MSG, source: source)
42
+
43
+ add_offense(
44
+ node,
45
+ location: source_range(node.first_argument.loc.expression),
46
+ message: message
47
+ )
48
+ end
49
+ end
50
+
51
+ def autocorrect(node)
52
+ lambda do |corrector|
53
+ corrector.replace(
54
+ node.first_argument.loc.expression, "'https://rubygems.org'"
55
+ )
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def source_range(node)
62
+ range_between(node.begin_pos, node.end_pos)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end