sevencop 0.22.0 → 0.24.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +5 -16
  5. data/config/default.yml +16 -143
  6. data/lib/rubocop/cop/sevencop/rails_action_name.rb +61 -0
  7. data/lib/rubocop/cop/sevencop/rspec_describe_http_endpoint.rb +23 -10
  8. data/lib/sevencop/cop_concerns.rb +0 -3
  9. data/lib/sevencop/version.rb +1 -1
  10. data/lib/sevencop.rb +1 -16
  11. metadata +3 -21
  12. data/lib/rubocop/cop/sevencop/rails_migration_add_check_constraint.rb +0 -111
  13. data/lib/rubocop/cop/sevencop/rails_migration_add_column_with_default_value.rb +0 -229
  14. data/lib/rubocop/cop/sevencop/rails_migration_add_foreign_key.rb +0 -166
  15. data/lib/rubocop/cop/sevencop/rails_migration_add_index_concurrently.rb +0 -164
  16. data/lib/rubocop/cop/sevencop/rails_migration_batch_in_batches.rb +0 -95
  17. data/lib/rubocop/cop/sevencop/rails_migration_batch_in_transaction.rb +0 -83
  18. data/lib/rubocop/cop/sevencop/rails_migration_batch_with_throttling.rb +0 -108
  19. data/lib/rubocop/cop/sevencop/rails_migration_change_column.rb +0 -113
  20. data/lib/rubocop/cop/sevencop/rails_migration_change_column_null.rb +0 -128
  21. data/lib/rubocop/cop/sevencop/rails_migration_create_table_force.rb +0 -89
  22. data/lib/rubocop/cop/sevencop/rails_migration_jsonb.rb +0 -131
  23. data/lib/rubocop/cop/sevencop/rails_migration_remove_column.rb +0 -258
  24. data/lib/rubocop/cop/sevencop/rails_migration_rename_column.rb +0 -81
  25. data/lib/rubocop/cop/sevencop/rails_migration_rename_table.rb +0 -79
  26. data/lib/rubocop/cop/sevencop/rails_migration_reserved_word_mysql.rb +0 -232
  27. data/lib/rubocop/cop/sevencop/rails_migration_unique_index_columns_count.rb +0 -92
  28. data/lib/sevencop/cop_concerns/batch_processing.rb +0 -32
  29. data/lib/sevencop/cop_concerns/column_type_method.rb +0 -26
  30. data/lib/sevencop/cop_concerns/disable_ddl_transaction.rb +0 -49
@@ -1,229 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Add the column without a default value then change the default.
7
- #
8
- # In earlier versions of Postgres, MySQL, and MariaDB,
9
- # adding a column with a default value to an existing table causes the entire table to be rewritten.
10
- # During this time, reads and writes are blocked in Postgres, and writes are blocked in MySQL and MariaDB.
11
- #
12
- # @safety
13
- # Only meaningful in earlier versions of Postgres, MySQL, and MariaDB.
14
- #
15
- # @example
16
- # # bad
17
- # class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
18
- # def change
19
- # add_column :users, :some_column, :string, default: 'some value'
20
- # end
21
- # end
22
- #
23
- # # good
24
- # class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
25
- # def change
26
- # add_column :users, :some_column, :string
27
- # change_column_default :users, :some_column, 'some value'
28
- # end
29
- # end
30
- class RailsMigrationAddColumnWithDefaultValue < RuboCop::Cop::Base
31
- extend AutoCorrector
32
-
33
- include RangeHelp
34
- include ::Sevencop::CopConcerns::ColumnTypeMethod
35
-
36
- MSG = 'Add the column without a default value then change the default.'
37
-
38
- RESTRICT_ON_SEND = [
39
- :add_column,
40
- *COLUMN_TYPE_METHOD_NAMES
41
- ].freeze
42
-
43
- # @param node [RuboCop::AST::SendNode]
44
- # @return [void]
45
- def on_send(node)
46
- return unless target_method?(node)
47
-
48
- default_option_node = non_nil_default_option_node_from(node)
49
- return unless default_option_node
50
-
51
- add_offense(default_option_node) do |corrector|
52
- autocorrect(
53
- corrector,
54
- default_option_node: default_option_node,
55
- send_node: node
56
- )
57
- end
58
- end
59
-
60
- private
61
-
62
- # @!method add_column?(node)
63
- # @param node [RuboCop::AST::SendNode]
64
- # @return [Boolean]
65
- def_node_matcher :add_column?, <<~PATTERN
66
- (send
67
- nil?
68
- :add_column
69
- ...
70
- )
71
- PATTERN
72
-
73
- # @!method column_type_method?(node)
74
- # @param node [RuboCop::AST::SendNode]
75
- # @return [Boolean]
76
- def_node_matcher :column_type_method?, <<~PATTERN
77
- (send
78
- lvar
79
- COLUMN_TYPE_METHOD_NAMES
80
- ...
81
- )
82
- PATTERN
83
-
84
- # @!method non_nil_default_option_node_from(node)
85
- # @param node [RuboCop::AST::SendNode]
86
- # @return [RuboCop::AST::PairNode, nil]
87
- def_node_matcher :non_nil_default_option_node_from, <<~PATTERN
88
- (send
89
- _
90
- _
91
- ...
92
- (hash
93
- <
94
- $(pair
95
- (sym :default)
96
- !nil
97
- )
98
- >
99
- ...
100
- )
101
- )
102
- PATTERN
103
-
104
- # @param corrector [RuboCop::Cop::Corrector]
105
- # @param default_option_node [RuboCop::AST::PairNode]
106
- # @param send_node [RuboCop::AST::SendNode]
107
- # @return [void]
108
- def autocorrect(
109
- corrector,
110
- default_option_node:,
111
- send_node:
112
- )
113
- remove_pair(
114
- corrector,
115
- default_option_node
116
- )
117
- insert_change_column_default(
118
- corrector,
119
- default_option_node: default_option_node,
120
- send_node: send_node
121
- )
122
- end
123
-
124
- # @param node [RuboCop::AST::SendNode]
125
- # @return [RuboCop::AST::SymNode]
126
- def find_column_node_from(node)
127
- case node.method_name
128
- when :add_column
129
- node.arguments[1]
130
- else
131
- node.first_argument
132
- end
133
- end
134
-
135
- # @param node [RuboCop::AST::SendNode]
136
- # @return [RuboCop::AST::SendNode]
137
- def find_insertion_target_node_from(node)
138
- case node.method_name
139
- when :add_column
140
- node
141
- else
142
- node.each_ancestor(:block).first
143
- end
144
- end
145
-
146
- # @param node [RuboCop::AST::SendNode]
147
- # @return [RuboCop::AST::SymNode]
148
- def find_table_node_from(node)
149
- case node.method_name
150
- when :add_column
151
- node.first_argument
152
- else
153
- node.each_ancestor(:block).first.send_node.first_argument
154
- end
155
- end
156
-
157
- # @param node [RuboCop::AST::SendNode]
158
- # @return [Boolean]
159
- def in_change_table?(node)
160
- node.each_ancestor(:block).first&.method?(:change_table)
161
- end
162
-
163
- # @param corrector [RuboCop::Cop::Corrector]
164
- # @param node [RuboCop::AST::Node]
165
- # @param string [String]
166
- def insert_after_with_same_indentation(
167
- corrector,
168
- node,
169
- string
170
- )
171
- corrector.insert_after(
172
- node,
173
- format(
174
- "\n%<indentation>s%<string>s",
175
- indentation: ' ' * node.location.column,
176
- string: string
177
- )
178
- )
179
- end
180
-
181
- # @param corrector [RuboCop::Cop::Corrector]
182
- # @param default_option_node [RuboCop::AST::PairNode]
183
- # @param send_node [RuboCop::AST::SendNode]
184
- # @return [void]
185
- def insert_change_column_default(
186
- corrector,
187
- default_option_node:,
188
- send_node:
189
- )
190
- insert_after_with_same_indentation(
191
- corrector,
192
- find_insertion_target_node_from(send_node),
193
- format(
194
- 'change_column_default %<table>s, %<column>s, %<default>s',
195
- column: find_column_node_from(send_node).source,
196
- default: default_option_node.value.source,
197
- table: find_table_node_from(send_node).source
198
- )
199
- )
200
- end
201
-
202
- # @param corrector [RuboCop::Cop::Corrector]
203
- # @param node [RuboCop::AST::Node]
204
- # @return [void]
205
- def remove_pair(
206
- corrector,
207
- node
208
- )
209
- corrector.remove(
210
- range_with_surrounding_comma(
211
- range_with_surrounding_space(
212
- node.location.expression,
213
- side: :left
214
- ),
215
- :left
216
- )
217
- )
218
- end
219
-
220
- # @param node [RuboCop::AST::SendNode]
221
- # @return [Boolean]
222
- def target_method?(node)
223
- add_column?(node) ||
224
- (column_type_method?(node) && in_change_table?(node))
225
- end
226
- end
227
- end
228
- end
229
- end
@@ -1,166 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Activate foreign key validation in a separate migration in PostgreSQL.
7
- #
8
- # To avoid blocking writes on both tables.
9
- #
10
- # @safety
11
- # Only meaningful in PostgreSQL.
12
- #
13
- # @example
14
- # # bad
15
- # class AddForeignKeyFromArticlesToUsers < ActiveRecord::Migration[7.0]
16
- # def change
17
- # add_foreign_key :articles, :users
18
- # end
19
- # end
20
- #
21
- # # good
22
- # class AddForeignKeyFromArticlesToUsersWithoutValidation < ActiveRecord::Migration[7.0]
23
- # def change
24
- # add_foreign_key :articles, :users, validate: false
25
- # end
26
- # end
27
- #
28
- # class ActivateForeignKeyValidationFromArticlesToUsers < ActiveRecord::Migration[7.0]
29
- # def change
30
- # validate_foreign_key :articles, :users
31
- # end
32
- # end
33
- class RailsMigrationAddForeignKey < RuboCop::Cop::Base
34
- extend AutoCorrector
35
-
36
- include RangeHelp
37
-
38
- MSG = 'Activate foreign key validation in a separate migration in PostgreSQL.'
39
-
40
- RESTRICT_ON_SEND = %i[
41
- add_foreign_key
42
- add_reference
43
- ].freeze
44
-
45
- # @param node [RuboCop::AST::SendNode]
46
- # @return [void]
47
- def on_send(node)
48
- return unless bad?(node)
49
-
50
- add_offense(node) do |corrector|
51
- autocorrect(corrector, node)
52
- end
53
- end
54
-
55
- private
56
-
57
- # @!method add_foreign_key_without_validate_option?(node)
58
- # @param node [RuboCop::AST::SendNode]
59
- # @return [Boolean]
60
- def_node_matcher :add_foreign_key_without_validate_option?, <<~PATTERN
61
- (send
62
- nil?
63
- :add_foreign_key
64
- _
65
- _
66
- (hash
67
- (pair
68
- !(sym :validate)
69
- _
70
- )*
71
- )?
72
- )
73
- PATTERN
74
-
75
- # @!method option_validate_true_value_node_from_add_foreign_key(node)
76
- # @param node [RuboCop::AST::SendNode]
77
- # @return [RuboCop::AST::PairNode]
78
- def_node_matcher :option_validate_true_value_node_from_add_foreign_key, <<~PATTERN
79
- (send
80
- nil?
81
- :add_foreign_key
82
- _
83
- _
84
- (hash
85
- <
86
- (pair
87
- (sym :validate)
88
- $true
89
- )
90
- ...
91
- >
92
- )
93
- )
94
- PATTERN
95
-
96
- # @!method option_foreign_key_true_node_from_add_reference(node)
97
- # @param node [RuboCop::AST::SendNode]
98
- # @return [RuboCop::AST::PairNode]
99
- def_node_matcher :option_foreign_key_true_node_from_add_reference, <<~PATTERN
100
- (send
101
- nil?
102
- :add_reference
103
- _
104
- _
105
- (hash
106
- <
107
- $(pair
108
- (sym :foreign_key)
109
- true
110
- )
111
- ...
112
- >
113
- )
114
- )
115
- PATTERN
116
-
117
- # @param node [RuboCop::AST::SendNode]
118
- # @return [Boolean]
119
- def add_foreign_key_with_validate_option_true?(node)
120
- option_validate_true_value_node_from_add_foreign_key(node)
121
- end
122
-
123
- # @param node [RuboCop::AST::SendNode]
124
- # @return [Boolean]
125
- def add_reference_with_validate_option_true?(node)
126
- option_foreign_key_true_node_from_add_reference(node)
127
- end
128
-
129
- # @param corrector [RuboCop::Cop::Corrector]
130
- # @param node [RuboCop::AST::SendNode]
131
- # @return [void]
132
- def autocorrect(
133
- corrector,
134
- node
135
- )
136
- if add_foreign_key_without_validate_option?(node)
137
- corrector.insert_after(node.last_argument, ', validate: false')
138
- elsif add_foreign_key_with_validate_option_true?(node)
139
- corrector.replace(
140
- option_validate_true_value_node_from_add_foreign_key(node),
141
- 'false'
142
- )
143
- elsif add_reference_with_validate_option_true?(node)
144
- corrector.remove(
145
- range_with_surrounding_comma(
146
- range_with_surrounding_space(
147
- option_foreign_key_true_node_from_add_reference(node).location.expression,
148
- side: :left
149
- ),
150
- :left
151
- )
152
- )
153
- end
154
- end
155
-
156
- # @param node [RuboCop::AST::SendNode]
157
- # @return [Boolean]
158
- def bad?(node)
159
- add_foreign_key_without_validate_option?(node) ||
160
- add_foreign_key_with_validate_option_true?(node) ||
161
- add_reference_with_validate_option_true?(node)
162
- end
163
- end
164
- end
165
- end
166
- end
@@ -1,164 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Use `algorithm: :concurrently` on adding indexes to existing tables in PostgreSQL.
7
- #
8
- # To avoid blocking writes.
9
- #
10
- # @safety
11
- # Only meaningful in PostgreSQL.
12
- #
13
- # @example
14
- # # bad
15
- # class AddIndexToUsersName < ActiveRecord::Migration[7.0]
16
- # def change
17
- # add_index :users, :name
18
- # end
19
- # end
20
- #
21
- # # good
22
- # class AddIndexToUsersNameConcurrently < ActiveRecord::Migration[7.0]
23
- # disable_ddl_transaction!
24
- #
25
- # def change
26
- # add_index :users, :name, algorithm: :concurrently
27
- # end
28
- # end
29
- class RailsMigrationAddIndexConcurrently < RuboCop::Cop::Base
30
- extend AutoCorrector
31
-
32
- include ::Sevencop::CopConcerns::DisableDdlTransaction
33
-
34
- MSG = 'Use `algorithm: :concurrently` on adding indexes to existing tables in PostgreSQL.'
35
-
36
- RESTRICT_ON_SEND = %i[
37
- add_index
38
- index
39
- ].freeze
40
-
41
- # @param node [RuboCop::AST::SendNode]
42
- # @return [void]
43
- def on_send(node)
44
- return unless bad?(node)
45
-
46
- add_offense(node) do |corrector|
47
- autocorrect(corrector, node)
48
- end
49
- end
50
-
51
- private
52
-
53
- # @!method add_index?(node)
54
- # @param node [RuboCop::AST::SendNode]
55
- # @return [Boolean]
56
- def_node_matcher :add_index?, <<~PATTERN
57
- (send
58
- nil?
59
- :add_index
60
- _
61
- _
62
- ...
63
- )
64
- PATTERN
65
-
66
- # @!method add_index_concurrently?(node)
67
- # @param node [RuboCop::AST::SendNode]
68
- # @return [Boolean]
69
- def_node_matcher :add_index_concurrently?, <<~PATTERN
70
- (send
71
- nil?
72
- :add_index
73
- _
74
- _
75
- (hash
76
- <
77
- (pair
78
- (sym :algorithm)
79
- (sym :concurrently)
80
- )
81
- ...
82
- >
83
- )
84
- )
85
- PATTERN
86
-
87
- # @!method index?(node)
88
- # @param node [RuboCop::AST::SendNode]
89
- # @return [Boolean]
90
- def_node_matcher :index?, <<~PATTERN
91
- (send
92
- lvar
93
- :index
94
- _
95
- ...
96
- )
97
- PATTERN
98
-
99
- # @!method index_concurrently?(node)
100
- # @param node [RuboCop::AST::SendNode]
101
- # @return [Boolean]
102
- def_node_matcher :index_concurrently?, <<~PATTERN
103
- (send
104
- lvar
105
- :index
106
- _
107
- (hash
108
- <
109
- (pair
110
- (sym :algorithm)
111
- (sym :concurrently)
112
- )
113
- ...
114
- >
115
- )
116
- )
117
- PATTERN
118
-
119
- # @param corrector [RuboCop::Cop::Corrector]
120
- # @param node [RuboCop::AST::SendNode]
121
- # @return [void]
122
- def autocorrect(
123
- corrector,
124
- node
125
- )
126
- insert_disable_ddl_transaction(corrector, node) unless within_disable_ddl_transaction?(node)
127
- insert_algorithm_option(corrector, node)
128
- end
129
-
130
- # @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
139
- end
140
-
141
- # @param node [RuboCop::AST::SendNode]
142
- # @return [Boolean]
143
- def in_change_table?(node)
144
- node.each_ancestor(:block).first&.method?(:change_table)
145
- end
146
-
147
- # @param corrector [RuboCop::Cop::Corrector]
148
- # @param node [RuboCop::AST::SendNode]
149
- # @return [void]
150
- def insert_algorithm_option(
151
- corrector,
152
- node
153
- )
154
- target_node = node.last_argument
155
- target_node = target_node.pairs.last if target_node.hash_type?
156
- corrector.insert_after(
157
- target_node,
158
- ', algorithm: :concurrently'
159
- )
160
- end
161
- end
162
- end
163
- end
164
- end
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Use `in_batches` in batch processing.
7
- #
8
- # For more efficient batch processing.
9
- #
10
- # @safety
11
- # There are some cases where we should not do that,
12
- # or this type of consideration might be already done in a way that we cannot detect.
13
- #
14
- # @example
15
- # # bad
16
- # class BackfillSomeColumn < ActiveRecord::Migration[7.0]
17
- # disable_ddl_transaction!
18
- #
19
- # def change
20
- # User.update_all(some_column: 'some value')
21
- # end
22
- # end
23
- #
24
- # # good
25
- # class BackfillSomeColumnToUsers < ActiveRecord::Migration[7.0]
26
- # disable_ddl_transaction!
27
- #
28
- # def up
29
- # User.within_in_batches do |relation|
30
- # relation.update_all(some_column: 'some value')
31
- # end
32
- # end
33
- # end
34
- class RailsMigrationBatchInBatches < RuboCop::Cop::Base
35
- extend AutoCorrector
36
-
37
- include ::Sevencop::CopConcerns::BatchProcessing
38
-
39
- MSG = 'Use `in_batches` in batch processing.'
40
-
41
- RESTRICT_ON_SEND = %i[
42
- delete_all
43
- update_all
44
- ].freeze
45
-
46
- # @param node [RuboCop::AST::SendNode]
47
- # @return [void]
48
- def on_send(node)
49
- return unless wrong?(node)
50
-
51
- add_offense(node) do |corrector|
52
- autocorrect(corrector, node)
53
- end
54
- end
55
-
56
- private
57
-
58
- # @param corrector [RuboCop::Cop::Corrector]
59
- # @param node [RuboCop::AST::SendNode]
60
- # @return [void]
61
- def autocorrect(
62
- corrector,
63
- node
64
- )
65
- range = node.location.selector.with(
66
- end_pos: node.location.expression.end_pos
67
- )
68
- corrector.replace(
69
- range,
70
- <<~TEXT.chomp
71
- in_batches do |relation|
72
- relation.#{range.source}
73
- end
74
- TEXT
75
- )
76
- end
77
-
78
- # @param node [RuboCop::AST::Node]
79
- # @return [Boolean]
80
- def within_in_batches?(node)
81
- node.each_ancestor(:block).any? do |ancestor|
82
- ancestor.method?(:in_batches)
83
- end
84
- end
85
-
86
- # @param node [RuboCop::AST::SendNode]
87
- # @return [Boolean]
88
- def wrong?(node)
89
- batch_processing?(node) &&
90
- !within_in_batches?(node)
91
- end
92
- end
93
- end
94
- end
95
- end