rubocop 0.71.0 → 0.75.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (280) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -8
  3. data/bin/console +1 -0
  4. data/config/default.yml +84 -488
  5. data/lib/rubocop.rb +16 -54
  6. data/lib/rubocop/ast/builder.rb +2 -0
  7. data/lib/rubocop/ast/node.rb +9 -15
  8. data/lib/rubocop/ast/node/float_node.rb +12 -0
  9. data/lib/rubocop/ast/node/int_node.rb +12 -0
  10. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
  11. data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
  12. data/lib/rubocop/ast/node/resbody_node.rb +1 -6
  13. data/lib/rubocop/ast/traversal.rb +3 -3
  14. data/lib/rubocop/cached_data.rb +1 -1
  15. data/lib/rubocop/comment_config.rb +3 -2
  16. data/lib/rubocop/config.rb +21 -508
  17. data/lib/rubocop/config_loader.rb +22 -8
  18. data/lib/rubocop/config_loader_resolver.rb +2 -16
  19. data/lib/rubocop/config_obsoletion.rb +213 -0
  20. data/lib/rubocop/config_validator.rb +239 -0
  21. data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
  22. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  24. data/lib/rubocop/cop/commissioner.rb +3 -9
  25. data/lib/rubocop/cop/cop.rb +39 -12
  26. data/lib/rubocop/cop/corrector.rb +2 -3
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  28. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
  29. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  30. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  31. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  32. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  33. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
  35. data/lib/rubocop/cop/generator.rb +4 -4
  36. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  37. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
  39. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
  41. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  42. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
  43. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  44. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  45. data/lib/rubocop/cop/layout/class_structure.rb +2 -2
  46. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
  51. data/lib/rubocop/cop/layout/indent_assignment.rb +10 -1
  52. data/lib/rubocop/cop/layout/indent_first_argument.rb +7 -3
  53. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  54. data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -4
  55. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  56. data/lib/rubocop/cop/layout/indentation_width.rb +28 -10
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
  58. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  59. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -4
  60. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  61. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  62. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +1 -1
  63. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
  64. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  65. data/lib/rubocop/cop/layout/tab.rb +10 -22
  66. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  67. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
  68. data/lib/rubocop/cop/lint/debugger.rb +4 -6
  69. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  70. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  71. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  72. data/lib/rubocop/cop/lint/erb_new_arguments.rb +57 -1
  73. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
  74. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  75. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  76. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  77. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  78. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
  79. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  80. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  81. data/lib/rubocop/cop/lint/number_conversion.rb +4 -4
  82. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  83. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  84. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  85. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -5
  86. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  87. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  88. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  89. data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
  90. data/lib/rubocop/cop/lint/unneeded_cop_disable_directive.rb +1 -1
  91. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -1
  92. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +7 -2
  93. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  94. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  95. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  96. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  97. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
  98. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
  99. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  100. data/lib/rubocop/cop/lint/void.rb +3 -22
  101. data/lib/rubocop/cop/message_annotator.rb +16 -7
  102. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  103. data/lib/rubocop/cop/metrics/line_length.rb +6 -0
  104. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  105. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  106. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  107. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  108. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  109. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  110. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
  111. data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
  112. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  113. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  114. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  115. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  116. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  117. data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
  118. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  119. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  120. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  121. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  122. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  123. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -20
  124. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  125. data/lib/rubocop/cop/offense.rb +18 -7
  126. data/lib/rubocop/cop/registry.rb +22 -1
  127. data/lib/rubocop/cop/security/eval.rb +1 -1
  128. data/lib/rubocop/cop/security/json_load.rb +1 -1
  129. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  130. data/lib/rubocop/cop/security/open.rb +1 -1
  131. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  132. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  133. data/lib/rubocop/cop/style/alias.rb +1 -1
  134. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  135. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +29 -10
  136. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  137. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  138. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -9
  140. data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
  141. data/lib/rubocop/cop/style/date_time.rb +3 -3
  142. data/lib/rubocop/cop/style/dir.rb +1 -1
  143. data/lib/rubocop/cop/style/documentation_method.rb +45 -1
  144. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
  145. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  146. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  147. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  148. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  149. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -4
  150. data/lib/rubocop/cop/style/float_division.rb +94 -0
  151. data/lib/rubocop/cop/style/format_string.rb +13 -9
  152. data/lib/rubocop/cop/style/format_string_token.rb +18 -69
  153. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +18 -33
  154. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  155. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  156. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  157. data/lib/rubocop/cop/style/if_unless_modifier.rb +51 -15
  158. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  159. data/lib/rubocop/cop/style/inverse_methods.rb +2 -2
  160. data/lib/rubocop/cop/style/lambda.rb +0 -2
  161. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +32 -26
  162. data/lib/rubocop/cop/style/min_max.rb +1 -1
  163. data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
  164. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  165. data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
  166. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  168. data/lib/rubocop/cop/style/nested_modifier.rb +18 -2
  169. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
  170. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  171. data/lib/rubocop/cop/style/or_assignment.rb +8 -3
  172. data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
  173. data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
  175. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  176. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  177. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
  178. data/lib/rubocop/cop/style/redundant_return.rb +12 -0
  179. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  180. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  181. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  182. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  183. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  184. data/lib/rubocop/cop/style/safe_navigation.rb +19 -2
  185. data/lib/rubocop/cop/style/sample.rb +1 -1
  186. data/lib/rubocop/cop/style/semicolon.rb +11 -0
  187. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  188. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  189. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
  190. data/lib/rubocop/cop/style/strip.rb +1 -1
  191. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  192. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  193. data/lib/rubocop/cop/style/ternary_parentheses.rb +32 -3
  194. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  195. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  196. data/lib/rubocop/cop/style/unneeded_sort.rb +1 -1
  197. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  198. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  199. data/lib/rubocop/cop/style/word_array.rb +2 -2
  200. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
  201. data/lib/rubocop/cop/team.rb +15 -14
  202. data/lib/rubocop/cop/utils/format_string.rb +128 -0
  203. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  204. data/lib/rubocop/core_ext/string.rb +0 -24
  205. data/lib/rubocop/error.rb +23 -0
  206. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
  207. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  208. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  209. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  210. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  211. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  212. data/lib/rubocop/formatter/tap_formatter.rb +17 -4
  213. data/lib/rubocop/magic_comment.rb +4 -0
  214. data/lib/rubocop/node_pattern.rb +2 -2
  215. data/lib/rubocop/options.rb +21 -17
  216. data/lib/rubocop/path_util.rb +1 -1
  217. data/lib/rubocop/processed_source.rb +6 -1
  218. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  219. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  220. data/lib/rubocop/rspec/shared_contexts.rb +12 -17
  221. data/lib/rubocop/rspec/support.rb +0 -1
  222. data/lib/rubocop/runner.rb +14 -25
  223. data/lib/rubocop/target_finder.rb +6 -4
  224. data/lib/rubocop/version.rb +1 -1
  225. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  226. metadata +17 -92
  227. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  228. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  229. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  230. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  231. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  232. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  233. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  234. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  235. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  236. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  237. data/lib/rubocop/cop/rails/blank.rb +0 -164
  238. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  239. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  240. data/lib/rubocop/cop/rails/date.rb +0 -161
  241. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  242. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  243. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  244. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  245. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  246. data/lib/rubocop/cop/rails/exit.rb +0 -67
  247. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  248. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  249. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  250. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  251. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  252. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  253. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  254. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  255. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  256. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  257. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  258. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  259. data/lib/rubocop/cop/rails/output.rb +0 -49
  260. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  261. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  262. data/lib/rubocop/cop/rails/presence.rb +0 -124
  263. data/lib/rubocop/cop/rails/present.rb +0 -153
  264. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  265. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  266. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  267. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  268. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  269. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  270. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  271. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  272. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  273. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  274. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  275. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  276. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  277. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  278. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  279. data/lib/rubocop/cop/rails/validation.rb +0 -109
  280. data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop checks for consistent uses of `request.referer` or
7
- # `request.referrer`, depending on the cop's configuration.
8
- #
9
- # @example EnforcedStyle: referer (default)
10
- # # bad
11
- # request.referrer
12
- #
13
- # # good
14
- # request.referer
15
- #
16
- # @example EnforcedStyle: referrer
17
- # # bad
18
- # request.referer
19
- #
20
- # # good
21
- # request.referrer
22
- class RequestReferer < Cop
23
- include ConfigurableEnforcedStyle
24
-
25
- MSG = 'Use `request.%<prefer>s` instead of ' \
26
- '`request.%<current>s`.'
27
-
28
- def_node_matcher :referer?, <<-PATTERN
29
- (send (send nil? :request) {:referer :referrer})
30
- PATTERN
31
-
32
- def on_send(node)
33
- referer?(node) do
34
- return unless node.method?(wrong_method_name)
35
-
36
- add_offense(node.source_range, location: node.source_range)
37
- end
38
- end
39
-
40
- def autocorrect(node)
41
- ->(corrector) { corrector.replace(node, "request.#{style}") }
42
- end
43
-
44
- private
45
-
46
- def message(_node)
47
- format(MSG, prefer: style, current: wrong_method_name)
48
- end
49
-
50
- def wrong_method_name
51
- style == :referer ? :referrer : :referer
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,286 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop checks whether the change method of the migration file is
7
- # reversible.
8
- #
9
- # @example
10
- # # bad
11
- # def change
12
- # change_table :users do |t|
13
- # t.remove :name
14
- # end
15
- # end
16
- #
17
- # # good
18
- # def change
19
- # create_table :users do |t|
20
- # t.string :name
21
- # end
22
- # end
23
- #
24
- # # good
25
- # def change
26
- # reversible do |dir|
27
- # change_table :users do |t|
28
- # dir.up do
29
- # t.column :name, :string
30
- # end
31
- #
32
- # dir.down do
33
- # t.remove :name
34
- # end
35
- # end
36
- # end
37
- # end
38
- #
39
- # @example
40
- # # drop_table
41
- #
42
- # # bad
43
- # def change
44
- # drop_table :users
45
- # end
46
- #
47
- # # good
48
- # def change
49
- # drop_table :users do |t|
50
- # t.string :name
51
- # end
52
- # end
53
- #
54
- # @example
55
- # # change_column_default
56
- #
57
- # # bad
58
- # def change
59
- # change_column_default(:suppliers, :qualification, 'new')
60
- # end
61
- #
62
- # # good
63
- # def change
64
- # change_column_default(:posts, :state, from: nil, to: "draft")
65
- # end
66
- #
67
- # @example
68
- # # remove_column
69
- #
70
- # # bad
71
- # def change
72
- # remove_column(:suppliers, :qualification)
73
- # end
74
- #
75
- # # good
76
- # def change
77
- # remove_column(:suppliers, :qualification, :string)
78
- # end
79
- #
80
- # @example
81
- # # remove_foreign_key
82
- #
83
- # # bad
84
- # def change
85
- # remove_foreign_key :accounts, column: :owner_id
86
- # end
87
- #
88
- # # good
89
- # def change
90
- # remove_foreign_key :accounts, :branches
91
- # end
92
- #
93
- # @example
94
- # # change_table
95
- #
96
- # # bad
97
- # def change
98
- # change_table :users do |t|
99
- # t.remove :name
100
- # t.change_default :authorized, 1
101
- # t.change :price, :string
102
- # end
103
- # end
104
- #
105
- # # good
106
- # def change
107
- # change_table :users do |t|
108
- # t.string :name
109
- # end
110
- # end
111
- #
112
- # # good
113
- # def change
114
- # reversible do |dir|
115
- # change_table :users do |t|
116
- # dir.up do
117
- # t.change :price, :string
118
- # end
119
- #
120
- # dir.down do
121
- # t.change :price, :integer
122
- # end
123
- # end
124
- # end
125
- # end
126
- #
127
- # @see https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html
128
- class ReversibleMigration < Cop
129
- MSG = '%<action>s is not reversible.'
130
- IRREVERSIBLE_CHANGE_TABLE_CALLS = %i[
131
- change change_default remove
132
- ].freeze
133
-
134
- def_node_matcher :irreversible_schema_statement_call, <<-PATTERN
135
- (send nil? ${:change_table_comment :execute :remove_belongs_to} ...)
136
- PATTERN
137
-
138
- def_node_matcher :drop_table_call, <<-PATTERN
139
- (send nil? :drop_table ...)
140
- PATTERN
141
-
142
- def_node_matcher :change_column_default_call, <<-PATTERN
143
- (send nil? :change_column_default {[(sym _) (sym _)] (splat _)} $...)
144
- PATTERN
145
-
146
- def_node_matcher :remove_column_call, <<-PATTERN
147
- (send nil? :remove_column $...)
148
- PATTERN
149
-
150
- def_node_matcher :remove_foreign_key_call, <<-PATTERN
151
- (send nil? :remove_foreign_key _ $_)
152
- PATTERN
153
-
154
- def_node_matcher :change_table_call, <<-PATTERN
155
- (send nil? :change_table $_ ...)
156
- PATTERN
157
-
158
- def on_send(node)
159
- return unless within_change_method?(node)
160
- return if within_reversible_or_up_only_block?(node)
161
-
162
- check_irreversible_schema_statement_node(node)
163
- check_drop_table_node(node)
164
- check_change_column_default_node(node)
165
- check_remove_column_node(node)
166
- check_remove_foreign_key_node(node)
167
- end
168
-
169
- def on_block(node)
170
- return unless within_change_method?(node)
171
- return if within_reversible_or_up_only_block?(node)
172
- return if node.body.nil?
173
-
174
- check_change_table_node(node.send_node, node.body)
175
- end
176
-
177
- private
178
-
179
- def check_irreversible_schema_statement_node(node)
180
- irreversible_schema_statement_call(node) do |method_name|
181
- add_offense(node, message: format(MSG, action: method_name))
182
- end
183
- end
184
-
185
- def check_drop_table_node(node)
186
- drop_table_call(node) do
187
- unless node.parent.block_type?
188
- add_offense(
189
- node,
190
- message: format(MSG, action: 'drop_table(without block)')
191
- )
192
- end
193
- end
194
- end
195
-
196
- def check_change_column_default_node(node)
197
- change_column_default_call(node) do |args|
198
- unless all_hash_key?(args.last, :from, :to)
199
- add_offense(
200
- node,
201
- message: format(
202
- MSG, action: 'change_column_default(without :from and :to)'
203
- )
204
- )
205
- end
206
- end
207
- end
208
-
209
- def check_remove_column_node(node)
210
- remove_column_call(node) do |args|
211
- if args.to_a.size < 3
212
- add_offense(
213
- node,
214
- message: format(MSG, action: 'remove_column(without type)')
215
- )
216
- end
217
- end
218
- end
219
-
220
- def check_remove_foreign_key_node(node)
221
- remove_foreign_key_call(node) do |arg|
222
- if arg.hash_type?
223
- add_offense(
224
- node,
225
- message: format(MSG,
226
- action: 'remove_foreign_key(without table)')
227
- )
228
- end
229
- end
230
- end
231
-
232
- def check_change_table_node(node, block)
233
- change_table_call(node) do |arg|
234
- if target_rails_version < 4.0
235
- add_offense(
236
- node,
237
- message: format(MSG, action: 'change_table')
238
- )
239
- elsif block.send_type?
240
- check_change_table_offense(arg, block)
241
- else
242
- block.each_child_node(:send) do |child_node|
243
- check_change_table_offense(arg, child_node)
244
- end
245
- end
246
- end
247
- end
248
-
249
- def check_change_table_offense(receiver, node)
250
- method_name = node.method_name
251
- return if receiver != node.receiver &&
252
- !IRREVERSIBLE_CHANGE_TABLE_CALLS.include?(method_name)
253
-
254
- add_offense(
255
- node,
256
- message: format(MSG, action: "change_table(with #{method_name})")
257
- )
258
- end
259
-
260
- def within_change_method?(node)
261
- node.each_ancestor(:def).any? do |ancestor|
262
- ancestor.method?(:change)
263
- end
264
- end
265
-
266
- def within_reversible_or_up_only_block?(node)
267
- node.each_ancestor(:block).any? do |ancestor|
268
- ancestor.block_type? &&
269
- ancestor.send_node.method?(:reversible) ||
270
- ancestor.send_node.method?(:up_only)
271
- end
272
- end
273
-
274
- def all_hash_key?(args, *keys)
275
- return false unless args&.hash_type?
276
-
277
- hash_keys = args.keys.map do |key|
278
- key.children.first.to_sym
279
- end
280
-
281
- hash_keys & keys == keys
282
- end
283
- end
284
- end
285
- end
286
- end
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop converts usages of `try!` to `&.`. It can also be configured
7
- # to convert `try`. It will convert code to use safe navigation.
8
- #
9
- # @example
10
- # # ConvertTry: false
11
- # # bad
12
- # foo.try!(:bar)
13
- # foo.try!(:bar, baz)
14
- # foo.try!(:bar) { |e| e.baz }
15
- #
16
- # foo.try!(:[], 0)
17
- #
18
- # # good
19
- # foo.try(:bar)
20
- # foo.try(:bar, baz)
21
- # foo.try(:bar) { |e| e.baz }
22
- #
23
- # foo&.bar
24
- # foo&.bar(baz)
25
- # foo&.bar { |e| e.baz }
26
- #
27
- #
28
- # # ConvertTry: true
29
- # # bad
30
- # foo.try!(:bar)
31
- # foo.try!(:bar, baz)
32
- # foo.try!(:bar) { |e| e.baz }
33
- # foo.try(:bar)
34
- # foo.try(:bar, baz)
35
- # foo.try(:bar) { |e| e.baz }
36
- #
37
- # # good
38
- # foo&.bar
39
- # foo&.bar(baz)
40
- # foo&.bar { |e| e.baz }
41
- class SafeNavigation < Cop
42
- include RangeHelp
43
-
44
- MSG = 'Use safe navigation (`&.`) instead of `%<try>s`.'
45
-
46
- def_node_matcher :try_call, <<-PATTERN
47
- (send !nil? ${:try :try!} $_ ...)
48
- PATTERN
49
-
50
- def on_send(node)
51
- try_call(node) do |try_method, dispatch|
52
- return if try_method == :try && !cop_config['ConvertTry']
53
- return unless dispatch.sym_type? && dispatch.value =~ /\w+[=!?]?/
54
-
55
- add_offense(node, message: format(MSG, try: try_method))
56
- end
57
- end
58
-
59
- def autocorrect(node)
60
- method_node, *params = *node.arguments
61
- method = method_node.source[1..-1]
62
-
63
- range = range_between(node.loc.dot.begin_pos,
64
- node.loc.expression.end_pos)
65
-
66
- lambda do |corrector|
67
- corrector.replace(range, replacement(method, params))
68
- end
69
- end
70
-
71
- private
72
-
73
- def replacement(method, params)
74
- new_params = params.map(&:source).join(', ')
75
-
76
- if method.end_with?('=')
77
- "&.#{method[0...-1]} = #{new_params}"
78
- elsif params.empty?
79
- "&.#{method}"
80
- else
81
- "&.#{method}(#{new_params})"
82
- end
83
- end
84
- end
85
- end
86
- end
87
- end
@@ -1,316 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop identifies possible cases where Active Record save! or related
7
- # should be used instead of save because the model might have failed to
8
- # save and an exception is better than unhandled failure.
9
- #
10
- # This will allow:
11
- # - update or save calls, assigned to a variable,
12
- # or used as a condition in an if/unless/case statement.
13
- # - create calls, assigned to a variable that then has a
14
- # call to `persisted?`.
15
- # - calls if the result is explicitly returned from methods and blocks,
16
- # or provided as arguments.
17
- # - calls whose signature doesn't look like an ActiveRecord
18
- # persistence method.
19
- #
20
- # By default it will also allow implicit returns from methods and blocks.
21
- # that behavior can be turned off with `AllowImplicitReturn: false`.
22
- #
23
- # You can permit receivers that are giving false positives with
24
- # `AllowedReceivers: []`
25
- #
26
- # @example
27
- #
28
- # # bad
29
- # user.save
30
- # user.update(name: 'Joe')
31
- # user.find_or_create_by(name: 'Joe')
32
- # user.destroy
33
- #
34
- # # good
35
- # unless user.save
36
- # # ...
37
- # end
38
- # user.save!
39
- # user.update!(name: 'Joe')
40
- # user.find_or_create_by!(name: 'Joe')
41
- # user.destroy!
42
- #
43
- # user = User.find_or_create_by(name: 'Joe')
44
- # unless user.persisted?
45
- # # ...
46
- # end
47
- #
48
- # def save_user
49
- # return user.save
50
- # end
51
- #
52
- # @example AllowImplicitReturn: true (default)
53
- #
54
- # # good
55
- # users.each { |u| u.save }
56
- #
57
- # def save_user
58
- # user.save
59
- # end
60
- #
61
- # @example AllowImplicitReturn: false
62
- #
63
- # # bad
64
- # users.each { |u| u.save }
65
- # def save_user
66
- # user.save
67
- # end
68
- #
69
- # # good
70
- # users.each { |u| u.save! }
71
- #
72
- # def save_user
73
- # user.save!
74
- # end
75
- #
76
- # def save_user
77
- # return user.save
78
- # end
79
- #
80
- # @example AllowedReceivers: ['merchant.customers', 'Service::Mailer']
81
- #
82
- # # bad
83
- # merchant.create
84
- # customers.builder.save
85
- # Mailer.create
86
- #
87
- # module Service::Mailer
88
- # self.create
89
- # end
90
- #
91
- # # good
92
- # merchant.customers.create
93
- # MerchantService.merchant.customers.destroy
94
- # Service::Mailer.update(message: 'Message')
95
- # ::Service::Mailer.update
96
- # Services::Service::Mailer.update(message: 'Message')
97
- # Service::Mailer::update
98
- #
99
- class SaveBang < Cop
100
- include NegativeConditional
101
-
102
- MSG = 'Use `%<prefer>s` instead of `%<current>s` if the return ' \
103
- 'value is not checked.'
104
- CREATE_MSG = (MSG +
105
- ' Or check `persisted?` on model returned from ' \
106
- '`%<current>s`.').freeze
107
- CREATE_CONDITIONAL_MSG = '`%<current>s` returns a model which is ' \
108
- 'always truthy.'
109
-
110
- CREATE_PERSIST_METHODS = %i[create
111
- first_or_create find_or_create_by].freeze
112
- MODIFY_PERSIST_METHODS = %i[save
113
- update update_attributes destroy].freeze
114
- PERSIST_METHODS = (CREATE_PERSIST_METHODS +
115
- MODIFY_PERSIST_METHODS).freeze
116
-
117
- def join_force?(force_class)
118
- force_class == VariableForce
119
- end
120
-
121
- def after_leaving_scope(scope, _variable_table)
122
- scope.variables.each_value do |variable|
123
- variable.assignments.each do |assignment|
124
- check_assignment(assignment)
125
- end
126
- end
127
- end
128
-
129
- def check_assignment(assignment)
130
- node = right_assignment_node(assignment)
131
-
132
- return unless node&.send_type?
133
- return unless persist_method?(node, CREATE_PERSIST_METHODS)
134
- return if persisted_referenced?(assignment)
135
-
136
- add_offense_for_node(node, CREATE_MSG)
137
- end
138
-
139
- def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
140
- return unless persist_method?(node)
141
- return if return_value_assigned?(node)
142
- return if check_used_in_conditional(node)
143
- return if argument?(node)
144
- return if implicit_return?(node)
145
- return if explicit_return?(node)
146
-
147
- add_offense_for_node(node)
148
- end
149
- alias on_csend on_send
150
-
151
- def autocorrect(node)
152
- save_loc = node.loc.selector
153
- new_method = "#{node.method_name}!"
154
-
155
- ->(corrector) { corrector.replace(save_loc, new_method) }
156
- end
157
-
158
- private
159
-
160
- def add_offense_for_node(node, msg = MSG)
161
- name = node.method_name
162
- full_message = format(msg, prefer: "#{name}!", current: name.to_s)
163
-
164
- add_offense(node, location: :selector, message: full_message)
165
- end
166
-
167
- def right_assignment_node(assignment)
168
- node = assignment.node.child_nodes.first
169
-
170
- return node unless node&.block_type?
171
-
172
- node.send_node
173
- end
174
-
175
- def persisted_referenced?(assignment)
176
- return unless assignment.referenced?
177
-
178
- assignment.variable.references.any? do |reference|
179
- call_to_persisted?(reference.node.parent)
180
- end
181
- end
182
-
183
- def call_to_persisted?(node)
184
- node.send_type? && node.method?(:persisted?)
185
- end
186
-
187
- def assignable_node(node)
188
- assignable = node.block_node || node
189
- while node
190
- node = hash_parent(node) || array_parent(node)
191
- assignable = node if node
192
- end
193
- assignable
194
- end
195
-
196
- def hash_parent(node)
197
- pair = node.parent
198
- return unless pair&.pair_type?
199
-
200
- hash = pair.parent
201
- return unless hash&.hash_type?
202
-
203
- hash
204
- end
205
-
206
- def array_parent(node)
207
- array = node.parent
208
- return unless array&.array_type?
209
-
210
- array
211
- end
212
-
213
- def check_used_in_conditional(node)
214
- return false unless conditional?(node)
215
-
216
- unless MODIFY_PERSIST_METHODS.include?(node.method_name)
217
- add_offense_for_node(node, CREATE_CONDITIONAL_MSG)
218
- end
219
-
220
- true
221
- end
222
-
223
- def conditional?(node) # rubocop:disable Metrics/CyclomaticComplexity
224
- node = node.block_node || node
225
-
226
- condition = node.parent
227
- return false unless condition
228
-
229
- condition.if_type? || condition.case_type? ||
230
- condition.or_type? || condition.and_type? ||
231
- single_negative?(condition)
232
- end
233
-
234
- def allowed_receiver?(node)
235
- return false unless node.receiver
236
- return false unless cop_config['AllowedReceivers']
237
-
238
- cop_config['AllowedReceivers'].any? do |allowed_receiver|
239
- receiver_chain_matches?(node, allowed_receiver)
240
- end
241
- end
242
-
243
- def receiver_chain_matches?(node, allowed_receiver)
244
- allowed_receiver.split('.').reverse.all? do |receiver_part|
245
- node = node.receiver
246
- return false unless node
247
-
248
- if node.variable?
249
- node.node_parts.first == receiver_part.to_sym
250
- elsif node.send_type?
251
- node.method_name == receiver_part.to_sym
252
- elsif node.const_type?
253
- const_matches?(node.const_name, receiver_part)
254
- end
255
- end
256
- end
257
-
258
- # Const == Const
259
- # ::Const == ::Const
260
- # ::Const == Const
261
- # Const == ::Const
262
- # NameSpace::Const == Const
263
- # NameSpace::Const == NameSpace::Const
264
- # NameSpace::Const != ::Const
265
- # Const != NameSpace::Const
266
- def const_matches?(const, allowed_const)
267
- parts = allowed_const.split('::').reverse.zip(
268
- const.split('::').reverse
269
- )
270
- parts.all? do |(allowed_part, const_part)|
271
- allowed_part == const_part.to_s
272
- end
273
- end
274
-
275
- def implicit_return?(node)
276
- return false unless cop_config['AllowImplicitReturn']
277
-
278
- node = assignable_node(node)
279
- method = node.parent
280
- return unless method && (method.def_type? || method.block_type?)
281
-
282
- method.children.size == node.sibling_index + 1
283
- end
284
-
285
- def argument?(node)
286
- assignable_node(node).argument?
287
- end
288
-
289
- def explicit_return?(node)
290
- ret = assignable_node(node).parent
291
- ret && (ret.return_type? || ret.next_type?)
292
- end
293
-
294
- def return_value_assigned?(node)
295
- assignment = assignable_node(node).parent
296
- assignment&.lvasgn_type?
297
- end
298
-
299
- def persist_method?(node, methods = PERSIST_METHODS)
300
- methods.include?(node.method_name) &&
301
- expected_signature?(node) &&
302
- !allowed_receiver?(node)
303
- end
304
-
305
- # Check argument signature as no arguments or one hash
306
- def expected_signature?(node)
307
- !node.arguments? ||
308
- (node.arguments.one? &&
309
- node.method_name != :destroy &&
310
- (node.first_argument.hash_type? ||
311
- !node.first_argument.literal?))
312
- end
313
- end
314
- end
315
- end
316
- end