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,55 +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 `where.first` and
7
- # change them to use `find_by` instead.
8
- #
9
- # @example
10
- # # bad
11
- # User.where(name: 'Bruce').first
12
- # User.where(name: 'Bruce').take
13
- #
14
- # # good
15
- # User.find_by(name: 'Bruce')
16
- class FindBy < Cop
17
- include RangeHelp
18
-
19
- MSG = 'Use `find_by` instead of `where.%<method>s`.'
20
- TARGET_SELECTORS = %i[first take].freeze
21
-
22
- def_node_matcher :where_first?, <<-PATTERN
23
- (send ({send csend} _ :where ...) {:first :take})
24
- PATTERN
25
-
26
- def on_send(node)
27
- return unless where_first?(node)
28
-
29
- range = range_between(node.receiver.loc.selector.begin_pos,
30
- node.loc.selector.end_pos)
31
-
32
- add_offense(node, location: range,
33
- message: format(MSG, method: node.method_name))
34
- end
35
- alias on_csend on_send
36
-
37
- def autocorrect(node)
38
- # Don't autocorrect where(...).first, because it can return different
39
- # results from find_by. (They order records differently, so the
40
- # 'first' record can be different.)
41
- return if node.method?(:first)
42
-
43
- where_loc = node.receiver.loc.selector
44
- first_loc = range_between(node.loc.dot.begin_pos,
45
- node.loc.selector.end_pos)
46
-
47
- lambda do |corrector|
48
- corrector.replace(where_loc, 'find_by')
49
- corrector.replace(first_loc, '')
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,51 +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 `all.each` and
7
- # change them to use `all.find_each` instead.
8
- #
9
- # @example
10
- # # bad
11
- # User.all.each
12
- #
13
- # # good
14
- # User.all.find_each
15
- class FindEach < Cop
16
- MSG = 'Use `find_each` instead of `each`.'
17
-
18
- SCOPE_METHODS = %i[
19
- all eager_load includes joins left_joins left_outer_joins not preload
20
- references unscoped where
21
- ].freeze
22
- IGNORED_METHODS = %i[order limit select].freeze
23
-
24
- def on_send(node)
25
- return unless node.receiver&.send_type? &&
26
- node.method?(:each)
27
-
28
- return unless SCOPE_METHODS.include?(node.receiver.method_name)
29
- return if method_chain(node).any? { |m| ignored_by_find_each?(m) }
30
-
31
- add_offense(node, location: :selector)
32
- end
33
-
34
- def autocorrect(node)
35
- ->(corrector) { corrector.replace(node.loc.selector, 'find_each') }
36
- end
37
-
38
- private
39
-
40
- def method_chain(node)
41
- node.each_node(:send).map(&:method_name)
42
- end
43
-
44
- def ignored_by_find_each?(relation_method)
45
- # Active Record's #find_each ignores various extra parameters
46
- IGNORED_METHODS.include?(relation_method)
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop checks for the use of the has_and_belongs_to_many macro.
7
- #
8
- # @example
9
- # # bad
10
- # # has_and_belongs_to_many :ingredients
11
- #
12
- # # good
13
- # # has_many :ingredients, through: :recipe_ingredients
14
- class HasAndBelongsToMany < Cop
15
- MSG = 'Prefer `has_many :through` to `has_and_belongs_to_many`.'
16
-
17
- def on_send(node)
18
- return unless node.command?(:has_and_belongs_to_many)
19
-
20
- add_offense(node, location: :selector)
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # This cop looks for `has_many` or `has_one` associations that don't
7
- # specify a `:dependent` option.
8
- # It doesn't register an offense if `:through` option was specified.
9
- #
10
- # @example
11
- # # bad
12
- # class User < ActiveRecord::Base
13
- # has_many :comments
14
- # has_one :avatar
15
- # end
16
- #
17
- # # good
18
- # class User < ActiveRecord::Base
19
- # has_many :comments, dependent: :restrict_with_exception
20
- # has_one :avatar, dependent: :destroy
21
- # has_many :patients, through: :appointments
22
- # end
23
- class HasManyOrHasOneDependent < Cop
24
- MSG = 'Specify a `:dependent` option.'
25
-
26
- def_node_search :active_resource_class?, <<-PATTERN
27
- (const (const nil? :ActiveResource) :Base)
28
- PATTERN
29
-
30
- def_node_matcher :association_without_options?, <<-PATTERN
31
- (send nil? {:has_many :has_one} _)
32
- PATTERN
33
-
34
- def_node_matcher :association_with_options?, <<-PATTERN
35
- (send nil? {:has_many :has_one} _ (hash $...))
36
- PATTERN
37
-
38
- def_node_matcher :dependent_option?, <<-PATTERN
39
- (pair (sym :dependent) !nil)
40
- PATTERN
41
-
42
- def_node_matcher :present_option?, <<-PATTERN
43
- (pair (sym :through) !nil)
44
- PATTERN
45
-
46
- def_node_matcher :with_options_block, <<-PATTERN
47
- (block
48
- (send nil? :with_options
49
- (hash $...))
50
- (args) ...)
51
- PATTERN
52
-
53
- def on_send(node)
54
- return if active_resource?(node.parent)
55
-
56
- unless association_without_options?(node)
57
- return if valid_options?(association_with_options?(node))
58
- end
59
-
60
- return if valid_options_in_with_options_block?(node)
61
-
62
- add_offense(node, location: :selector)
63
- end
64
-
65
- private
66
-
67
- def valid_options_in_with_options_block?(node)
68
- return true unless node.parent
69
-
70
- n = node.parent.begin_type? ? node.parent.parent : node.parent
71
-
72
- contain_valid_options_in_with_options_block?(n)
73
- end
74
-
75
- def contain_valid_options_in_with_options_block?(node)
76
- if with_options_block(node)
77
- return true if valid_options?(with_options_block(node))
78
-
79
- return false unless node.parent
80
-
81
- return true if contain_valid_options_in_with_options_block?(
82
- node.parent.parent
83
- )
84
- end
85
-
86
- false
87
- end
88
-
89
- def valid_options?(options)
90
- return true unless options
91
- return true if options.any? do |o|
92
- dependent_option?(o) || present_option?(o)
93
- end
94
-
95
- false
96
- end
97
-
98
- def active_resource?(node)
99
- return false if node.nil?
100
-
101
- active_resource_class?(node)
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,117 +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 http methods like `get`, `post`,
7
- # `put`, `patch` without the usage of keyword arguments in your tests and
8
- # change them to use keyword args. This cop only applies to Rails >= 5.
9
- # If you are running Rails < 5 you should disable the
10
- # Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your
11
- # .rubocop.yml file to 4.0, etc.
12
- #
13
- # @example
14
- # # bad
15
- # get :new, { user_id: 1}
16
- #
17
- # # good
18
- # get :new, params: { user_id: 1 }
19
- class HttpPositionalArguments < Cop
20
- extend TargetRailsVersion
21
-
22
- MSG = 'Use keyword arguments instead of ' \
23
- 'positional arguments for http call: `%<verb>s`.'
24
- KEYWORD_ARGS = %i[
25
- method params session body flash xhr as headers env
26
- ].freeze
27
- HTTP_METHODS = %i[get post put patch delete head].freeze
28
-
29
- minimum_target_rails_version 5.0
30
-
31
- def_node_matcher :http_request?, <<-PATTERN
32
- (send nil? {#{HTTP_METHODS.map(&:inspect).join(' ')}} !nil? $_ ...)
33
- PATTERN
34
-
35
- def on_send(node)
36
- http_request?(node) do |data|
37
- return unless needs_conversion?(data)
38
-
39
- add_offense(node, location: :selector,
40
- message: format(MSG, verb: node.method_name))
41
- end
42
- end
43
-
44
- # given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
45
- #
46
- # @return lambda of auto correct procedure
47
- # the result should look like:
48
- # get :new, params: { user_id: @user.id }, session: {}
49
- # the http_method is the method used to call the controller
50
- # the controller node can be a symbol, method, object or string
51
- # that represents the path/action on the Rails controller
52
- # the data is the http parameters and environment sent in
53
- # the Rails 5 http call
54
- def autocorrect(node)
55
- lambda do |corrector|
56
- corrector.replace(node.loc.expression, correction(node))
57
- end
58
- end
59
-
60
- private
61
-
62
- def needs_conversion?(data)
63
- return true unless data.hash_type?
64
-
65
- data.each_pair.none? do |pair|
66
- special_keyword_arg?(pair.key) ||
67
- format_arg?(pair.key) && data.pairs.one?
68
- end
69
- end
70
-
71
- def special_keyword_arg?(node)
72
- node.sym_type? && KEYWORD_ARGS.include?(node.value)
73
- end
74
-
75
- def format_arg?(node)
76
- node.sym_type? && node.value == :format
77
- end
78
-
79
- def convert_hash_data(data, type)
80
- return '' if data.hash_type? && data.empty?
81
-
82
- hash_data = if data.hash_type?
83
- format('{ %<data>s }',
84
- data: data.pairs.map(&:source).join(', '))
85
- else
86
- # user supplies an object,
87
- # no need to surround with braces
88
- data.source
89
- end
90
-
91
- format(', %<type>s: %<hash_data>s', type: type, hash_data: hash_data)
92
- end
93
-
94
- def correction(node)
95
- http_path, *data = *node.arguments
96
-
97
- controller_action = http_path.source
98
- params = convert_hash_data(data.first, 'params')
99
- session = convert_hash_data(data.last, 'session') if data.size > 1
100
-
101
- format(correction_template(node), name: node.method_name,
102
- action: controller_action,
103
- params: params,
104
- session: session)
105
- end
106
-
107
- def correction_template(node)
108
- if parentheses?(node)
109
- '%<name>s(%<action>s%<params>s%<session>s)'
110
- else
111
- '%<name>s %<action>s%<params>s%<session>s'
112
- end
113
- end
114
- end
115
- end
116
- end
117
- end
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Rails
6
- # Enforces use of symbolic or numeric value to define HTTP status.
7
- #
8
- # @example EnforcedStyle: symbolic (default)
9
- # # bad
10
- # render :foo, status: 200
11
- # render json: { foo: 'bar' }, status: 200
12
- # render plain: 'foo/bar', status: 304
13
- # redirect_to root_url, status: 301
14
- #
15
- # # good
16
- # render :foo, status: :ok
17
- # render json: { foo: 'bar' }, status: :ok
18
- # render plain: 'foo/bar', status: :not_modified
19
- # redirect_to root_url, status: :moved_permanently
20
- #
21
- # @example EnforcedStyle: numeric
22
- # # bad
23
- # render :foo, status: :ok
24
- # render json: { foo: 'bar' }, status: :not_found
25
- # render plain: 'foo/bar', status: :not_modified
26
- # redirect_to root_url, status: :moved_permanently
27
- #
28
- # # good
29
- # render :foo, status: 200
30
- # render json: { foo: 'bar' }, status: 404
31
- # render plain: 'foo/bar', status: 304
32
- # redirect_to root_url, status: 301
33
- #
34
- class HttpStatus < Cop
35
- begin
36
- require 'rack/utils'
37
- RACK_LOADED = true
38
- rescue LoadError
39
- RACK_LOADED = false
40
- end
41
-
42
- include ConfigurableEnforcedStyle
43
-
44
- def_node_matcher :http_status, <<-PATTERN
45
- {
46
- (send nil? {:render :redirect_to} _ $hash)
47
- (send nil? {:render :redirect_to} $hash)
48
- }
49
- PATTERN
50
-
51
- def_node_matcher :status_code, <<-PATTERN
52
- (hash <(pair (sym :status) ${int sym}) ...>)
53
- PATTERN
54
-
55
- def on_send(node)
56
- http_status(node) do |hash_node|
57
- status = status_code(hash_node)
58
- return unless status
59
-
60
- checker = checker_class.new(status)
61
- return unless checker.offensive?
62
-
63
- add_offense(checker.node, message: checker.message)
64
- end
65
- end
66
-
67
- def support_autocorrect?
68
- RACK_LOADED
69
- end
70
-
71
- def autocorrect(node)
72
- lambda do |corrector|
73
- checker = checker_class.new(node)
74
- corrector.replace(node.loc.expression, checker.preferred_style)
75
- end
76
- end
77
-
78
- private
79
-
80
- def checker_class
81
- case style
82
- when :symbolic
83
- SymbolicStyleChecker
84
- when :numeric
85
- NumericStyleChecker
86
- end
87
- end
88
-
89
- # :nodoc:
90
- class SymbolicStyleChecker
91
- MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
92
- 'to define HTTP status code.'
93
- DEFAULT_MSG = 'Prefer `symbolic` over `numeric` ' \
94
- 'to define HTTP status code.'
95
-
96
- attr_reader :node
97
- def initialize(node)
98
- @node = node
99
- end
100
-
101
- def offensive?
102
- !node.sym_type? && !custom_http_status_code?
103
- end
104
-
105
- def message
106
- if RACK_LOADED
107
- format(MSG, prefer: preferred_style, current: number.to_s)
108
- else
109
- DEFAULT_MSG
110
- end
111
- end
112
-
113
- def preferred_style
114
- symbol.inspect
115
- end
116
-
117
- private
118
-
119
- def symbol
120
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
121
- end
122
-
123
- def number
124
- node.children.first
125
- end
126
-
127
- def custom_http_status_code?
128
- node.int_type? &&
129
- !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(number)
130
- end
131
- end
132
-
133
- # :nodoc:
134
- class NumericStyleChecker
135
- MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
136
- 'to define HTTP status code.'
137
- DEFAULT_MSG = 'Prefer `numeric` over `symbolic` ' \
138
- 'to define HTTP status code.'
139
- PERMITTED_STATUS = %i[error success missing redirect].freeze
140
-
141
- attr_reader :node
142
- def initialize(node)
143
- @node = node
144
- end
145
-
146
- def offensive?
147
- !node.int_type? && !permitted_symbol?
148
- end
149
-
150
- def message
151
- if RACK_LOADED
152
- format(MSG, prefer: preferred_style, current: symbol.inspect)
153
- else
154
- DEFAULT_MSG
155
- end
156
- end
157
-
158
- def preferred_style
159
- number.to_s
160
- end
161
-
162
- private
163
-
164
- def number
165
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol]
166
- end
167
-
168
- def symbol
169
- node.value
170
- end
171
-
172
- def permitted_symbol?
173
- node.sym_type? && PERMITTED_STATUS.include?(node.value)
174
- end
175
- end
176
- end
177
- end
178
- end
179
- end