rubocop-rails 2.26.2 → 2.28.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.
- checksums.yaml +4 -4
- data/README.md +36 -0
- data/config/default.yml +9 -5
- data/lib/rubocop/cop/mixin/migrations_helper.rb +29 -0
- data/lib/rubocop/cop/mixin/target_rails_version.rb +3 -5
- data/lib/rubocop/cop/rails/add_column_index.rb +1 -0
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -0
- data/lib/rubocop/cop/rails/dangerous_column_names.rb +2 -0
- data/lib/rubocop/cop/rails/enum_syntax.rb +2 -0
- data/lib/rubocop/cop/rails/env_local.rb +26 -3
- data/lib/rubocop/cop/rails/file_path.rb +3 -0
- data/lib/rubocop/cop/rails/migration_class_name.rb +1 -1
- data/lib/rubocop/cop/rails/not_null_column.rb +1 -0
- data/lib/rubocop/cop/rails/pluck.rb +20 -0
- data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +1 -1
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -1
- data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +1 -1
- data/lib/rubocop/cop/rails/save_bang.rb +1 -1
- data/lib/rubocop/cop/rails/schema_comment.rb +1 -0
- data/lib/rubocop/cop/rails/select_map.rb +3 -2
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -1
- data/lib/rubocop/cop/rails/three_state_boolean_column.rb +2 -1
- data/lib/rubocop/cop/rails/time_zone.rb +3 -0
- data/lib/rubocop/cop/rails/transaction_exit_statement.rb +5 -0
- data/lib/rubocop/cop/rails/where_range.rb +1 -1
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +4 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 758b691d39a36d50333d038d5efc0615f3da32aa8b47f0a465f684586b15463c
|
4
|
+
data.tar.gz: 8cf337b9a94306e55af10e5c7f0ee1e607fe22b27ca02cde32ece30e0c8c9bb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5841dbc4ae81e23e5eac1921e5752204e0c0dea5d17e0edd894329bd8d8764d0594b44a045f0d4f722d8b6927037f1b8817a1d29f444c75555ecd94feb8180d
|
7
|
+
data.tar.gz: 2adfb7937e87109d54e8fe596bc653528a62cfe87cebe7554ee1865a07daf5c3169fb7387bf6dacc59e71ee479ddd718c2775f2a1df573f5383b1f10fc27fd42
|
data/README.md
CHANGED
@@ -63,6 +63,42 @@ RuboCop::RakeTask.new do |task|
|
|
63
63
|
end
|
64
64
|
```
|
65
65
|
|
66
|
+
## RuboCop Rails configuration
|
67
|
+
|
68
|
+
The following settings specific to RuboCop Rails can be configured in `.rubocop.yml`.
|
69
|
+
|
70
|
+
### `AllCops: TargetRailsVersion`
|
71
|
+
|
72
|
+
What version of Rails is the inspected code using? If a value is specified
|
73
|
+
for `TargetRailsVersion` then it is used. Acceptable values are specified
|
74
|
+
as a float (e.g., 7.2); the patch version of Rails should not be included.
|
75
|
+
|
76
|
+
```yaml
|
77
|
+
AllCops:
|
78
|
+
TargetRailsVersion: 7.2
|
79
|
+
```
|
80
|
+
|
81
|
+
If `TargetRailsVersion` is not set, RuboCop will parse the Gemfile.lock or
|
82
|
+
gems.locked file to find the version of Rails that has been bound to the
|
83
|
+
application. If neither of those files exist, RuboCop will use Rails 5.0
|
84
|
+
as the default.
|
85
|
+
|
86
|
+
### `AllCops: MigratedSchemaVersion`
|
87
|
+
|
88
|
+
By specifying the `MigratedSchemaVersion` option, migration files that have already been run can be ignored.
|
89
|
+
When `MigratedSchemaVersion: '20241225000000'` is set, migration files lower than or equal to '20241225000000' will be ignored.
|
90
|
+
For example, to ignore db/migrate/20241225000000_create_articles.rb and earlier migrations you would configure it the following way:
|
91
|
+
|
92
|
+
```yaml
|
93
|
+
AllCops
|
94
|
+
MigratedSchemaVersion: '20241225000000'
|
95
|
+
```
|
96
|
+
|
97
|
+
This prevents inspecting schema settings for already applied migration files.
|
98
|
+
Changing already applied migrations should be avoided because it can lead to the schema getting out of sync
|
99
|
+
between your local copy and what it actually is in production, depending on when `bin/rails db:migrate` was executed.
|
100
|
+
If you want to modify your schema to comply with the cops, you should instead create new migrations.
|
101
|
+
|
66
102
|
## Rails configuration tip
|
67
103
|
|
68
104
|
In Rails 6.1+, add the following `config.generators.after_generate` setting to
|
data/config/default.yml
CHANGED
@@ -17,14 +17,18 @@ AllCops:
|
|
17
17
|
# Enable checking Active Support extensions.
|
18
18
|
# See: https://docs.rubocop.org/rubocop/configuration.html#enable-checking-active-support-extensions
|
19
19
|
ActiveSupportExtensionsEnabled: true
|
20
|
-
# What version of Rails is the inspected code using?
|
21
|
-
# for TargetRailsVersion then it is used.
|
22
|
-
# as a float (
|
23
|
-
# If TargetRailsVersion is not set, RuboCop will parse the Gemfile.lock or
|
20
|
+
# What version of Rails is the inspected code using? If a value is specified
|
21
|
+
# for `TargetRailsVersion` then it is used. Acceptable values are specified
|
22
|
+
# as a float (e.g., 7.2); the patch version of Rails should not be included.
|
23
|
+
# If `TargetRailsVersion` is not set, RuboCop will parse the Gemfile.lock or
|
24
24
|
# gems.locked file to find the version of Rails that has been bound to the
|
25
|
-
# application.
|
25
|
+
# application. If neither of those files exist, RuboCop will use Rails 5.0
|
26
26
|
# as the default.
|
27
27
|
TargetRailsVersion: ~
|
28
|
+
# By specifying `MigratedSchemaVersion` option, migration files that have been migrated can be ignored.
|
29
|
+
# When `MigratedSchemaVersion: '20241231000000'` is set. Migration files lower than or equal to '20250101000000' will be ignored.
|
30
|
+
# For example, this is the timestamp in db/migrate/20250101000000_create_articles.rb.
|
31
|
+
MigratedSchemaVersion: ~
|
28
32
|
|
29
33
|
Lint/NumberConversion:
|
30
34
|
# Add Rails' duration methods to the ignore list for `Lint/NumberConversion`
|
@@ -21,6 +21,35 @@ module RuboCop
|
|
21
21
|
migration_class?(class_node)
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
# rubocop:disable Style/DocumentDynamicEvalDefinition
|
26
|
+
%i[on_send on_csend on_block on_numblock on_class].each do |method|
|
27
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
28
|
+
def #{method}(node)
|
29
|
+
return if already_migrated_file?
|
30
|
+
|
31
|
+
super if method(__method__).super_method
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
end
|
35
|
+
# rubocop:enable Style/DocumentDynamicEvalDefinition
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def already_migrated_file?
|
40
|
+
return false unless migrated_schema_version
|
41
|
+
|
42
|
+
match_data = File.basename(processed_source.file_path).match(/(?<timestamp>\d{14})/)
|
43
|
+
schema_version = match_data['timestamp'] if match_data
|
44
|
+
|
45
|
+
return false unless schema_version
|
46
|
+
|
47
|
+
schema_version <= migrated_schema_version.to_s # Ignore applied migration files.
|
48
|
+
end
|
49
|
+
|
50
|
+
def migrated_schema_version
|
51
|
+
config.for_all_cops.fetch('MigratedSchemaVersion', nil)
|
52
|
+
end
|
24
53
|
end
|
25
54
|
end
|
26
55
|
end
|
@@ -7,6 +7,9 @@ module RuboCop
|
|
7
7
|
# Informs the base RuboCop gem that it the Rails version is checked via `requires_gem` API,
|
8
8
|
# without needing to call this `#support_target_rails_version` method.
|
9
9
|
USES_REQUIRES_GEM_API = true
|
10
|
+
# Look for `railties` instead of `rails`, to support apps that only use a subset of `rails`
|
11
|
+
# See https://github.com/rubocop/rubocop/pull/11289
|
12
|
+
TARGET_GEM_NAME = 'railties' # :nodoc:
|
10
13
|
|
11
14
|
def minimum_target_rails_version(version)
|
12
15
|
if respond_to?(:requires_gem)
|
@@ -33,11 +36,6 @@ module RuboCop
|
|
33
36
|
@minimum_target_rails_version <= version
|
34
37
|
end
|
35
38
|
end
|
36
|
-
|
37
|
-
# Look for `railties` instead of `rails`, to support apps that only use a subset of `rails`
|
38
|
-
# See https://github.com/rubocop/rubocop/pull/11289
|
39
|
-
TARGET_GEM_NAME = 'railties'
|
40
|
-
private_constant :TARGET_GEM_NAME
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
@@ -19,20 +19,33 @@ module RuboCop
|
|
19
19
|
extend TargetRailsVersion
|
20
20
|
|
21
21
|
MSG = 'Use `Rails.env.local?` instead.'
|
22
|
+
MSG_NEGATED = 'Use `!Rails.env.local?` instead.'
|
22
23
|
LOCAL_ENVIRONMENTS = %i[development? test?].to_set.freeze
|
23
24
|
|
24
25
|
minimum_target_rails_version 7.1
|
25
26
|
|
26
|
-
# @!method
|
27
|
-
def_node_matcher :
|
27
|
+
# @!method rails_env_local_or?(node)
|
28
|
+
def_node_matcher :rails_env_local_or?, <<~PATTERN
|
28
29
|
(or
|
29
30
|
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
30
31
|
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
31
32
|
)
|
32
33
|
PATTERN
|
33
34
|
|
35
|
+
# @!method rails_env_local_and?(node)
|
36
|
+
def_node_matcher :rails_env_local_and?, <<~PATTERN
|
37
|
+
(and
|
38
|
+
(send
|
39
|
+
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
40
|
+
:!)
|
41
|
+
(send
|
42
|
+
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
|
43
|
+
:!)
|
44
|
+
)
|
45
|
+
PATTERN
|
46
|
+
|
34
47
|
def on_or(node)
|
35
|
-
|
48
|
+
rails_env_local_or?(node) do |*environments|
|
36
49
|
next unless environments.to_set == LOCAL_ENVIRONMENTS
|
37
50
|
|
38
51
|
add_offense(node) do |corrector|
|
@@ -40,6 +53,16 @@ module RuboCop
|
|
40
53
|
end
|
41
54
|
end
|
42
55
|
end
|
56
|
+
|
57
|
+
def on_and(node)
|
58
|
+
rails_env_local_and?(node) do |*environments|
|
59
|
+
next unless environments.to_set == LOCAL_ENVIRONMENTS
|
60
|
+
|
61
|
+
add_offense(node, message: MSG_NEGATED) do |corrector|
|
62
|
+
corrector.replace(node, '!Rails.env.local?')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
43
66
|
end
|
44
67
|
end
|
45
68
|
end
|
@@ -66,6 +66,8 @@ module RuboCop
|
|
66
66
|
|
67
67
|
def on_send(node)
|
68
68
|
check_for_file_join_with_rails_root(node)
|
69
|
+
return unless node.receiver
|
70
|
+
|
69
71
|
check_for_rails_root_join_with_slash_separated_path(node)
|
70
72
|
check_for_rails_root_join_with_string_arguments(node)
|
71
73
|
end
|
@@ -76,6 +78,7 @@ module RuboCop
|
|
76
78
|
rails_root_index = find_rails_root_index(node)
|
77
79
|
slash_node = node.children[rails_root_index + 1]
|
78
80
|
return unless slash_node&.str_type? && slash_node.source.start_with?(File::SEPARATOR)
|
81
|
+
return unless node.children[rails_root_index].children.first.send_type?
|
79
82
|
|
80
83
|
register_offense(node, require_to_s: false) do |corrector|
|
81
84
|
autocorrect_slash_after_rails_root_in_dstr(corrector, node, rails_root_index)
|
@@ -41,6 +41,7 @@ module RuboCop
|
|
41
41
|
# change_column_null :products, :category_id, false
|
42
42
|
class NotNullColumn < Base
|
43
43
|
include DatabaseTypeResolvable
|
44
|
+
prepend MigrationsHelper
|
44
45
|
|
45
46
|
MSG = 'Do not add a NOT NULL column without a default value.'
|
46
47
|
RESTRICT_ON_SEND = %i[add_column add_reference].freeze
|
@@ -9,6 +9,24 @@ module RuboCop
|
|
9
9
|
# element in an enumerable. When called on an Active Record relation, it
|
10
10
|
# results in a more efficient query that only selects the necessary key.
|
11
11
|
#
|
12
|
+
# NOTE: If the receiver's relation is not loaded and `pluck` is used inside an iteration,
|
13
|
+
# it may result in N+1 queries because `pluck` queries the database on each iteration.
|
14
|
+
# This cop ignores offenses for `map/collect` when they are suspected to be part of an iteration
|
15
|
+
# to prevent such potential issues.
|
16
|
+
#
|
17
|
+
# [source,ruby]
|
18
|
+
# ----
|
19
|
+
# users = User.all
|
20
|
+
# 5.times do
|
21
|
+
# users.map { |user| user[:foo] } # Only one query is executed
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# users = User.all
|
25
|
+
# 5.times do
|
26
|
+
# users.pluck(:id) # A query is executed on every iteration
|
27
|
+
# end
|
28
|
+
# ----
|
29
|
+
#
|
12
30
|
# @safety
|
13
31
|
# This cop is unsafe because model can use column aliases.
|
14
32
|
#
|
@@ -42,6 +60,8 @@ module RuboCop
|
|
42
60
|
PATTERN
|
43
61
|
|
44
62
|
def on_block(node)
|
63
|
+
return if node.each_ancestor(:block, :numblock).any?
|
64
|
+
|
45
65
|
pluck_candidate?(node) do |argument, key|
|
46
66
|
next if key.regexp_type? || !use_one_block_argument?(argument)
|
47
67
|
|
@@ -174,7 +174,7 @@ module RuboCop
|
|
174
174
|
parent = node.parent
|
175
175
|
return false unless POSSIBLE_ENUMERABLE_BLOCK_METHODS.include?(parent.method_name)
|
176
176
|
|
177
|
-
parent.
|
177
|
+
parent.block_literal? || parent.first_argument&.block_pass_type?
|
178
178
|
end
|
179
179
|
|
180
180
|
def sensitive_association_method?(node)
|
@@ -40,12 +40,13 @@ module RuboCop
|
|
40
40
|
autocorrect(corrector, select_node, node, preferred_method)
|
41
41
|
end
|
42
42
|
end
|
43
|
+
alias on_csend on_send
|
43
44
|
|
44
45
|
private
|
45
46
|
|
46
47
|
def find_select_node(node, column_name)
|
47
48
|
node.descendants.detect do |select_candidate|
|
48
|
-
next if !select_candidate.
|
49
|
+
next if !select_candidate.call_type? || !select_candidate.method?(:select)
|
49
50
|
|
50
51
|
match_column_name?(select_candidate, column_name)
|
51
52
|
end
|
@@ -53,7 +54,7 @@ module RuboCop
|
|
53
54
|
|
54
55
|
# rubocop:disable Metrics/AbcSize
|
55
56
|
def autocorrect(corrector, select_node, node, preferred_method)
|
56
|
-
corrector.remove(select_node.
|
57
|
+
corrector.remove(select_node.parent.loc.dot)
|
57
58
|
corrector.remove(select_node.loc.selector.begin.join(select_node.source_range.end))
|
58
59
|
corrector.replace(node.loc.selector.begin.join(node.source_range.end), preferred_method)
|
59
60
|
end
|
@@ -18,8 +18,9 @@ module RuboCop
|
|
18
18
|
# t.boolean :active, default: true, null: false
|
19
19
|
#
|
20
20
|
class ThreeStateBooleanColumn < Base
|
21
|
-
|
21
|
+
prepend MigrationsHelper
|
22
22
|
|
23
|
+
MSG = 'Boolean columns should always have a default value and a `NOT NULL` constraint.'
|
23
24
|
RESTRICT_ON_SEND = %i[add_column column boolean].freeze
|
24
25
|
|
25
26
|
def_node_matcher :three_state_boolean?, <<~PATTERN
|
@@ -28,6 +28,8 @@ module RuboCop
|
|
28
28
|
# Time.zone.now
|
29
29
|
# Time.zone.parse('2015-03-02T19:05:37')
|
30
30
|
# Time.zone.parse('2015-03-02T19:05:37Z') # Respect ISO 8601 format with timezone specifier.
|
31
|
+
# Time.parse('2015-03-02T19:05:37Z') # Also respects ISO 8601
|
32
|
+
# '2015-03-02T19:05:37Z'.to_time # Also respects ISO 8601
|
31
33
|
#
|
32
34
|
# @example EnforcedStyle: flexible (default)
|
33
35
|
# # `flexible` allows usage of `in_time_zone` instead of `zone`.
|
@@ -67,6 +69,7 @@ module RuboCop
|
|
67
69
|
|
68
70
|
def on_send(node)
|
69
71
|
return if !node.receiver&.str_type? || !node.method?(:to_time)
|
72
|
+
return if attach_timezone_specifier?(node.receiver)
|
70
73
|
|
71
74
|
add_offense(node.loc.selector, message: MSG_STRING_TO_TIME) do |corrector|
|
72
75
|
corrector.replace(node, "Time.zone.parse(#{node.receiver.source})") unless node.csend_type?
|
@@ -15,6 +15,10 @@ module RuboCop
|
|
15
15
|
#
|
16
16
|
# If you are defining custom transaction methods, you can configure it with `TransactionMethods`.
|
17
17
|
#
|
18
|
+
# NOTE: This cop is disabled on Rails >= 7.2 because transactions were restored
|
19
|
+
# to their historical behavior. In Rails 7.1, the behavior is controlled with
|
20
|
+
# the config `active_record.commit_transaction_on_non_local_return`.
|
21
|
+
#
|
18
22
|
# @example
|
19
23
|
# # bad
|
20
24
|
# ApplicationRecord.transaction do
|
@@ -76,6 +80,7 @@ module RuboCop
|
|
76
80
|
PATTERN
|
77
81
|
|
78
82
|
def on_send(node)
|
83
|
+
return if target_rails_version >= 7.2
|
79
84
|
return unless in_transaction_block?(node)
|
80
85
|
|
81
86
|
exit_statements(node.parent.body).each do |statement_node|
|
metadata
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2024-
|
12
|
+
date: 2024-12-25 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: activesupport
|
@@ -247,10 +246,9 @@ metadata:
|
|
247
246
|
homepage_uri: https://docs.rubocop.org/rubocop-rails/
|
248
247
|
changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
|
249
248
|
source_code_uri: https://github.com/rubocop/rubocop-rails/
|
250
|
-
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.
|
249
|
+
documentation_uri: https://docs.rubocop.org/rubocop-rails/2.28/
|
251
250
|
bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
|
252
251
|
rubygems_mfa_required: 'true'
|
253
|
-
post_install_message:
|
254
252
|
rdoc_options: []
|
255
253
|
require_paths:
|
256
254
|
- lib
|
@@ -265,8 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
265
263
|
- !ruby/object:Gem::Version
|
266
264
|
version: '0'
|
267
265
|
requirements: []
|
268
|
-
rubygems_version: 3.
|
269
|
-
signing_key:
|
266
|
+
rubygems_version: 3.6.1
|
270
267
|
specification_version: 4
|
271
268
|
summary: Automatic Rails code style checking tool.
|
272
269
|
test_files: []
|