rubocop-migration 0.3.2 → 0.4.1
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/Gemfile.lock +8 -8
- data/README.md +7 -8
- data/lib/rubocop/cop/migration/add_index_concurrently.rb +31 -11
- data/lib/rubocop/cop/migration/change_column_null.rb +117 -37
- data/lib/rubocop/migration/cop_concerns/disable_ddl_transaction.rb +10 -4
- data/lib/rubocop/migration/version.rb +1 -1
- metadata +3 -4
- data/CHANGELOG.md +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa5e7fda6eeffbf26f8c9bd1a4433a689416e0a2098ce9193f93c72564b8b4f2
|
4
|
+
data.tar.gz: 4907939dbd5ba1a39cf76d838824bfa8574fe527b6a8985588bd7897eb5a3a1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6885d3a799806f1a3699cf892eb2a9855b66b8d29f9578fe9a0d8f98e84ab0526683710a35b22dbb1601cc6b52c015421aa163c6f671a4366ceb3d5a582dedba
|
7
|
+
data.tar.gz: 8838e0d3758231c59a844e26d4b7795dd7abf74743a16f25075f9804f3de51248d2c6893614ecfdee8cdf075af46430b3723b3e10f62a57a39f42ef31b326489
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubocop-migration (0.
|
4
|
+
rubocop-migration (0.4.1)
|
5
5
|
activesupport
|
6
6
|
rubocop (>= 1.34)
|
7
7
|
rubocop-rails
|
@@ -9,22 +9,22 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activesupport (7.0.
|
12
|
+
activesupport (7.0.5)
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
14
|
i18n (>= 1.6, < 2)
|
15
15
|
minitest (>= 5.1)
|
16
16
|
tzinfo (~> 2.0)
|
17
17
|
ast (2.4.2)
|
18
|
-
concurrent-ruby (1.
|
18
|
+
concurrent-ruby (1.2.2)
|
19
19
|
diff-lcs (1.5.0)
|
20
|
-
i18n (1.
|
20
|
+
i18n (1.14.1)
|
21
21
|
concurrent-ruby (~> 1.0)
|
22
22
|
json (2.6.2)
|
23
|
-
minitest (5.
|
23
|
+
minitest (5.18.0)
|
24
24
|
parallel (1.22.1)
|
25
25
|
parser (3.1.2.1)
|
26
26
|
ast (~> 2.4.1)
|
27
|
-
rack (3.0.
|
27
|
+
rack (3.0.7)
|
28
28
|
rainbow (3.1.1)
|
29
29
|
rake (13.0.6)
|
30
30
|
regexp_parser (2.6.0)
|
@@ -57,7 +57,7 @@ GEM
|
|
57
57
|
rubocop-performance (1.15.0)
|
58
58
|
rubocop (>= 1.7.0, < 2.0)
|
59
59
|
rubocop-ast (>= 0.4.0)
|
60
|
-
rubocop-rails (2.
|
60
|
+
rubocop-rails (2.19.1)
|
61
61
|
activesupport (>= 4.2.0)
|
62
62
|
rack (>= 1.1)
|
63
63
|
rubocop (>= 1.33.0, < 2.0)
|
@@ -68,7 +68,7 @@ GEM
|
|
68
68
|
ruby-progressbar (1.11.0)
|
69
69
|
sevencop (0.21.0)
|
70
70
|
rubocop
|
71
|
-
tzinfo (2.0.
|
71
|
+
tzinfo (2.0.6)
|
72
72
|
concurrent-ruby (~> 1.0)
|
73
73
|
unicode-display_width (2.3.0)
|
74
74
|
|
data/README.md
CHANGED
@@ -6,14 +6,11 @@ RuboCop extension focused on ActiveRecord migration.
|
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
This gem is not yet published to rubygems.org.
|
12
|
-
See [#1](https://github.com/r7kamura/rubocop-migration/issues/1) for more details.
|
9
|
+
Install `rubocop-migration` gem:
|
13
10
|
|
14
11
|
```ruby
|
15
12
|
# Gemfile
|
16
|
-
gem 'rubocop-migration', require: false
|
13
|
+
gem 'rubocop-migration', require: false
|
17
14
|
```
|
18
15
|
|
19
16
|
then require `rubocop-migration` and enable the cops you want to use in your .rubocop.yml:
|
@@ -24,7 +21,7 @@ require:
|
|
24
21
|
- rubocop-migration
|
25
22
|
|
26
23
|
Migration/AddCheckConstraint:
|
27
|
-
Enabled:
|
24
|
+
Enabled: true
|
28
25
|
```
|
29
26
|
|
30
27
|
Note that all cops are `Enabled: false` by default.
|
@@ -53,6 +50,8 @@ Please read the comments of the respective cop classes for more information.
|
|
53
50
|
|
54
51
|
## Acknowledgements
|
55
52
|
|
56
|
-
This gem was heavily inspired by
|
53
|
+
This gem was heavily inspired by [ankane/strong_migrations](https://github.com/ankane/strong_migrations).
|
54
|
+
|
55
|
+
The gem `rubocop-migration` was originally developed at [wealthsimple/rubocop-migration](https://github.com/wealthsimple/rubocop-migration), and later the gem name was transferred to this repository.
|
57
56
|
|
58
|
-
|
57
|
+
Some cops were originally created at [r7kamura/sevencop](https://github.com/r7kamura/sevencop) then moved to this repository.
|
@@ -30,9 +30,12 @@ module RuboCop
|
|
30
30
|
extend AutoCorrector
|
31
31
|
|
32
32
|
include ::RuboCop::Migration::CopConcerns::DisableDdlTransaction
|
33
|
+
include RangeHelp
|
33
34
|
|
34
35
|
MSG = 'Use `algorithm: :concurrently` on adding indexes to existing tables in PostgreSQL.'
|
35
36
|
|
37
|
+
MESSAGE_FOR_DUPLICATED_DISABLE_DDL_TRANSACTION = 'Remove duplicated `disable_ddl_transaction!`.'
|
38
|
+
|
36
39
|
RESTRICT_ON_SEND = %i[
|
37
40
|
add_index
|
38
41
|
index
|
@@ -41,10 +44,21 @@ module RuboCop
|
|
41
44
|
# @param node [RuboCop::AST::SendNode]
|
42
45
|
# @return [void]
|
43
46
|
def on_send(node)
|
44
|
-
|
47
|
+
if add_index_without_concurrency?(node)
|
48
|
+
add_offense(node) do |corrector|
|
49
|
+
autocorrect(corrector, node)
|
50
|
+
end
|
51
|
+
end
|
45
52
|
|
46
|
-
|
47
|
-
|
53
|
+
duplicated_disable_ddl_transactions_from(node).each do |disable_ddl_transactions_node|
|
54
|
+
add_offense(node, message: MESSAGE_FOR_DUPLICATED_DISABLE_DDL_TRANSACTION) do |corrector|
|
55
|
+
corrector.remove(
|
56
|
+
range_with_surrounding_space(
|
57
|
+
disable_ddl_transactions_node.source_range,
|
58
|
+
side: :left
|
59
|
+
)
|
60
|
+
)
|
61
|
+
end
|
48
62
|
end
|
49
63
|
end
|
50
64
|
|
@@ -116,6 +130,17 @@ module RuboCop
|
|
116
130
|
)
|
117
131
|
PATTERN
|
118
132
|
|
133
|
+
# @param node [RuboCop::AST::SendNode]
|
134
|
+
# @return [Boolean]
|
135
|
+
def add_index_without_concurrency?(node)
|
136
|
+
case node.method_name
|
137
|
+
when :add_index
|
138
|
+
add_index?(node) && !add_index_concurrently?(node)
|
139
|
+
when :index
|
140
|
+
index?(node) && in_change_table?(node) && !index_concurrently?(node)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
119
144
|
# @param corrector [RuboCop::Cop::Corrector]
|
120
145
|
# @param node [RuboCop::AST::SendNode]
|
121
146
|
# @return [void]
|
@@ -128,14 +153,9 @@ module RuboCop
|
|
128
153
|
end
|
129
154
|
|
130
155
|
# @param node [RuboCop::AST::SendNode]
|
131
|
-
# @return [
|
132
|
-
def
|
133
|
-
|
134
|
-
when :add_index
|
135
|
-
add_index?(node) && !add_index_concurrently?(node)
|
136
|
-
when :index
|
137
|
-
index?(node) && in_change_table?(node) && !index_concurrently?(node)
|
138
|
-
end
|
156
|
+
# @return [Array<RuboCop::AST::SendNode>]
|
157
|
+
def duplicated_disable_ddl_transactions_from(node)
|
158
|
+
disable_ddl_transactions_from(node)[1..] || []
|
139
159
|
end
|
140
160
|
|
141
161
|
# @param node [RuboCop::AST::SendNode]
|
@@ -40,12 +40,13 @@ module RuboCop
|
|
40
40
|
|
41
41
|
RESTRICT_ON_SEND = %i[
|
42
42
|
change_column_null
|
43
|
+
change_null
|
43
44
|
].freeze
|
44
45
|
|
45
46
|
# @param node [RuboCop::AST::SendNode]
|
46
47
|
# @return [void]
|
47
48
|
def on_send(node)
|
48
|
-
return if
|
49
|
+
return if called_with_validate_constraint?(node)
|
49
50
|
|
50
51
|
add_offense(node) do |corrector|
|
51
52
|
autocorrect(corrector, node)
|
@@ -54,26 +55,6 @@ module RuboCop
|
|
54
55
|
|
55
56
|
private
|
56
57
|
|
57
|
-
# @!method parse_table_name_and_column_name(node)
|
58
|
-
# @param node [RuboCop::AST::SendNode]
|
59
|
-
# @return [Array<Symbol>, nil]
|
60
|
-
def_node_matcher :parse_table_name_and_column_name, <<~PATTERN
|
61
|
-
(send
|
62
|
-
nil?
|
63
|
-
_
|
64
|
-
({str sym} $_)
|
65
|
-
({str sym} $_)
|
66
|
-
...
|
67
|
-
)
|
68
|
-
PATTERN
|
69
|
-
|
70
|
-
# @!method remove_check_constraint?(node)
|
71
|
-
# @param node [RuboCop::AST::SendNode]
|
72
|
-
# @return [Boolean]
|
73
|
-
def_node_matcher :remove_check_constraint?, <<~PATTERN
|
74
|
-
(send nil? :remove_check_constraint ...)
|
75
|
-
PATTERN
|
76
|
-
|
77
58
|
# @!method validate_constraint?(node)
|
78
59
|
# @param node [RuboCop::AST::SendNode]
|
79
60
|
# @return [Boolean]
|
@@ -88,39 +69,138 @@ module RuboCop
|
|
88
69
|
corrector,
|
89
70
|
node
|
90
71
|
)
|
91
|
-
|
72
|
+
case node.method_name
|
73
|
+
when :change_column_null
|
74
|
+
autocorrect_change_column_null(corrector, node)
|
75
|
+
when :change_null
|
76
|
+
autocorrect_change_null(corrector, node)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
81
|
+
# @param node [RuboCop::AST::SendNode]
|
82
|
+
# @return [void]
|
83
|
+
def autocorrect_change_column_null(
|
84
|
+
corrector,
|
85
|
+
node
|
86
|
+
)
|
92
87
|
corrector.replace(
|
93
88
|
node,
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
89
|
+
format_add_check_constraint(
|
90
|
+
column_name: find_column_name_from_change_column_null(node),
|
91
|
+
table_name: find_table_name_from_change_column_null(node)
|
92
|
+
)
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
97
|
+
# @param node [RuboCop::AST::SendNode]
|
98
|
+
# @return [void]
|
99
|
+
def autocorrect_change_null(
|
100
|
+
corrector,
|
101
|
+
node
|
102
|
+
)
|
103
|
+
corrector.replace(
|
104
|
+
node.location.selector.with(
|
105
|
+
end_pos: node.location.expression.end_pos
|
106
|
+
),
|
107
|
+
format_check_constraint(
|
108
|
+
column_name: find_column_name_from_change_null(node),
|
109
|
+
table_name: find_table_name_from_change_null(node)
|
99
110
|
)
|
100
111
|
)
|
101
112
|
end
|
102
113
|
|
103
114
|
# @param node [RuboCop::AST::SendNode]
|
104
115
|
# @return [Boolean]
|
105
|
-
def
|
106
|
-
node.
|
116
|
+
def called_with_validate_constraint?(node)
|
117
|
+
case node.method_name
|
118
|
+
when :change_column_null
|
119
|
+
node
|
120
|
+
when :change_null
|
121
|
+
find_ancestor_change_table(node)
|
122
|
+
end.left_siblings.any? do |sibling|
|
107
123
|
validate_constraint?(sibling)
|
108
124
|
end
|
109
125
|
end
|
110
126
|
|
111
127
|
# @param node [RuboCop::AST::SendNode]
|
112
|
-
# @return [
|
113
|
-
def
|
114
|
-
node.
|
115
|
-
|
128
|
+
# @return [RuboCop::AST::BlockNode]
|
129
|
+
def find_ancestor_change_table(node)
|
130
|
+
node.each_ancestor(:block).find do |ancestor|
|
131
|
+
ancestor.method?(:change_table)
|
116
132
|
end
|
117
133
|
end
|
118
134
|
|
119
135
|
# @param node [RuboCop::AST::SendNode]
|
120
|
-
# @return [
|
121
|
-
def
|
122
|
-
|
123
|
-
|
136
|
+
# @return [String]
|
137
|
+
def find_column_name_from_change_column_null(node)
|
138
|
+
node.arguments[1].value.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param node [RuboCop::AST::SendNode]
|
142
|
+
# @return [String]
|
143
|
+
def find_column_name_from_change_null(node)
|
144
|
+
node.arguments[0].value.to_s
|
145
|
+
end
|
146
|
+
|
147
|
+
# @parm node [RuboCop::AST::SendNode]
|
148
|
+
# @return [String]
|
149
|
+
def find_table_name_from_change_column_null(node)
|
150
|
+
node.arguments[0].value.to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
# @param node [RuboCop::AST::SendNode]
|
154
|
+
# @return [String]
|
155
|
+
def find_table_name_from_change_null(node)
|
156
|
+
find_ancestor_change_table(node).send_node.arguments[0].value.to_s
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param column_name [String]
|
160
|
+
# @param table_name [String]
|
161
|
+
# @return [String]
|
162
|
+
def format_add_check_constraint(
|
163
|
+
column_name:,
|
164
|
+
table_name:
|
165
|
+
)
|
166
|
+
format(
|
167
|
+
'add_check_constraint :%<table_name>s, %<arguments>s',
|
168
|
+
arguments: format_check_constraint_arguments(
|
169
|
+
column_name: column_name,
|
170
|
+
table_name: table_name
|
171
|
+
),
|
172
|
+
table_name: table_name
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @param column_name [String]
|
177
|
+
# @param table_name [String]
|
178
|
+
# @return [String]
|
179
|
+
def format_check_constraint(
|
180
|
+
column_name:,
|
181
|
+
table_name:
|
182
|
+
)
|
183
|
+
format(
|
184
|
+
'check_constraint %<arguments>s',
|
185
|
+
arguments: format_check_constraint_arguments(
|
186
|
+
column_name: column_name,
|
187
|
+
table_name: table_name
|
188
|
+
)
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
# @param coumn_name [String]
|
193
|
+
# @param table_name [String]
|
194
|
+
# @return [String]
|
195
|
+
def format_check_constraint_arguments(
|
196
|
+
column_name:,
|
197
|
+
table_name:
|
198
|
+
)
|
199
|
+
format(
|
200
|
+
"'%<column_name>s IS NOT NULL', name: '%<constraint_name>s', validate: false",
|
201
|
+
column_name: column_name,
|
202
|
+
constraint_name: "#{table_name}_#{column_name}_is_not_null"
|
203
|
+
)
|
124
204
|
end
|
125
205
|
end
|
126
206
|
end
|
@@ -24,6 +24,15 @@ module RuboCop
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
+
# @param node [RuboCop::AST::SendNode]
|
28
|
+
# @return [Array<RuboCop::AST::SendNode>]
|
29
|
+
def disable_ddl_transactions_from(node)
|
30
|
+
node.each_ancestor(:def).first&.left_siblings&.select do |sibling|
|
31
|
+
sibling.is_a?(::RuboCop::AST::SendNode) &&
|
32
|
+
disable_ddl_transaction?(sibling)
|
33
|
+
end || []
|
34
|
+
end
|
35
|
+
|
27
36
|
# @param corrector [RuboCop::Cop::Corrector]
|
28
37
|
# @param node [RuboCop::AST::SendNode]
|
29
38
|
# @return [void]
|
@@ -40,10 +49,7 @@ module RuboCop
|
|
40
49
|
# @param node [RuboCop::AST::SendNode]
|
41
50
|
# @return [Boolean]
|
42
51
|
def within_disable_ddl_transaction?(node)
|
43
|
-
node
|
44
|
-
sibling.is_a?(::RuboCop::AST::SendNode) &&
|
45
|
-
disable_ddl_transaction?(sibling)
|
46
|
-
end
|
52
|
+
!disable_ddl_transactions_from(node).empty?
|
47
53
|
end
|
48
54
|
end
|
49
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-migration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -61,7 +61,6 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- ".rspec"
|
63
63
|
- ".rubocop.yml"
|
64
|
-
- CHANGELOG.md
|
65
64
|
- CODE_OF_CONDUCT.md
|
66
65
|
- Gemfile
|
67
66
|
- Gemfile.lock
|
@@ -118,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
117
|
- !ruby/object:Gem::Version
|
119
118
|
version: '0'
|
120
119
|
requirements: []
|
121
|
-
rubygems_version: 3.3.
|
120
|
+
rubygems_version: 3.3.26
|
122
121
|
signing_key:
|
123
122
|
specification_version: 4
|
124
123
|
summary: RuboCop extension focused on ActiveRecord migration.
|