rubocop-rails 2.21.2 → 2.22.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/config/default.yml +10 -2
- data/lib/rubocop/cop/mixin/database_type_resolvable.rb +66 -0
- data/lib/rubocop/cop/rails/action_filter.rb +3 -0
- data/lib/rubocop/cop/rails/bulk_change_table.rb +3 -53
- data/lib/rubocop/cop/rails/dangerous_column_names.rb +9 -1
- data/lib/rubocop/cop/rails/duplicate_association.rb +66 -12
- data/lib/rubocop/cop/rails/env_local.rb +46 -0
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
- data/lib/rubocop/cop/rails/not_null_column.rb +13 -3
- data/lib/rubocop/cop/rails/output.rb +3 -2
- data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +40 -1
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +7 -0
- data/lib/rubocop/cop/rails/save_bang.rb +7 -2
- data/lib/rubocop/cop/rails/unknown_env.rb +5 -1
- data/lib/rubocop/cop/rails_cops.rb +2 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4d08f111893c16ea5c725b8da3b488a85d193366cdec6c876e780e794d66ba3
|
4
|
+
data.tar.gz: 40bd526fbf58ea8b3b45ab82ff5b7f809dcf29c7377991023fb30157dc66cc0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6dd91e7f4068bba386e8b66ce86ec18961bc6e346d000947220af3fccdaf076907a11d7367786702124370aa070aacadba96bde0c200303ad64eaf1b5de6f8d5
|
7
|
+
data.tar.gz: 783d1a9013524550b3bbd2271f3d244b13565038b1f0e73b7726565a6ea79e6e409b19f748e043fd7d850c623ea3f56c831f81f7d5bafd2cbd5e08d4181b1172
|
data/README.md
CHANGED
@@ -56,6 +56,8 @@ Note: `--rails` option is required while `rubocop` command supports `--rails` op
|
|
56
56
|
### Rake task
|
57
57
|
|
58
58
|
```ruby
|
59
|
+
require 'rubocop/rake_task'
|
60
|
+
|
59
61
|
RuboCop::RakeTask.new do |task|
|
60
62
|
task.requires << 'rubocop-rails'
|
61
63
|
end
|
@@ -80,7 +82,7 @@ module YourCoolApp
|
|
80
82
|
end
|
81
83
|
```
|
82
84
|
|
83
|
-
It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsafe
|
85
|
+
It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsafe autocorrection cops.
|
84
86
|
`rubocop -A` is unsafe autocorrection, but code generated by default is simple and less likely to
|
85
87
|
be incompatible with `rubocop -A`. If you have problems you can replace it with `rubocop -a` instead.
|
86
88
|
|
data/config/default.yml
CHANGED
@@ -95,8 +95,9 @@ Rails/ActionControllerTestCase:
|
|
95
95
|
|
96
96
|
Rails/ActionFilter:
|
97
97
|
Description: 'Enforces consistent use of action filter methods.'
|
98
|
-
Enabled:
|
98
|
+
Enabled: false
|
99
99
|
VersionAdded: '0.19'
|
100
|
+
VersionChanged: '2.22'
|
100
101
|
EnforcedStyle: action
|
101
102
|
SupportedStyles:
|
102
103
|
- action
|
@@ -338,7 +339,6 @@ Rails/Date:
|
|
338
339
|
|
339
340
|
Rails/DefaultScope:
|
340
341
|
Description: 'Avoid use of `default_scope`.'
|
341
|
-
StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
|
342
342
|
Enabled: false
|
343
343
|
VersionAdded: '2.7'
|
344
344
|
|
@@ -430,6 +430,11 @@ Rails/EnumUniqueness:
|
|
430
430
|
Include:
|
431
431
|
- app/models/**/*.rb
|
432
432
|
|
433
|
+
Rails/EnvLocal:
|
434
|
+
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
|
435
|
+
Enabled: pending
|
436
|
+
VersionAdded: '2.22'
|
437
|
+
|
433
438
|
Rails/EnvironmentComparison:
|
434
439
|
Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
|
435
440
|
Enabled: true
|
@@ -690,6 +695,9 @@ Rails/NotNullColumn:
|
|
690
695
|
Enabled: true
|
691
696
|
VersionAdded: '0.43'
|
692
697
|
VersionChanged: '2.20'
|
698
|
+
Database: null
|
699
|
+
SupportedDatabases:
|
700
|
+
- mysql
|
693
701
|
Include:
|
694
702
|
- db/**/*.rb
|
695
703
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# A mixin to extend cops in order to determine the database type.
|
6
|
+
#
|
7
|
+
# This module automatically detect an adapter from `development` environment
|
8
|
+
# in `config/database.yml` or the environment variable `DATABASE_URL`
|
9
|
+
# when the `Database` option is not set.
|
10
|
+
module DatabaseTypeResolvable
|
11
|
+
MYSQL = 'mysql'
|
12
|
+
POSTGRESQL = 'postgresql'
|
13
|
+
|
14
|
+
def database
|
15
|
+
cop_config['Database'] || database_from_yaml || database_from_env
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def database_from_yaml
|
21
|
+
return unless database_yaml
|
22
|
+
|
23
|
+
case database_adapter
|
24
|
+
when 'mysql2', 'trilogy'
|
25
|
+
MYSQL
|
26
|
+
when 'postgresql'
|
27
|
+
POSTGRESQL
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def database_from_env
|
32
|
+
url = ENV['DATABASE_URL'].presence
|
33
|
+
return unless url
|
34
|
+
|
35
|
+
case url
|
36
|
+
when %r{\A(mysql2|trilogy)://}
|
37
|
+
MYSQL
|
38
|
+
when %r{\Apostgres(ql)?://}
|
39
|
+
POSTGRESQL
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def database_yaml
|
44
|
+
return unless File.exist?('config/database.yml')
|
45
|
+
|
46
|
+
yaml = if YAML.respond_to?(:unsafe_load_file)
|
47
|
+
YAML.unsafe_load_file('config/database.yml')
|
48
|
+
else
|
49
|
+
YAML.load_file('config/database.yml')
|
50
|
+
end
|
51
|
+
return unless yaml.is_a? Hash
|
52
|
+
|
53
|
+
config = yaml['development']
|
54
|
+
return unless config.is_a?(Hash)
|
55
|
+
|
56
|
+
config
|
57
|
+
rescue Psych::SyntaxError
|
58
|
+
# noop
|
59
|
+
end
|
60
|
+
|
61
|
+
def database_adapter
|
62
|
+
database_yaml['adapter'] || database_yaml.first.last['adapter']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
8
8
|
# The cop is configurable and can enforce the use of the older
|
9
9
|
# something_filter methods or the newer something_action methods.
|
10
10
|
#
|
11
|
+
# IMPORTANT: This cop is deprecated. Because the `*_filter` methods were removed in Rails 4.2,
|
12
|
+
# and that Rails version is no longer supported by RuboCop Rails. This cop will be removed in RuboCop Rails 3.0.
|
13
|
+
#
|
11
14
|
# @example EnforcedStyle: action (default)
|
12
15
|
# # bad
|
13
16
|
# after_filter :do_stuff
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
14
14
|
# automatically detect an adapter from `development` environment
|
15
15
|
# in `config/database.yml` or the environment variable `DATABASE_URL`
|
16
16
|
# when the `Database` option is not set.
|
17
|
-
# If the adapter is not `mysql2` or `postgresql`,
|
17
|
+
# If the adapter is not `mysql2`, `trilogy`, or `postgresql`,
|
18
18
|
# this Cop ignores offenses.
|
19
19
|
#
|
20
20
|
# @example
|
@@ -64,6 +64,8 @@ module RuboCop
|
|
64
64
|
# end
|
65
65
|
# end
|
66
66
|
class BulkChangeTable < Base
|
67
|
+
include DatabaseTypeResolvable
|
68
|
+
|
67
69
|
MSG_FOR_CHANGE_TABLE = <<~MSG.chomp
|
68
70
|
You can combine alter queries using `bulk: true` options.
|
69
71
|
MSG
|
@@ -71,9 +73,6 @@ module RuboCop
|
|
71
73
|
You can use `change_table :%<table>s, bulk: true` to combine alter queries.
|
72
74
|
MSG
|
73
75
|
|
74
|
-
MYSQL = 'mysql'
|
75
|
-
POSTGRESQL = 'postgresql'
|
76
|
-
|
77
76
|
MIGRATION_METHODS = %i[change up down].freeze
|
78
77
|
|
79
78
|
COMBINABLE_TRANSFORMATIONS = %i[
|
@@ -175,55 +174,6 @@ module RuboCop
|
|
175
174
|
options.hash_type? && options.keys.any? { |key| key.sym_type? && key.value == :bulk }
|
176
175
|
end
|
177
176
|
|
178
|
-
def database
|
179
|
-
cop_config['Database'] || database_from_yaml || database_from_env
|
180
|
-
end
|
181
|
-
|
182
|
-
def database_from_yaml
|
183
|
-
return nil unless database_yaml
|
184
|
-
|
185
|
-
case database_adapter
|
186
|
-
when 'mysql2'
|
187
|
-
MYSQL
|
188
|
-
when 'postgresql'
|
189
|
-
POSTGRESQL
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def database_adapter
|
194
|
-
database_yaml['adapter'] || database_yaml.first.last['adapter']
|
195
|
-
end
|
196
|
-
|
197
|
-
def database_yaml
|
198
|
-
return nil unless File.exist?('config/database.yml')
|
199
|
-
|
200
|
-
yaml = if YAML.respond_to?(:unsafe_load_file)
|
201
|
-
YAML.unsafe_load_file('config/database.yml')
|
202
|
-
else
|
203
|
-
YAML.load_file('config/database.yml')
|
204
|
-
end
|
205
|
-
return nil unless yaml.is_a? Hash
|
206
|
-
|
207
|
-
config = yaml['development']
|
208
|
-
return nil unless config.is_a?(Hash)
|
209
|
-
|
210
|
-
config
|
211
|
-
rescue Psych::SyntaxError
|
212
|
-
nil
|
213
|
-
end
|
214
|
-
|
215
|
-
def database_from_env
|
216
|
-
url = ENV['DATABASE_URL'].presence
|
217
|
-
return nil unless url
|
218
|
-
|
219
|
-
case url
|
220
|
-
when %r{\Amysql2://}
|
221
|
-
MYSQL
|
222
|
-
when %r{\Apostgres(ql)?://}
|
223
|
-
POSTGRESQL
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
177
|
def support_bulk_alter?
|
228
178
|
case database
|
229
179
|
when MYSQL
|
@@ -31,10 +31,11 @@ module RuboCop
|
|
31
31
|
time
|
32
32
|
].to_set.freeze
|
33
33
|
|
34
|
-
# Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.0.
|
34
|
+
# Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.1.0.
|
35
35
|
# rubocop:disable Metrics/CollectionLiteralLength
|
36
36
|
DANGEROUS_COLUMN_NAMES = %w[
|
37
37
|
__callbacks
|
38
|
+
__id__
|
38
39
|
_assign_attribute
|
39
40
|
_assign_attributes
|
40
41
|
_before_commit_callbacks
|
@@ -195,11 +196,13 @@ module RuboCop
|
|
195
196
|
changes_to_save
|
196
197
|
check_record_limit
|
197
198
|
ciphertext_for
|
199
|
+
class
|
198
200
|
clear_attribute_change
|
199
201
|
clear_attribute_changes
|
200
202
|
clear_changes_information
|
201
203
|
clear_timestamp_attributes
|
202
204
|
clear_transaction_record_state
|
205
|
+
clone
|
203
206
|
collection_cache_versioning
|
204
207
|
column_for_attribute
|
205
208
|
committed
|
@@ -227,6 +230,7 @@ module RuboCop
|
|
227
230
|
destroyed
|
228
231
|
destroyed_by_association
|
229
232
|
destroyed_by_association=
|
233
|
+
dup
|
230
234
|
each_counter_cached_associations
|
231
235
|
encode_with
|
232
236
|
encrypt
|
@@ -243,7 +247,9 @@ module RuboCop
|
|
243
247
|
find_parameter_position
|
244
248
|
forget_attribute_assignments
|
245
249
|
format_for_inspect
|
250
|
+
freeze
|
246
251
|
from_json
|
252
|
+
frozen?
|
247
253
|
halted_callback_hook
|
248
254
|
has_attribute
|
249
255
|
has_changes_to_save
|
@@ -252,6 +258,7 @@ module RuboCop
|
|
252
258
|
has_encrypted_attributes
|
253
259
|
has_encrypted_rich_texts
|
254
260
|
has_transactional_callbacks
|
261
|
+
hash
|
255
262
|
id
|
256
263
|
id_before_type_cast
|
257
264
|
id_for_database
|
@@ -283,6 +290,7 @@ module RuboCop
|
|
283
290
|
new_record
|
284
291
|
no_touching
|
285
292
|
normalize_reflection_attribute
|
293
|
+
object_id
|
286
294
|
partial_inserts
|
287
295
|
partial_updates
|
288
296
|
perform_validations
|
@@ -20,6 +20,15 @@ module RuboCop
|
|
20
20
|
# belongs_to :bar
|
21
21
|
# has_one :foo
|
22
22
|
#
|
23
|
+
# # bad
|
24
|
+
# has_many :foo, class_name: 'Foo'
|
25
|
+
# has_many :bar, class_name: 'Foo'
|
26
|
+
# has_one :baz
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# has_many :bar, class_name: 'Foo'
|
30
|
+
# has_one :foo
|
31
|
+
#
|
23
32
|
class DuplicateAssociation < Base
|
24
33
|
include RangeHelp
|
25
34
|
extend AutoCorrector
|
@@ -27,31 +36,76 @@ module RuboCop
|
|
27
36
|
include ActiveRecordHelper
|
28
37
|
|
29
38
|
MSG = "Association `%<name>s` is defined multiple times. Don't repeat associations."
|
39
|
+
MSG_CLASS_NAME = "Association `class_name: %<name>s` is defined multiple times. Don't repeat associations."
|
30
40
|
|
31
41
|
def_node_matcher :association, <<~PATTERN
|
32
|
-
(send nil? {:belongs_to :has_one :has_many :has_and_belongs_to_many} ({sym str} $_)
|
42
|
+
(send nil? {:belongs_to :has_one :has_many :has_and_belongs_to_many} ({sym str} $_) $...)
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def_node_matcher :class_name, <<~PATTERN
|
46
|
+
(hash (pair (sym :class_name) $_))
|
33
47
|
PATTERN
|
34
48
|
|
35
49
|
def on_class(class_node)
|
36
50
|
return unless active_record?(class_node.parent_class)
|
37
51
|
|
38
|
-
|
39
|
-
nodes.each do |node|
|
40
|
-
add_offense(node, message: format(MSG, name: name)) do |corrector|
|
41
|
-
next if same_line?(nodes.last, node)
|
52
|
+
association_nodes = association_nodes(class_node)
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
54
|
+
duplicated_association_name_nodes(association_nodes).each do |name, nodes|
|
55
|
+
register_offense(name, nodes, MSG)
|
56
|
+
end
|
57
|
+
|
58
|
+
duplicated_class_name_nodes(association_nodes).each do |class_name, nodes|
|
59
|
+
register_offense(class_name, nodes, MSG_CLASS_NAME)
|
46
60
|
end
|
47
61
|
end
|
48
62
|
|
49
63
|
private
|
50
64
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
65
|
+
def register_offense(name, nodes, message_template)
|
66
|
+
nodes.each do |node|
|
67
|
+
add_offense(node, message: format(message_template, name: name)) do |corrector|
|
68
|
+
next if same_line?(nodes.last, node)
|
69
|
+
|
70
|
+
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def association_nodes(class_node)
|
76
|
+
class_send_nodes(class_node).select do |node|
|
77
|
+
association(node)&.first
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def duplicated_association_name_nodes(association_nodes)
|
82
|
+
grouped_associations = association_nodes.group_by do |node|
|
83
|
+
association(node).first.to_sym
|
84
|
+
end
|
85
|
+
|
86
|
+
leave_duplicated_association(grouped_associations)
|
87
|
+
end
|
88
|
+
|
89
|
+
def duplicated_class_name_nodes(association_nodes)
|
90
|
+
filtered_nodes = association_nodes.reject { |node| node.method?(:belongs_to) }
|
91
|
+
grouped_associations = filtered_nodes.group_by do |node|
|
92
|
+
arguments = association(node).last
|
93
|
+
next unless arguments.count == 1
|
94
|
+
|
95
|
+
if (class_name = class_name(arguments.first))
|
96
|
+
class_name.source
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
grouped_associations.delete(nil)
|
101
|
+
|
102
|
+
leave_duplicated_association(grouped_associations)
|
103
|
+
end
|
104
|
+
|
105
|
+
def leave_duplicated_association(grouped_associations)
|
106
|
+
grouped_associations.select do |_, nodes|
|
107
|
+
nodes.length > 1
|
108
|
+
end
|
55
109
|
end
|
56
110
|
end
|
57
111
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Checks for usage of `Rails.env.development? || Rails.env.test?` which
|
7
|
+
# can be replaced with `Rails.env.local?`, introduced in Rails 7.1.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# Rails.env.development? || Rails.env.test?
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# Rails.env.local?
|
16
|
+
#
|
17
|
+
class EnvLocal < Base
|
18
|
+
extend AutoCorrector
|
19
|
+
extend TargetRailsVersion
|
20
|
+
|
21
|
+
MSG = 'Use `Rails.env.local?` instead.'
|
22
|
+
LOCAL_ENVIRONMENTS = %i[development? test?].to_set.freeze
|
23
|
+
|
24
|
+
minimum_target_rails_version 7.1
|
25
|
+
|
26
|
+
# @!method rails_env_local_candidate?(node)
|
27
|
+
def_node_matcher :rails_env_local_candidate?, <<~PATTERN
|
28
|
+
(or
|
29
|
+
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
30
|
+
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
31
|
+
)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_or(node)
|
35
|
+
rails_env_local_candidate?(node) do |*environments|
|
36
|
+
next unless environments.to_set == LOCAL_ENVIRONMENTS
|
37
|
+
|
38
|
+
add_offense(node) do |corrector|
|
39
|
+
corrector.replace(node, 'Rails.env.local?')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks for use of the helper methods which reference
|
7
7
|
# instance variables.
|
8
8
|
#
|
9
|
-
# Relying on instance variables makes it difficult to
|
9
|
+
# Relying on instance variables makes it difficult to reuse helper
|
10
10
|
# methods.
|
11
11
|
#
|
12
12
|
# If it seems awkward to explicitly pass in each dependent
|
@@ -3,8 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# Checks for add_column call with NOT NULL constraint
|
7
|
-
#
|
6
|
+
# Checks for add_column call with NOT NULL constraint in migration file.
|
7
|
+
#
|
8
|
+
# `TEXT` can have default values in PostgreSQL, but not in MySQL.
|
9
|
+
# It will automatically detect an adapter from `development` environment
|
10
|
+
# in `config/database.yml` or the environment variable `DATABASE_URL`
|
11
|
+
# when the `Database` option is not set. If the database is MySQL,
|
12
|
+
# this cop ignores offenses for the `TEXT`.
|
8
13
|
#
|
9
14
|
# @example
|
10
15
|
# # bad
|
@@ -17,6 +22,8 @@ module RuboCop
|
|
17
22
|
# add_reference :products, :category
|
18
23
|
# add_reference :products, :category, null: false, default: 1
|
19
24
|
class NotNullColumn < Base
|
25
|
+
include DatabaseTypeResolvable
|
26
|
+
|
20
27
|
MSG = 'Do not add a NOT NULL column without a default value.'
|
21
28
|
RESTRICT_ON_SEND = %i[add_column add_reference].freeze
|
22
29
|
|
@@ -45,7 +52,10 @@ module RuboCop
|
|
45
52
|
|
46
53
|
def check_add_column(node)
|
47
54
|
add_not_null_column?(node) do |type, pairs|
|
48
|
-
|
55
|
+
if type.respond_to?(:value)
|
56
|
+
return if type.value == :virtual || type.value == 'virtual'
|
57
|
+
return if (type.value == :text || type.value == 'text') && database == MYSQL
|
58
|
+
end
|
49
59
|
|
50
60
|
check_pairs(pairs)
|
51
61
|
end
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
|
24
24
|
MSG = "Do not write to stdout. Use Rails's logger if you want to log."
|
25
25
|
RESTRICT_ON_SEND = %i[ap p pp pretty_print print puts binwrite syswrite write write_nonblock].freeze
|
26
|
+
ALLOWED_TYPES = %i[send csend block numblock].freeze
|
26
27
|
|
27
28
|
def_node_matcher :output?, <<~PATTERN
|
28
29
|
(send nil? {:ap :p :pp :pretty_print :print :puts} ...)
|
@@ -39,8 +40,8 @@ module RuboCop
|
|
39
40
|
PATTERN
|
40
41
|
|
41
42
|
def on_send(node)
|
42
|
-
return if node.parent&.
|
43
|
-
return
|
43
|
+
return if ALLOWED_TYPES.include?(node.parent&.type)
|
44
|
+
return if !output?(node) && !io_output?(node)
|
44
45
|
|
45
46
|
range = offense_range(node)
|
46
47
|
|
@@ -35,11 +35,19 @@ module RuboCop
|
|
35
35
|
|
36
36
|
RESTRICT_ON_SEND = [:all].freeze
|
37
37
|
|
38
|
-
# Defined methods in `ActiveRecord::Querying::QUERYING_METHODS` on activerecord 7.0.
|
38
|
+
# Defined methods in `ActiveRecord::Querying::QUERYING_METHODS` on activerecord 7.1.0.
|
39
39
|
QUERYING_METHODS = %i[
|
40
40
|
and
|
41
41
|
annotate
|
42
42
|
any?
|
43
|
+
async_average
|
44
|
+
async_count
|
45
|
+
async_ids
|
46
|
+
async_maximum
|
47
|
+
async_minimum
|
48
|
+
async_pick
|
49
|
+
async_pluck
|
50
|
+
async_sum
|
43
51
|
average
|
44
52
|
calculate
|
45
53
|
count
|
@@ -109,6 +117,7 @@ module RuboCop
|
|
109
117
|
preload
|
110
118
|
readonly
|
111
119
|
references
|
120
|
+
regroup
|
112
121
|
reorder
|
113
122
|
reselect
|
114
123
|
rewhere
|
@@ -130,6 +139,7 @@ module RuboCop
|
|
130
139
|
unscope
|
131
140
|
update_all
|
132
141
|
where
|
142
|
+
with
|
133
143
|
without
|
134
144
|
].to_set.freeze
|
135
145
|
|
@@ -162,6 +172,35 @@ module RuboCop
|
|
162
172
|
def offense_range(node)
|
163
173
|
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
164
174
|
end
|
175
|
+
|
176
|
+
# TODO: In the future, please support only RuboCop 1.52+ and use `RuboCop::Cop::AllowedReceivers`:
|
177
|
+
# https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/mixin/allowed_receivers.rb
|
178
|
+
# At that time, this duplicated module implementation can be removed.
|
179
|
+
module AllowedReceivers
|
180
|
+
def allowed_receiver?(receiver)
|
181
|
+
receiver_name = receiver_name(receiver)
|
182
|
+
|
183
|
+
allowed_receivers.include?(receiver_name)
|
184
|
+
end
|
185
|
+
|
186
|
+
def receiver_name(receiver)
|
187
|
+
return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type?
|
188
|
+
|
189
|
+
if receiver.send_type?
|
190
|
+
if receiver.receiver
|
191
|
+
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
192
|
+
else
|
193
|
+
receiver.method_name.to_s
|
194
|
+
end
|
195
|
+
else
|
196
|
+
receiver.source
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def allowed_receivers
|
201
|
+
cop_config.fetch('AllowedReceivers', [])
|
202
|
+
end
|
203
|
+
end
|
165
204
|
end
|
166
205
|
end
|
167
206
|
end
|
@@ -53,6 +53,12 @@ module RuboCop
|
|
53
53
|
# @example source that matches - by a foreign key
|
54
54
|
# validates :user_id, presence: true
|
55
55
|
#
|
56
|
+
# @example source that DOES NOT match - if condition
|
57
|
+
# validates :user_id, presence: true, if: condition
|
58
|
+
#
|
59
|
+
# @example source that DOES NOT match - unless condition
|
60
|
+
# validates :user_id, presence: true, unless: condition
|
61
|
+
#
|
56
62
|
# @example source that DOES NOT match - strict validation
|
57
63
|
# validates :user_id, presence: true, strict: true
|
58
64
|
#
|
@@ -65,6 +71,7 @@ module RuboCop
|
|
65
71
|
$[
|
66
72
|
(hash <$(pair (sym :presence) true) ...>) # presence: true
|
67
73
|
!(hash <$(pair (sym :strict) {true const}) ...>) # strict: true
|
74
|
+
!(hash <$(pair (sym {:if :unless}) _) ...>) # if: some_condition or unless: some_condition
|
68
75
|
]
|
69
76
|
)
|
70
77
|
PATTERN
|
@@ -235,10 +235,10 @@ module RuboCop
|
|
235
235
|
|
236
236
|
def in_condition_or_compound_boolean?(node)
|
237
237
|
node = node.block_node || node
|
238
|
-
parent = node.
|
238
|
+
parent = node.each_ancestor.find { |ancestor| !ancestor.begin_type? }
|
239
239
|
return false unless parent
|
240
240
|
|
241
|
-
operator_or_single_negative?(parent) || (conditional?(parent) && node == parent.condition)
|
241
|
+
operator_or_single_negative?(parent) || (conditional?(parent) && node == deparenthesize(parent.condition))
|
242
242
|
end
|
243
243
|
|
244
244
|
def operator_or_single_negative?(node)
|
@@ -249,6 +249,11 @@ module RuboCop
|
|
249
249
|
parent.if_type? || parent.case_type?
|
250
250
|
end
|
251
251
|
|
252
|
+
def deparenthesize(node)
|
253
|
+
node = node.children.last while node.begin_type?
|
254
|
+
node
|
255
|
+
end
|
256
|
+
|
252
257
|
def checked_immediately?(node)
|
253
258
|
node.parent && call_to_persisted?(node.parent)
|
254
259
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative 'mixin/active_record_helper'
|
4
4
|
require_relative 'mixin/active_record_migrations_helper'
|
5
5
|
require_relative 'mixin/class_send_node_helper'
|
6
|
+
require_relative 'mixin/database_type_resolvable'
|
6
7
|
require_relative 'mixin/enforce_superclass'
|
7
8
|
require_relative 'mixin/index_method'
|
8
9
|
require_relative 'mixin/migrations_helper'
|
@@ -46,6 +47,7 @@ require_relative 'rails/dynamic_find_by'
|
|
46
47
|
require_relative 'rails/eager_evaluation_log_message'
|
47
48
|
require_relative 'rails/enum_hash'
|
48
49
|
require_relative 'rails/enum_uniqueness'
|
50
|
+
require_relative 'rails/env_local'
|
49
51
|
require_relative 'rails/environment_comparison'
|
50
52
|
require_relative 'rails/environment_variable_access'
|
51
53
|
require_relative 'rails/exit'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.22.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-10-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/rubocop/cop/mixin/active_record_helper.rb
|
79
79
|
- lib/rubocop/cop/mixin/active_record_migrations_helper.rb
|
80
80
|
- lib/rubocop/cop/mixin/class_send_node_helper.rb
|
81
|
+
- lib/rubocop/cop/mixin/database_type_resolvable.rb
|
81
82
|
- lib/rubocop/cop/mixin/enforce_superclass.rb
|
82
83
|
- lib/rubocop/cop/mixin/index_method.rb
|
83
84
|
- lib/rubocop/cop/mixin/migrations_helper.rb
|
@@ -120,6 +121,7 @@ files:
|
|
120
121
|
- lib/rubocop/cop/rails/eager_evaluation_log_message.rb
|
121
122
|
- lib/rubocop/cop/rails/enum_hash.rb
|
122
123
|
- lib/rubocop/cop/rails/enum_uniqueness.rb
|
124
|
+
- lib/rubocop/cop/rails/env_local.rb
|
123
125
|
- lib/rubocop/cop/rails/environment_comparison.rb
|
124
126
|
- lib/rubocop/cop/rails/environment_variable_access.rb
|
125
127
|
- lib/rubocop/cop/rails/exit.rb
|
@@ -223,7 +225,7 @@ metadata:
|
|
223
225
|
homepage_uri: https://docs.rubocop.org/rubocop-rails/
|
224
226
|
changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
|
225
227
|
source_code_uri: https://github.com/rubocop/rubocop-rails/
|
226
|
-
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.
|
228
|
+
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.22/
|
227
229
|
bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
|
228
230
|
rubygems_mfa_required: 'true'
|
229
231
|
post_install_message:
|