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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d5fe85da04542f564b53e8c0d779c4258ca907f99a7583919aa02007d719f33
4
- data.tar.gz: 06bd03d9e0afdf5618ad2bdfffbfa2ac465821f65009e2c949051bd04e3defae
3
+ metadata.gz: fa5e7fda6eeffbf26f8c9bd1a4433a689416e0a2098ce9193f93c72564b8b4f2
4
+ data.tar.gz: 4907939dbd5ba1a39cf76d838824bfa8574fe527b6a8985588bd7897eb5a3a1c
5
5
  SHA512:
6
- metadata.gz: 5943d60b5a214eecc77d326cf94b7f44fb270592822687f05b7165ca4b6165086ae6491f523a27dab620fb3e83ee6c7e03058d14b93cbecbc9dcf1334c47f333
7
- data.tar.gz: 7b20c8d2766ff2803ae32a31f598e447fa5fd4282c9507fded7181d5c85d139fe8de603f6000e4dbe49c73b963a07f6cef12b8ec248eba925a621024086c2b86
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.3.2)
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.4)
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.1.10)
18
+ concurrent-ruby (1.2.2)
19
19
  diff-lcs (1.5.0)
20
- i18n (1.12.0)
20
+ i18n (1.14.1)
21
21
  concurrent-ruby (~> 1.0)
22
22
  json (2.6.2)
23
- minitest (5.16.3)
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.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.16.1)
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.5)
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
- ~~Install `rubocop-migration` gem:~~
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, github: 'r7kamura/rubocop-migration', tag: 'v0.3.1'
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: false
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 the following gem:
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
- - [ankane/strong_migrations](https://github.com/ankane/strong_migrations)
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
- return unless bad?(node)
47
+ if add_index_without_concurrency?(node)
48
+ add_offense(node) do |corrector|
49
+ autocorrect(corrector, node)
50
+ end
51
+ end
45
52
 
46
- add_offense(node) do |corrector|
47
- autocorrect(corrector, node)
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 [Boolean]
132
- def bad?(node)
133
- case node.method_name
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 in_second_migration?(node)
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
- table_name, column_name = parse_table_name_and_column_name(node)
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
- format(
95
- "add_check_constraint :%<table>s, '%<column>s IS NOT NULL', name: '%<constraint>s', validate: false",
96
- column: column_name,
97
- constraint: "#{table_name}_#{column_name}_is_not_null",
98
- table: table_name
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 called_after_validate_constraint?(node)
106
- node.left_siblings.any? do |sibling|
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 [Boolean]
113
- def called_before_remove_check_constraint?(node)
114
- node.right_siblings.any? do |sibling|
115
- remove_check_constraint?(sibling)
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 [Boolean]
121
- def in_second_migration?(node)
122
- called_after_validate_constraint?(node) ||
123
- called_before_remove_check_constraint?(node)
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.each_ancestor(:def).first&.left_siblings&.any? do |sibling|
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rubocop
4
4
  module Migration
5
- VERSION = '0.3.2'
5
+ VERSION = '0.4.1'
6
6
  end
7
7
  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.3.2
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: 2022-10-19 00:00:00.000000000 Z
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.7
120
+ rubygems_version: 3.3.26
122
121
  signing_key:
123
122
  specification_version: 4
124
123
  summary: RuboCop extension focused on ActiveRecord migration.
data/CHANGELOG.md DELETED
@@ -1,5 +0,0 @@
1
- ## [Unreleased]
2
-
3
- ## [0.1.0] - 2022-10-17
4
-
5
- - Initial release