rubocop 0.71.0 → 0.72.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -8
  3. data/config/default.yml +42 -484
  4. data/lib/rubocop.rb +5 -53
  5. data/lib/rubocop/ast/builder.rb +2 -0
  6. data/lib/rubocop/ast/node.rb +1 -1
  7. data/lib/rubocop/ast/node/float_node.rb +12 -0
  8. data/lib/rubocop/ast/node/int_node.rb +12 -0
  9. data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
  10. data/lib/rubocop/ast/node/resbody_node.rb +1 -6
  11. data/lib/rubocop/cached_data.rb +1 -1
  12. data/lib/rubocop/config.rb +34 -5
  13. data/lib/rubocop/config_loader.rb +2 -6
  14. data/lib/rubocop/config_loader_resolver.rb +0 -14
  15. data/lib/rubocop/cop/cop.rb +0 -4
  16. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
  17. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  18. data/lib/rubocop/cop/layout/indent_first_argument.rb +6 -2
  19. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  20. data/lib/rubocop/cop/layout/indent_heredoc.rb +0 -1
  21. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  22. data/lib/rubocop/cop/layout/indentation_width.rb +8 -4
  23. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  24. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -20
  25. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  26. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -1
  27. data/lib/rubocop/cop/style/float_division.rb +94 -0
  28. data/lib/rubocop/cop/style/format_string.rb +7 -3
  29. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  30. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -1
  31. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  32. data/lib/rubocop/cop/style/ternary_parentheses.rb +12 -2
  33. data/lib/rubocop/cop/style/word_array.rb +2 -2
  34. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
  35. data/lib/rubocop/options.rb +0 -2
  36. data/lib/rubocop/processed_source.rb +2 -1
  37. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  38. data/lib/rubocop/rspec/shared_contexts.rb +0 -17
  39. data/lib/rubocop/rspec/support.rb +0 -1
  40. data/lib/rubocop/runner.rb +0 -17
  41. data/lib/rubocop/version.rb +1 -1
  42. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  43. metadata +8 -91
  44. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  45. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  46. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  47. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  48. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  49. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  50. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  51. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  52. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  53. data/lib/rubocop/cop/rails/blank.rb +0 -164
  54. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  55. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  56. data/lib/rubocop/cop/rails/date.rb +0 -161
  57. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  58. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  59. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  60. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  61. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  62. data/lib/rubocop/cop/rails/exit.rb +0 -67
  63. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  64. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  65. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  66. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  67. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  68. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  69. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  70. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  71. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  72. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  73. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  74. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  75. data/lib/rubocop/cop/rails/output.rb +0 -49
  76. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  77. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  78. data/lib/rubocop/cop/rails/presence.rb +0 -124
  79. data/lib/rubocop/cop/rails/present.rb +0 -153
  80. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  81. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  82. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  83. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  84. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  85. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  86. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  87. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  88. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  89. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  90. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  91. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  92. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  93. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  94. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  95. data/lib/rubocop/cop/rails/validation.rb +0 -109
  96. data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop looks for delegations that could have been created
7
- # automatically with the `delegate` method.
8
- #
9
- # Safe navigation `&.` is ignored because Rails' `allow_nil`
10
- # option checks not just for nil but also delegates if nil
11
- # responds to the delegated method.
12
- #
13
- # The `EnforceForPrefixed` option (defaulted to `true`) means that
14
- # using the target object as a prefix of the method name
15
- # without using the `delegate` method will be a violation.
16
- # When set to `false`, this case is legal.
17
- #
18
- # @example
19
- # # bad
20
- # def bar
21
- # foo.bar
22
- # end
23
- #
24
- # # good
25
- # delegate :bar, to: :foo
26
- #
27
- # # good
28
- # def bar
29
- # foo&.bar
30
- # end
31
- #
32
- # # good
33
- # private
34
- # def bar
35
- # foo.bar
36
- # end
37
- #
38
- # @example EnforceForPrefixed: true (default)
39
- # # bad
40
- # def foo_bar
41
- # foo.bar
42
- # end
43
- #
44
- # # good
45
- # delegate :bar, to: :foo, prefix: true
46
- #
47
- # @example EnforceForPrefixed: false
48
- # # good
49
- # def foo_bar
50
- # foo.bar
51
- # end
52
- #
53
- # # good
54
- # delegate :bar, to: :foo, prefix: true
55
- class Delegate < Cop
56
- MSG = 'Use `delegate` to define delegations.'
57
-
58
- def_node_matcher :delegate?, <<-PATTERN
59
- (def _method_name _args
60
- (send (send nil? _) _ ...))
61
- PATTERN
62
-
63
- def on_def(node)
64
- return unless trivial_delegate?(node)
65
- return if private_or_protected_delegation(node)
66
-
67
- add_offense(node, location: :keyword)
68
- end
69
-
70
- def autocorrect(node)
71
- delegation = ["delegate :#{node.body.method_name}",
72
- "to: :#{node.body.receiver.method_name}"]
73
-
74
- if node.method_name == prefixed_method_name(node.body)
75
- delegation << ['prefix: true']
76
- end
77
-
78
- lambda do |corrector|
79
- corrector.replace(node.source_range, delegation.join(', '))
80
- end
81
- end
82
-
83
- private
84
-
85
- def trivial_delegate?(def_node)
86
- delegate?(def_node) &&
87
- method_name_matches?(def_node.method_name, def_node.body) &&
88
- arguments_match?(def_node.arguments, def_node.body)
89
- end
90
-
91
- def arguments_match?(arg_array, body)
92
- argument_array = body.arguments
93
-
94
- return false if arg_array.size != argument_array.size
95
-
96
- arg_array.zip(argument_array).all? do |arg, argument|
97
- arg.arg_type? &&
98
- argument.lvar_type? &&
99
- arg.children == argument.children
100
- end
101
- end
102
-
103
- def method_name_matches?(method_name, body)
104
- method_name == body.method_name ||
105
- include_prefix_case? && method_name == prefixed_method_name(body)
106
- end
107
-
108
- def include_prefix_case?
109
- cop_config['EnforceForPrefixed']
110
- end
111
-
112
- def prefixed_method_name(body)
113
- [body.receiver.method_name, body.method_name].join('_').to_sym
114
- end
115
-
116
- def private_or_protected_delegation(node)
117
- line = node.first_line
118
- private_or_protected_before(line) ||
119
- private_or_protected_inline(line)
120
- end
121
-
122
- def private_or_protected_before(line)
123
- (processed_source[0..line].map(&:strip) & %w[private protected]).any?
124
- end
125
-
126
- def private_or_protected_inline(line)
127
- processed_source[line - 1].strip =~ /\A(private )|(protected )/
128
- end
129
- end
130
- end
131
- end
132
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop looks for delegations that pass :allow_blank as an option
7
- # instead of :allow_nil. :allow_blank is not a valid option to pass
8
- # to ActiveSupport#delegate.
9
- #
10
- # @example
11
- # # bad
12
- # delegate :foo, to: :bar, allow_blank: true
13
- #
14
- # # good
15
- # delegate :foo, to: :bar, allow_nil: true
16
- class DelegateAllowBlank < Cop
17
- MSG = '`allow_blank` is not a valid option, use `allow_nil`.'
18
-
19
- def_node_matcher :allow_blank_option, <<-PATTERN
20
- (send nil? :delegate _ (hash <$(pair (sym :allow_blank) true) ...>))
21
- PATTERN
22
-
23
- def on_send(node)
24
- allow_blank_option(node) do |offending_node|
25
- add_offense(offending_node)
26
- end
27
- end
28
-
29
- def autocorrect(pair_node)
30
- lambda do |corrector|
31
- corrector.replace(pair_node.key.source_range, 'allow_nil')
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop checks dynamic `find_by_*` methods.
7
- # Use `find_by` instead of dynamic method.
8
- # See. https://github.com/rubocop-hq/rails-style-guide#find_by
9
- #
10
- # @example
11
- # # bad
12
- # User.find_by_name(name)
13
- #
14
- # # bad
15
- # User.find_by_name_and_email(name)
16
- #
17
- # # bad
18
- # User.find_by_email!(name)
19
- #
20
- # # good
21
- # User.find_by(name: name)
22
- #
23
- # # good
24
- # User.find_by(name: name, email: email)
25
- #
26
- # # good
27
- # User.find_by!(email: email)
28
- class DynamicFindBy < Cop
29
- MSG = 'Use `%<static_name>s` instead of dynamic `%<method>s`.'
30
- METHOD_PATTERN = /^find_by_(.+?)(!)?$/.freeze
31
-
32
- def on_send(node)
33
- method_name = node.method_name.to_s
34
-
35
- return if whitelist.include?(method_name)
36
-
37
- static_name = static_method_name(method_name)
38
-
39
- return unless static_name
40
-
41
- add_offense(node,
42
- message: format(MSG, static_name: static_name,
43
- method: node.method_name))
44
- end
45
- alias on_csend on_send
46
-
47
- def autocorrect(node)
48
- keywords = column_keywords(node.method_name)
49
-
50
- return if keywords.size != node.arguments.size
51
-
52
- lambda do |corrector|
53
- autocorrect_method_name(corrector, node)
54
- autocorrect_argument_keywords(corrector, node, keywords)
55
- end
56
- end
57
-
58
- private
59
-
60
- def autocorrect_method_name(corrector, node)
61
- corrector.replace(node.loc.selector,
62
- static_method_name(node.method_name.to_s))
63
- end
64
-
65
- def autocorrect_argument_keywords(corrector, node, keywords)
66
- keywords.each.with_index do |keyword, idx|
67
- corrector.insert_before(node.arguments[idx].loc.expression, keyword)
68
- end
69
- end
70
-
71
- def whitelist
72
- cop_config['Whitelist']
73
- end
74
-
75
- def column_keywords(method)
76
- keyword_string = method.to_s[METHOD_PATTERN, 1]
77
- keyword_string.split('_and_').map { |keyword| "#{keyword}: " }
78
- end
79
-
80
- # Returns static method name.
81
- # If code isn't wrong, returns nil
82
- def static_method_name(method_name)
83
- match = METHOD_PATTERN.match(method_name)
84
- return nil unless match
85
-
86
- match[2] ? 'find_by!' : 'find_by'
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop looks for duplicate values in enum declarations.
7
- #
8
- # @example
9
- # # bad
10
- # enum status: { active: 0, archived: 0 }
11
- #
12
- # # good
13
- # enum status: { active: 0, archived: 1 }
14
- #
15
- # # bad
16
- # enum status: [:active, :archived, :active]
17
- #
18
- # # good
19
- # enum status: [:active, :archived]
20
- class EnumUniqueness < Cop
21
- include Duplication
22
-
23
- MSG = 'Duplicate value `%<value>s` found in `%<enum>s` ' \
24
- 'enum declaration.'
25
-
26
- def_node_matcher :enum_declaration, <<-PATTERN
27
- (send nil? :enum (hash (pair (_ $_) ${array hash})))
28
- PATTERN
29
-
30
- def on_send(node)
31
- enum_declaration(node) do |name, args|
32
- items = args.values
33
-
34
- return unless duplicates?(items)
35
-
36
- consecutive_duplicates(items).each do |item|
37
- add_offense(item, message: format(MSG, value: item.source,
38
- enum: name))
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop checks that Rails.env is compared using `.production?`-like
7
- # methods instead of equality against a string or symbol.
8
- #
9
- # @example
10
- # # bad
11
- # Rails.env == 'production'
12
- #
13
- # # bad, always returns false
14
- # Rails.env == :test
15
- #
16
- # # good
17
- # Rails.env.production?
18
- class EnvironmentComparison < Cop
19
- MSG = "Favor `Rails.env.%<env>s?` over `Rails.env == '%<env>s'`."
20
-
21
- SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always ' \
22
- 'evaluate to `false`.'
23
-
24
- def_node_matcher :environment_str_comparison?, <<-PATTERN
25
- (send
26
- (send (const {nil? cbase} :Rails) :env)
27
- :==
28
- $str
29
- )
30
- PATTERN
31
-
32
- def_node_matcher :environment_sym_comparison?, <<-PATTERN
33
- (send
34
- (send (const {nil? cbase} :Rails) :env)
35
- :==
36
- $sym
37
- )
38
- PATTERN
39
-
40
- def on_send(node)
41
- environment_str_comparison?(node) do |env_node|
42
- env, = *env_node
43
- add_offense(node, message: format(MSG, env: env))
44
- end
45
- environment_sym_comparison?(node) do |_|
46
- add_offense(node, message: SYM_MSG)
47
- end
48
- end
49
-
50
- def autocorrect(node)
51
- lambda do |corrector|
52
- corrector.replace(node.source_range, replacement(node))
53
- end
54
- end
55
-
56
- private
57
-
58
- def replacement(node)
59
- "#{node.receiver.source}.#{content(node.first_argument)}?"
60
- end
61
-
62
- def_node_matcher :content, <<-PATTERN
63
- ({str sym} $_)
64
- PATTERN
65
- end
66
- end
67
- end
68
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop enforces that `exit` calls are not used within a rails app.
7
- # Valid options are instead to raise an error, break, return, or some
8
- # other form of stopping execution of current request.
9
- #
10
- # There are two obvious cases where `exit` is particularly harmful:
11
- #
12
- # - Usage in library code for your application. Even though Rails will
13
- # rescue from a `SystemExit` and continue on, unit testing that library
14
- # code will result in specs exiting (potentially silently if `exit(0)`
15
- # is used.)
16
- # - Usage in application code outside of the web process could result in
17
- # the program exiting, which could result in the code failing to run and
18
- # do its job.
19
- #
20
- # @example
21
- # # bad
22
- # exit(0)
23
- #
24
- # # good
25
- # raise 'a bad error has happened'
26
- class Exit < Cop
27
- include ConfigurableEnforcedStyle
28
-
29
- MSG = 'Do not use `exit` in Rails applications.'
30
- TARGET_METHODS = %i[exit exit!].freeze
31
- EXPLICIT_RECEIVERS = %i[Kernel Process].freeze
32
-
33
- def on_send(node)
34
- add_offense(node, location: :selector) if offending_node?(node)
35
- end
36
-
37
- private
38
-
39
- def offending_node?(node)
40
- right_method_name?(node.method_name) &&
41
- right_argument_count?(node.arguments) &&
42
- right_receiver?(node.receiver)
43
- end
44
-
45
- def right_method_name?(method_name)
46
- TARGET_METHODS.include?(method_name)
47
- end
48
-
49
- # More than 1 argument likely means it is a different
50
- # `exit` implementation than the one we are preventing.
51
- def right_argument_count?(arg_nodes)
52
- arg_nodes.size <= 1
53
- end
54
-
55
- # Only register if exit is being called explicitly on `Kernel`,
56
- # `Process`, or if receiver node is nil for plain `exit` calls.
57
- def right_receiver?(receiver_node)
58
- return true unless receiver_node
59
-
60
- _a, receiver_node_class, _c = *receiver_node
61
-
62
- EXPLICIT_RECEIVERS.include?(receiver_node_class)
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,108 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop is used to identify usages of file path joining process
7
- # to use `Rails.root.join` clause. It is used to add uniformity when
8
- # joining paths.
9
- #
10
- # @example EnforcedStyle: arguments (default)
11
- # # bad
12
- # Rails.root.join('app/models/goober')
13
- # File.join(Rails.root, 'app/models/goober')
14
- # "#{Rails.root}/app/models/goober"
15
- #
16
- # # good
17
- # Rails.root.join('app', 'models', 'goober')
18
- #
19
- # @example EnforcedStyle: slashes
20
- # # bad
21
- # Rails.root.join('app', 'models', 'goober')
22
- # File.join(Rails.root, 'app/models/goober')
23
- # "#{Rails.root}/app/models/goober"
24
- #
25
- # # good
26
- # Rails.root.join('app/models/goober')
27
- #
28
- class FilePath < Cop
29
- include ConfigurableEnforcedStyle
30
- include RangeHelp
31
-
32
- MSG_SLASHES = 'Please use `Rails.root.join(\'path/to\')` ' \
33
- 'instead.'
34
- MSG_ARGUMENTS = 'Please use `Rails.root.join(\'path\', \'to\')` ' \
35
- 'instead.'
36
-
37
- def_node_matcher :file_join_nodes?, <<-PATTERN
38
- (send (const nil? :File) :join ...)
39
- PATTERN
40
-
41
- def_node_search :rails_root_nodes?, <<-PATTERN
42
- (send (const nil? :Rails) :root)
43
- PATTERN
44
-
45
- def_node_matcher :rails_root_join_nodes?, <<-PATTERN
46
- (send (send (const nil? :Rails) :root) :join ...)
47
- PATTERN
48
-
49
- def on_dstr(node)
50
- return unless rails_root_nodes?(node)
51
- return unless node.children.last.source.start_with?('.') ||
52
- node.children.last.source.include?(File::SEPARATOR)
53
-
54
- register_offense(node)
55
- end
56
-
57
- def on_send(node)
58
- check_for_file_join_with_rails_root(node)
59
- check_for_rails_root_join_with_slash_separated_path(node)
60
- check_for_rails_root_join_with_string_arguments(node)
61
- end
62
-
63
- private
64
-
65
- def check_for_file_join_with_rails_root(node)
66
- return unless file_join_nodes?(node)
67
- return unless node.arguments.any? { |e| rails_root_nodes?(e) }
68
-
69
- register_offense(node)
70
- end
71
-
72
- def check_for_rails_root_join_with_string_arguments(node)
73
- return unless style == :slashes
74
- return unless rails_root_nodes?(node)
75
- return unless rails_root_join_nodes?(node)
76
- return unless node.arguments.size > 1
77
- return unless node.arguments.all?(&:str_type?)
78
-
79
- register_offense(node)
80
- end
81
-
82
- def check_for_rails_root_join_with_slash_separated_path(node)
83
- return unless style == :arguments
84
- return unless rails_root_nodes?(node)
85
- return unless rails_root_join_nodes?(node)
86
- return unless node.arguments.any? { |arg| string_with_slash?(arg) }
87
-
88
- register_offense(node)
89
- end
90
-
91
- def string_with_slash?(node)
92
- node.str_type? && node.source =~ %r{/}
93
- end
94
-
95
- def register_offense(node)
96
- line_range = node.loc.column...node.loc.last_column
97
- source_range = source_range(processed_source.buffer, node.first_line,
98
- line_range)
99
- add_offense(node, location: source_range)
100
- end
101
-
102
- def message(_node)
103
- format(style == :arguments ? MSG_ARGUMENTS : MSG_SLASHES)
104
- end
105
- end
106
- end
107
- end
108
- end