sevencop 0.20.1 → 0.22.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/.rubocop.yml +6 -0
- data/Gemfile.lock +13 -1
- data/README.md +19 -4
- data/config/default.yml +163 -0
- data/lib/rubocop/cop/sevencop/factory_bot_association_option.rb +89 -0
- data/lib/rubocop/cop/sevencop/factory_bot_association_style.rb +167 -0
- data/lib/rubocop/cop/sevencop/rails_inferred_spec_type.rb +1 -1
- data/lib/rubocop/cop/sevencop/rails_migration_add_check_constraint.rb +111 -0
- data/lib/rubocop/cop/sevencop/rails_migration_add_column_with_default_value.rb +229 -0
- data/lib/rubocop/cop/sevencop/rails_migration_add_foreign_key.rb +166 -0
- data/lib/rubocop/cop/sevencop/rails_migration_add_index_concurrently.rb +164 -0
- data/lib/rubocop/cop/sevencop/rails_migration_batch_in_batches.rb +95 -0
- data/lib/rubocop/cop/sevencop/rails_migration_batch_in_transaction.rb +83 -0
- data/lib/rubocop/cop/sevencop/rails_migration_batch_with_throttling.rb +108 -0
- data/lib/rubocop/cop/sevencop/rails_migration_change_column.rb +113 -0
- data/lib/rubocop/cop/sevencop/rails_migration_change_column_null.rb +128 -0
- data/lib/rubocop/cop/sevencop/rails_migration_create_table_force.rb +89 -0
- data/lib/rubocop/cop/sevencop/rails_migration_jsonb.rb +131 -0
- data/lib/rubocop/cop/sevencop/rails_migration_remove_column.rb +258 -0
- data/lib/rubocop/cop/sevencop/rails_migration_rename_column.rb +81 -0
- data/lib/rubocop/cop/sevencop/rails_migration_rename_table.rb +79 -0
- data/lib/rubocop/cop/sevencop/rails_migration_reserved_word_mysql.rb +2 -19
- data/lib/rubocop/cop/sevencop/rails_migration_unique_index_columns_count.rb +92 -0
- data/lib/sevencop/config_loader.rb +11 -10
- data/lib/sevencop/cop_concerns/batch_processing.rb +32 -0
- data/lib/sevencop/cop_concerns/column_type_method.rb +26 -0
- data/lib/sevencop/cop_concerns/disable_ddl_transaction.rb +49 -0
- data/lib/sevencop/cop_concerns.rb +3 -0
- data/lib/sevencop/rubocop_extension.rb +6 -1
- data/lib/sevencop/version.rb +1 -1
- data/lib/sevencop.rb +17 -0
- data/sevencop.gemspec +1 -0
- metadata +36 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2aff4e0e776ef3fa5b3f71ece7b7c83013caadaf829fc86827ab246f5f80382
|
4
|
+
data.tar.gz: 1889785ce282e4d530c7eef4a54afaa948181b1557e788425e9b30e831935b77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 386a275378516b205cbd1dc4d50226776d106dc98eb8c534973ff7379c39b59f0e49ae4985058f79254d2256a09ac459b6357e1c5d0f03a8e2d780ec8b1fc990
|
7
|
+
data.tar.gz: 91adea811d280655577fd88cdb4b861b3a9e04f4c89d9542a4ce38281f325cfe0be590cb45ce8937375b4d13e67970518e6381531f46087689e58f3b8d0c5156
|
data/.rubocop.yml
CHANGED
@@ -13,6 +13,9 @@ AllCops:
|
|
13
13
|
Gemspec/RequireMFA:
|
14
14
|
Enabled: false
|
15
15
|
|
16
|
+
Layout/LineLength:
|
17
|
+
Enabled: false
|
18
|
+
|
16
19
|
Metrics:
|
17
20
|
Enabled: false
|
18
21
|
|
@@ -49,6 +52,9 @@ Sevencop/MethodDefinitionKeywordArgumentOrdered:
|
|
49
52
|
Sevencop/MethodDefinitionOrdered:
|
50
53
|
Enabled: true
|
51
54
|
|
55
|
+
Sevencop/RequireOrdered:
|
56
|
+
Enabled: true
|
57
|
+
|
52
58
|
Style/Documentation:
|
53
59
|
Enabled: false
|
54
60
|
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,25 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sevencop (0.
|
4
|
+
sevencop (0.22.0)
|
5
|
+
activesupport
|
5
6
|
rubocop
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
activesupport (7.0.4)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 1.6, < 2)
|
14
|
+
minitest (>= 5.1)
|
15
|
+
tzinfo (~> 2.0)
|
10
16
|
ast (2.4.2)
|
17
|
+
concurrent-ruby (1.1.10)
|
11
18
|
diff-lcs (1.5.0)
|
19
|
+
i18n (1.12.0)
|
20
|
+
concurrent-ruby (~> 1.0)
|
12
21
|
json (2.6.2)
|
22
|
+
minitest (5.16.3)
|
13
23
|
parallel (1.22.1)
|
14
24
|
parser (3.1.2.1)
|
15
25
|
ast (~> 2.4.1)
|
@@ -50,6 +60,8 @@ GEM
|
|
50
60
|
rubocop-rspec (2.13.1)
|
51
61
|
rubocop (~> 1.33)
|
52
62
|
ruby-progressbar (1.11.0)
|
63
|
+
tzinfo (2.0.5)
|
64
|
+
concurrent-ruby (~> 1.0)
|
53
65
|
unicode-display_width (2.3.0)
|
54
66
|
|
55
67
|
PLATFORMS
|
data/README.md
CHANGED
@@ -24,11 +24,13 @@ Sevencop/MethodDefinitionOrdered:
|
|
24
24
|
Enabled: true
|
25
25
|
```
|
26
26
|
|
27
|
-
|
27
|
+
Note that all cops are `Enabled: false` by default.
|
28
28
|
|
29
|
-
|
29
|
+
## Cops
|
30
30
|
|
31
31
|
- [Sevencop/AutoloadOrdered](lib/rubocop/cop/sevencop/autoload_ordered.rb)
|
32
|
+
- [Sevencop/FactoryBotAssociationOption](lib/rubocop/cop/sevencop/factory_bot_association_option.rb)
|
33
|
+
- [Sevencop/FactoryBotAssociationStyle](lib/rubocop/cop/sevencop/factory_bot_association_style.rb)
|
32
34
|
- [Sevencop/HashElementOrdered](lib/rubocop/cop/sevencop/hash_element_ordered.rb)
|
33
35
|
- [Sevencop/MethodDefinitionArgumentsMultiline](lib/rubocop/cop/sevencop/method_definition_arguments_multiline.rb)
|
34
36
|
- [Sevencop/MethodDefinitionInIncluded](lib/rubocop/cop/sevencop/method_definition_in_included.rb)
|
@@ -36,12 +38,25 @@ Choose the cops you want to use and enable them on your .rubocop.yml.
|
|
36
38
|
- [Sevencop/MethodDefinitionOrdered](lib/rubocop/cop/sevencop/method_definition_ordered.rb)
|
37
39
|
- [Sevencop/RailsBelongsToOptional](lib/rubocop/cop/sevencop/rails_belongs_to_optional.rb)
|
38
40
|
- [Sevencop/RailsInferredSpecType](lib/rubocop/cop/sevencop/rails_inferred_spec_type.rb)
|
41
|
+
- [Sevencop/RailsMigrationAddCheckConstraint](lib/rubocop/cop/sevencop/rails_migration_add_check_constraint.rb)
|
42
|
+
- [Sevencop/RailsMigrationAddColumnWithDefaultValue](lib/rubocop/cop/sevencop/rails_migration_add_column_with_default_value.rb)
|
43
|
+
- [Sevencop/RailsMigrationAddForeignKey](lib/rubocop/cop/sevencop/rails_migration_add_foreign_key.rb)
|
44
|
+
- [Sevencop/RailsMigrationAddIndexConcurrently](lib/rubocop/cop/sevencop/rails_migration_add_index_concurrently.rb)
|
45
|
+
- [Sevencop/RailsMigrationBatchInBatches](lib/rubocop/cop/sevencop/rails_migration_batch_in_batches.rb)
|
46
|
+
- [Sevencop/RailsMigrationBatchInTransaction](lib/rubocop/cop/sevencop/rails_migration_batch_in_transaction.rb)
|
47
|
+
- [Sevencop/RailsMigrationBatchWithThrottling](lib/rubocop/cop/sevencop/rails_migration_batch_with_throttling.rb)
|
48
|
+
- [Sevencop/RailsMigrationChangeColumn](lib/rubocop/cop/sevencop/rails_migration_change_column.rb)
|
49
|
+
- [Sevencop/RailsMigrationChangeColumnNull](lib/rubocop/cop/sevencop/rails_migration_change_column_null.rb)
|
50
|
+
- [Sevencop/RailsMigrationCreateTableForce](lib/rubocop/cop/sevencop/rails_migration_create_table_force.rb)
|
51
|
+
- [Sevencop/RailsMigrationJsonb](lib/rubocop/cop/sevencop/rails_migration_jsonb.rb)
|
52
|
+
- [Sevencop/RailsMigrationRemoveColumn](lib/rubocop/cop/sevencop/rails_migration_remove_column.rb)
|
53
|
+
- [Sevencop/RailsMigrationRenameColumn](lib/rubocop/cop/sevencop/rails_migration_rename_column.rb)
|
54
|
+
- [Sevencop/RailsMigrationRenameTable](lib/rubocop/cop/sevencop/rails_migration_rename_table.rb)
|
39
55
|
- [Sevencop/RailsMigrationReservedWordMysql](lib/rubocop/cop/sevencop/rails_migration_reserved_word_mysql.rb)
|
56
|
+
- [Sevencop/RailsMigrationUniqueIndexColumnsCount](lib/rubocop/cop/sevencop/rails_migration_unique_index_columns_count.rb)
|
40
57
|
- [Sevencop/RailsOrderField](lib/rubocop/cop/sevencop/rails_order_field.rb)
|
41
58
|
- [Sevencop/RailsUniquenessValidatorExplicitCaseSensitivity](lib/rubocop/cop/sevencop/rails_uniqueness_validator_explicit_case_sensitivity.rb)
|
42
59
|
- [Sevencop/RailsWhereNot](lib/rubocop/cop/sevencop/rails_where_not.rb)
|
43
60
|
- [Sevencop/RequireOrdered](lib/rubocop/cop/sevencop/require_ordered.rb)
|
44
61
|
- [Sevencop/RSpecDescribeHttpEndpoint](lib/rubocop/cop/sevencop/rspec_describe_http_endpoint.rb)
|
45
62
|
- [Sevencop/RSpecExamplesInSameGroup](lib/rubocop/cop/sevencop/rspec_examples_in_same_group.rb)
|
46
|
-
|
47
|
-
Note that all cops are `Enabled: false` by default.
|
data/config/default.yml
CHANGED
@@ -5,6 +5,35 @@ Sevencop/AutoloadOrdered:
|
|
5
5
|
Safe: false
|
6
6
|
VersionAdded: '0.12'
|
7
7
|
|
8
|
+
Sevencop/FactoryBotAssociationOptions:
|
9
|
+
Description: |
|
10
|
+
Remove redundant options from FactoryBot associations.
|
11
|
+
Enabled: false
|
12
|
+
VersionAdded: '0.21'
|
13
|
+
|
14
|
+
Sevencop/FactoryBotAssociationStyle:
|
15
|
+
Description: |
|
16
|
+
Use consistent style in FactoryBot associations.
|
17
|
+
Enabled: false
|
18
|
+
Safe: false
|
19
|
+
VersionAdded: '0.21'
|
20
|
+
EnforcedStyle: implicit
|
21
|
+
SupportedStyles:
|
22
|
+
- explicit
|
23
|
+
- implicit
|
24
|
+
inherit_mode:
|
25
|
+
merge:
|
26
|
+
- NonImplicitAssociationMethodNames
|
27
|
+
NonImplicitAssociationMethodNames:
|
28
|
+
- skip_create
|
29
|
+
Include:
|
30
|
+
- factories.rb
|
31
|
+
- factories/*.rb
|
32
|
+
- spec/factories.rb
|
33
|
+
- spec/factories/*.rb
|
34
|
+
- test/factories.rb
|
35
|
+
- test/factories/*.rb
|
36
|
+
|
8
37
|
Sevencop/HashElementOrdered:
|
9
38
|
Description: |
|
10
39
|
Sort Hash elements by key.
|
@@ -53,6 +82,131 @@ Sevencop/RailsInferredSpecType:
|
|
53
82
|
Safe: false
|
54
83
|
VersionAdded: '0.9'
|
55
84
|
|
85
|
+
Sevencop/RailsMigrationAddCheckConstraint:
|
86
|
+
Description: |
|
87
|
+
Activate a check constraint in a separate migration in PostgreSQL.
|
88
|
+
Enabled: false
|
89
|
+
Safe: false
|
90
|
+
VersionAdded: '0.22'
|
91
|
+
Include:
|
92
|
+
- db/migrate/**/*.rb
|
93
|
+
|
94
|
+
Sevencop/RailsMigrationAddColumnWithDefaultValue:
|
95
|
+
Description: |
|
96
|
+
Add the column without a default value then change the default.
|
97
|
+
Enabled: false
|
98
|
+
Safe: false
|
99
|
+
VersionAdded: '0.22'
|
100
|
+
Include:
|
101
|
+
- db/migrate/**/*.rb
|
102
|
+
|
103
|
+
Sevencop/RailsMigrationAddForeignKey:
|
104
|
+
Description: |
|
105
|
+
Activate a foreign key validation in a separate migration in PostgreSQL.
|
106
|
+
Enabled: false
|
107
|
+
Safe: false
|
108
|
+
VersionAdded: '0.22'
|
109
|
+
Include:
|
110
|
+
- db/migrate/**/*.rb
|
111
|
+
|
112
|
+
Sevencop/RailsMigrationAddIndexConcurrently:
|
113
|
+
Description: |
|
114
|
+
Use `algorithm: :concurrently` on adding indexes to existing tables in PostgreSQL.
|
115
|
+
Enabled: false
|
116
|
+
Safe: false
|
117
|
+
VersionAdded: '0.22'
|
118
|
+
Include:
|
119
|
+
- db/migrate/**/*.rb
|
120
|
+
|
121
|
+
Sevencop/RailsMigrationBatchInBatches:
|
122
|
+
Description: |
|
123
|
+
Use `in_batches` in batch processing.
|
124
|
+
Enabled: false
|
125
|
+
Safe: false
|
126
|
+
VersionAdded: '0.22'
|
127
|
+
Include:
|
128
|
+
- db/migrate/**/*.rb
|
129
|
+
|
130
|
+
Sevencop/RailsMigrationBatchInTransaction:
|
131
|
+
Description: |
|
132
|
+
Disable transaction in batch processing.
|
133
|
+
Enabled: false
|
134
|
+
Safe: false
|
135
|
+
VersionAdded: '0.22'
|
136
|
+
Include:
|
137
|
+
- db/migrate/**/*.rb
|
138
|
+
|
139
|
+
Sevencop/RailsMigrationBatchWithThrottling:
|
140
|
+
Description: |
|
141
|
+
Use throttling in batch processing.
|
142
|
+
Enabled: false
|
143
|
+
Safe: false
|
144
|
+
VersionAdded: '0.22'
|
145
|
+
Include:
|
146
|
+
- db/migrate/**/*.rb
|
147
|
+
|
148
|
+
Sevencop/RailsMigrationCreateTableForce:
|
149
|
+
Description: |
|
150
|
+
Create tables without `force: true` option.
|
151
|
+
Enabled: false
|
152
|
+
VersionAdded: '0.22'
|
153
|
+
Include:
|
154
|
+
- db/migrate/**/*.rb
|
155
|
+
|
156
|
+
Sevencop/RailsMigrationJsonb:
|
157
|
+
Description: |
|
158
|
+
Prefer `jsonb` to `json`.
|
159
|
+
Enabled: false
|
160
|
+
Safe: false
|
161
|
+
VersionAdded: '0.22'
|
162
|
+
Include:
|
163
|
+
- db/migrate/**/*.rb
|
164
|
+
|
165
|
+
Sevencop/RailsMigrationChangeColumn:
|
166
|
+
Description: |
|
167
|
+
Avoid changing column type that is in use.
|
168
|
+
Enabled: false
|
169
|
+
Safe: false
|
170
|
+
VersionAdded: '0.22'
|
171
|
+
Include:
|
172
|
+
- db/migrate/**/*.rb
|
173
|
+
|
174
|
+
Sevencop/RailsMigrationChangeColumnNull:
|
175
|
+
Description: |
|
176
|
+
Avoid simply setting `NOT NULL` constraint on an existing column in PostgreSQL.
|
177
|
+
Enabled: false
|
178
|
+
Safe: false
|
179
|
+
VersionAdded: '0.22'
|
180
|
+
Include:
|
181
|
+
- db/migrate/**/*.rb
|
182
|
+
|
183
|
+
Sevencop/RailsMigrationRemoveColumn:
|
184
|
+
Description: |
|
185
|
+
Add to `ignored_columns` and then remove the column.
|
186
|
+
Enabled: false
|
187
|
+
Safe: false
|
188
|
+
VersionAdded: '0.22'
|
189
|
+
Include:
|
190
|
+
- db/migrate/**/*.rb
|
191
|
+
|
192
|
+
Sevencop/RailsMigrationRenameColumn:
|
193
|
+
Description: |
|
194
|
+
Avoid renaming columns that are in use.
|
195
|
+
Enabled: false
|
196
|
+
Safe: false
|
197
|
+
VersionAdded: '0.22'
|
198
|
+
Include:
|
199
|
+
- db/migrate/**/*.rb
|
200
|
+
|
201
|
+
Sevencop/RailsMigrationRenameTable:
|
202
|
+
Description: |
|
203
|
+
Avoid removing tables that are in use.
|
204
|
+
Enabled: false
|
205
|
+
Safe: false
|
206
|
+
VersionAdded: '0.22'
|
207
|
+
Include:
|
208
|
+
- db/migrate/**/*.rb
|
209
|
+
|
56
210
|
Sevencop/RailsMigrationReservedWordMysql:
|
57
211
|
Description: |
|
58
212
|
Avoid using MySQL reserved words as identifiers.
|
@@ -62,6 +216,15 @@ Sevencop/RailsMigrationReservedWordMysql:
|
|
62
216
|
Include:
|
63
217
|
- db/migrate/**/*.rb
|
64
218
|
|
219
|
+
Sevencop/RailsMigrationUniqueIndexColumnsCount:
|
220
|
+
Description: |
|
221
|
+
Keep unique index columns count less than a specified number.
|
222
|
+
Enabled: false
|
223
|
+
VersionAdded: '0.22'
|
224
|
+
MaxColumnsCount: 3
|
225
|
+
Include:
|
226
|
+
- db/migrate/**/*.rb
|
227
|
+
|
65
228
|
Sevencop/RailsOrderField:
|
66
229
|
Description: |
|
67
230
|
Wrap safe SQL String by `Arel.sql`.
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Remove redundant options from FactoryBot associations.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# association :user, factory: :user
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# association :user
|
14
|
+
class FactoryBotAssociationOption < RuboCop::Cop::Base
|
15
|
+
extend AutoCorrector
|
16
|
+
|
17
|
+
include RangeHelp
|
18
|
+
|
19
|
+
MSG = 'Remove redundant options from FactoryBot associations.'
|
20
|
+
|
21
|
+
RESTRICT_ON_SEND = %i[association].freeze
|
22
|
+
|
23
|
+
# @param node [RuboCop::AST::SendNode]
|
24
|
+
# @return [void]
|
25
|
+
def on_send(node)
|
26
|
+
association_name = association_name_from(node)
|
27
|
+
factory_option = factory_option_from(node)
|
28
|
+
return if !factory_option || association_name != factory_option.value.value
|
29
|
+
|
30
|
+
add_offense(factory_option) do |corrector|
|
31
|
+
autocorrect(corrector, factory_option)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @!method association_name_from(node)
|
38
|
+
# @param node [RuboCop::AST::SendNode]
|
39
|
+
# @return [Symbol, nil]
|
40
|
+
def_node_matcher :association_name_from, <<~PATTERN
|
41
|
+
(send
|
42
|
+
nil?
|
43
|
+
_
|
44
|
+
(sym $_)
|
45
|
+
...
|
46
|
+
)
|
47
|
+
PATTERN
|
48
|
+
|
49
|
+
# @!method factory_option_from(node)
|
50
|
+
# @param node [RuboCop::AST::SendNode]
|
51
|
+
# @return [RuboCop::AST::PairNode, nil]
|
52
|
+
def_node_matcher :factory_option_from, <<~PATTERN
|
53
|
+
(send
|
54
|
+
nil?
|
55
|
+
_
|
56
|
+
_
|
57
|
+
(hash
|
58
|
+
<
|
59
|
+
$(pair
|
60
|
+
(sym :factory)
|
61
|
+
sym
|
62
|
+
)
|
63
|
+
...
|
64
|
+
>
|
65
|
+
)
|
66
|
+
)
|
67
|
+
PATTERN
|
68
|
+
|
69
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
70
|
+
# @param node [RuboCop::AST::PairNode]
|
71
|
+
# @return [void]
|
72
|
+
def autocorrect(
|
73
|
+
corrector,
|
74
|
+
node
|
75
|
+
)
|
76
|
+
corrector.remove(
|
77
|
+
range_with_surrounding_comma(
|
78
|
+
range_with_surrounding_space(
|
79
|
+
node.location.expression,
|
80
|
+
side: :left
|
81
|
+
),
|
82
|
+
:left
|
83
|
+
)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Use consistent style in FactoryBot associations.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop may cause false-positives in `EnforcedStyle: explicit` case.
|
10
|
+
# It recognizes any method call that has no arguments as an implicit association
|
11
|
+
# but it might be a user-defined trait call.
|
12
|
+
#
|
13
|
+
# @example EnforcedStyle: implicit (default)
|
14
|
+
# # bad
|
15
|
+
# association :user
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# user
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# association :author, factory: user
|
22
|
+
#
|
23
|
+
# @example EnforcedStyle: explicit
|
24
|
+
# # bad
|
25
|
+
# user
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# association :user
|
29
|
+
#
|
30
|
+
# # good (defined in NonImplicitAssociationMethodNames)
|
31
|
+
# skip_create
|
32
|
+
class FactoryBotAssociationStyle < RuboCop::Cop::Base
|
33
|
+
extend AutoCorrector
|
34
|
+
|
35
|
+
include ConfigurableEnforcedStyle
|
36
|
+
|
37
|
+
MSG = 'Use consistent style in FactoryBot associations.'
|
38
|
+
|
39
|
+
RESTRICT_ON_SEND = %i[factory].freeze
|
40
|
+
|
41
|
+
# @param node [RuboCop::AST::SendNode]
|
42
|
+
# @return [void]
|
43
|
+
def on_send(node)
|
44
|
+
bad_associations_in(node).each do |association|
|
45
|
+
add_offense(association) do |corrector|
|
46
|
+
autocorrect(corrector, association)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# @!method explicit_association?(node)
|
54
|
+
# @param node [RuboCop::AST::SendNode]
|
55
|
+
# @return [Boolean]
|
56
|
+
def_node_matcher :explicit_association?, <<~PATTERN
|
57
|
+
(send
|
58
|
+
nil?
|
59
|
+
:association
|
60
|
+
...
|
61
|
+
)
|
62
|
+
PATTERN
|
63
|
+
|
64
|
+
# @!method implicit_association?(node)
|
65
|
+
# @param node [RuboCop::AST::SendNode]
|
66
|
+
# @return [Boolean]
|
67
|
+
def_node_matcher :implicit_association?, <<~PATTERN
|
68
|
+
(send
|
69
|
+
nil?
|
70
|
+
!#non_implicit_association_method_name?
|
71
|
+
)
|
72
|
+
PATTERN
|
73
|
+
|
74
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
75
|
+
# @param node [RuboCop::AST::SendNode]
|
76
|
+
def autocorrect(
|
77
|
+
corrector,
|
78
|
+
node
|
79
|
+
)
|
80
|
+
case style
|
81
|
+
when :explicit
|
82
|
+
autocorrect_to_explicit_style(corrector, node)
|
83
|
+
when :implicit
|
84
|
+
autocorrect_to_implicit_style(corrector, node)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
89
|
+
# @param node [RuboCop::AST::SendNode]
|
90
|
+
# @return [void]
|
91
|
+
def autocorrect_to_explicit_style(
|
92
|
+
corrector,
|
93
|
+
node
|
94
|
+
)
|
95
|
+
corrector.replace(node, "association :#{node.method_name}")
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
99
|
+
# @param node [RuboCop::AST::SendNode]
|
100
|
+
# @return [void]
|
101
|
+
def autocorrect_to_implicit_style(
|
102
|
+
corrector,
|
103
|
+
node
|
104
|
+
)
|
105
|
+
corrector.replace(node, node.first_argument.value.to_s)
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param node [RuboCop::AST::SendNode]
|
109
|
+
# @return [Boolean]
|
110
|
+
def autocorrectable_to_implicit_style?(node)
|
111
|
+
node.arguments.one?
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param node [RuboCop::AST::SendNode]
|
115
|
+
# @return [Boolean]
|
116
|
+
def bad?(node)
|
117
|
+
case style
|
118
|
+
when :explicit
|
119
|
+
bad_to_explicit_style?(node)
|
120
|
+
when :implicit
|
121
|
+
bad_to_implicit_style?(node)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# @param node [RuboCop::AST::SendNode]
|
126
|
+
# @return [Array<RuboCop::AST::SendNode>]
|
127
|
+
def bad_associations_in(node)
|
128
|
+
children_of_factory_block(node).select do |child|
|
129
|
+
bad?(child)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# @param node [RuboCop::AST::SendNode]
|
134
|
+
# @return [Boolean]
|
135
|
+
def bad_to_explicit_style?(node)
|
136
|
+
implicit_association?(node)
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param node [RuboCop::AST::SendNode]
|
140
|
+
# @return [Boolean]
|
141
|
+
def bad_to_implicit_style?(node)
|
142
|
+
explicit_association?(node) && autocorrectable_to_implicit_style?(node)
|
143
|
+
end
|
144
|
+
|
145
|
+
# @param node [RuboCop::AST::SendNode]
|
146
|
+
# @return [Array<RuboCop::AST::Node>]
|
147
|
+
def children_of_factory_block(node)
|
148
|
+
block = node.parent
|
149
|
+
return [] unless block
|
150
|
+
return [] unless block.block_type?
|
151
|
+
|
152
|
+
if block.body.begin_type?
|
153
|
+
block.body.children
|
154
|
+
else
|
155
|
+
[block.body]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param method_name [Symbol]
|
160
|
+
# @return [Boolean]
|
161
|
+
def non_implicit_association_method_name?(method_name)
|
162
|
+
cop_config['NonImplicitAssociationMethodNames'].include?(method_name.to_s)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Activate a check constraint in a separate migration in PostgreSQL.
|
7
|
+
#
|
8
|
+
# Adding a check constraint without `NOT VALID` blocks reads and writes in Postgres and
|
9
|
+
# blocks writes in MySQL and MariaDB while every row is checked.
|
10
|
+
#
|
11
|
+
# @safety
|
12
|
+
# Only meaningful in PostgreSQL.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# class AddCheckConstraintToOrdersPrice < ActiveRecord::Migration[7.0]
|
17
|
+
# def change
|
18
|
+
# add_check_constraint :orders, 'price > 0', name: 'orders_price_positive'
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# class AddCheckConstraintToOrdersPriceWithoutValidation < ActiveRecord::Migration[7.0]
|
24
|
+
# def change
|
25
|
+
# add_check_constraint :orders, 'price > 0', name: 'orders_price_positive', validate: false
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# class ActivateCheckConstraintOnOrdersPrice < ActiveRecord::Migration[7.0]
|
30
|
+
# def change
|
31
|
+
# validate_check_constraint :orders, name: 'orders_price_positive'
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
class RailsMigrationAddCheckConstraint < RuboCop::Cop::Base
|
35
|
+
extend AutoCorrector
|
36
|
+
|
37
|
+
MSG = 'Activate a check constraint in a separate migration in PostgreSQL.'
|
38
|
+
|
39
|
+
RESTRICT_ON_SEND = %i[
|
40
|
+
add_check_constraint
|
41
|
+
].freeze
|
42
|
+
|
43
|
+
# @param node [RuboCop::AST::SendNode]
|
44
|
+
# @return [void]
|
45
|
+
def on_send(node)
|
46
|
+
return unless bad?(node)
|
47
|
+
|
48
|
+
add_offense(node) do |corrector|
|
49
|
+
autocorrect(corrector, node)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @!method add_check_constraint?(node)
|
56
|
+
# @param node [RuboCop::AST::SendNode]
|
57
|
+
# @return [Boolean]
|
58
|
+
def_node_matcher :add_check_constraint?, <<~PATTERN
|
59
|
+
(send
|
60
|
+
nil?
|
61
|
+
:add_check_constraint
|
62
|
+
...
|
63
|
+
)
|
64
|
+
PATTERN
|
65
|
+
|
66
|
+
# @!method add_check_constraint_with_validate_false?(node)
|
67
|
+
# @param node [RuboCop::AST::SendNode]
|
68
|
+
# @return [Boolean]
|
69
|
+
def_node_matcher :add_check_constraint_with_validate_false?, <<~PATTERN
|
70
|
+
(send
|
71
|
+
nil?
|
72
|
+
:add_check_constraint
|
73
|
+
_
|
74
|
+
_
|
75
|
+
(hash
|
76
|
+
<
|
77
|
+
(pair
|
78
|
+
(sym :validate)
|
79
|
+
false
|
80
|
+
)
|
81
|
+
...
|
82
|
+
>
|
83
|
+
)
|
84
|
+
)
|
85
|
+
PATTERN
|
86
|
+
|
87
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
88
|
+
# @param node [RuboCop::AST::SendNode]
|
89
|
+
# @return [void]
|
90
|
+
def autocorrect(
|
91
|
+
corrector,
|
92
|
+
node
|
93
|
+
)
|
94
|
+
target = node.last_argument
|
95
|
+
target = target.pairs.last if target.hash_type?
|
96
|
+
corrector.insert_after(
|
97
|
+
target,
|
98
|
+
', validate: false'
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param node [RuboCop::AST::SendNode]
|
103
|
+
# @return [Boolean]
|
104
|
+
def bad?(node)
|
105
|
+
add_check_constraint?(node) &&
|
106
|
+
!add_check_constraint_with_validate_false?(node)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|