rubocop 0.70.0 → 0.72.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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -10
  3. data/config/default.yml +50 -491
  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 +35 -6
  13. data/lib/rubocop/config_loader.rb +2 -2
  14. data/lib/rubocop/config_loader_resolver.rb +0 -6
  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/empty_lines_around_block_body.rb +3 -1
  19. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -0
  20. data/lib/rubocop/cop/layout/indent_first_argument.rb +6 -2
  21. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  22. data/lib/rubocop/cop/layout/indent_heredoc.rb +0 -1
  23. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  24. data/lib/rubocop/cop/layout/indentation_width.rb +8 -4
  25. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +2 -0
  26. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  27. data/lib/rubocop/cop/mixin/hash_alignment.rb +4 -0
  28. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +20 -22
  29. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  30. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -1
  31. data/lib/rubocop/cop/style/float_division.rb +94 -0
  32. data/lib/rubocop/cop/style/format_string.rb +7 -3
  33. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  34. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -1
  35. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  36. data/lib/rubocop/cop/style/ternary_parentheses.rb +12 -2
  37. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -0
  38. data/lib/rubocop/cop/style/word_array.rb +2 -2
  39. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
  40. data/lib/rubocop/node_pattern.rb +84 -5
  41. data/lib/rubocop/options.rb +0 -2
  42. data/lib/rubocop/processed_source.rb +5 -1
  43. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  44. data/lib/rubocop/rspec/shared_contexts.rb +0 -17
  45. data/lib/rubocop/rspec/support.rb +0 -1
  46. data/lib/rubocop/runner.rb +6 -7
  47. data/lib/rubocop/version.rb +1 -1
  48. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  49. metadata +7 -69
  50. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  51. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  52. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  53. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  54. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  55. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  56. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  57. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  58. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  59. data/lib/rubocop/cop/rails/blank.rb +0 -164
  60. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  61. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  62. data/lib/rubocop/cop/rails/date.rb +0 -161
  63. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  64. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  65. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  66. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  67. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  68. data/lib/rubocop/cop/rails/exit.rb +0 -67
  69. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  70. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  71. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  72. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  73. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  74. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  75. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  76. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  77. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  78. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  79. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  80. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  81. data/lib/rubocop/cop/rails/output.rb +0 -49
  82. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  83. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  84. data/lib/rubocop/cop/rails/presence.rb +0 -124
  85. data/lib/rubocop/cop/rails/present.rb +0 -153
  86. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  87. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  88. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  89. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  90. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  91. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  92. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  93. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  94. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  95. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  96. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  97. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  98. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  99. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  100. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  101. data/lib/rubocop/cop/rails/validation.rb +0 -109
  102. 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