rubocop-migration 0.2.0 → 0.4.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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +58 -0
  3. data/CODE_OF_CONDUCT.md +84 -0
  4. data/Gemfile +11 -1
  5. data/Gemfile.lock +89 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +42 -18
  8. data/Rakefile +9 -3
  9. data/config/default.yml +151 -0
  10. data/data/reserved_words_mysql.txt +750 -0
  11. data/lib/rubocop/cop/migration/add_check_constraint.rb +111 -0
  12. data/lib/rubocop/cop/migration/add_column_with_default_value.rb +229 -0
  13. data/lib/rubocop/cop/migration/add_foreign_key.rb +166 -0
  14. data/lib/rubocop/cop/migration/add_index_columns_count.rb +114 -0
  15. data/lib/rubocop/cop/migration/add_index_concurrently.rb +164 -0
  16. data/lib/rubocop/cop/migration/add_index_duplicate.rb +183 -0
  17. data/lib/rubocop/cop/migration/batch_in_batches.rb +95 -0
  18. data/lib/rubocop/cop/migration/batch_in_transaction.rb +83 -0
  19. data/lib/rubocop/cop/migration/batch_with_throttling.rb +108 -0
  20. data/lib/rubocop/cop/migration/change_column.rb +113 -0
  21. data/lib/rubocop/cop/migration/change_column_null.rb +208 -0
  22. data/lib/rubocop/cop/migration/create_table_force.rb +89 -0
  23. data/lib/rubocop/cop/migration/jsonb.rb +131 -0
  24. data/lib/rubocop/cop/migration/remove_column.rb +246 -0
  25. data/lib/rubocop/cop/migration/rename_column.rb +81 -0
  26. data/lib/rubocop/cop/migration/rename_table.rb +79 -0
  27. data/lib/rubocop/cop/migration/reserved_word_mysql.rb +232 -0
  28. data/lib/rubocop/migration/config_loader.rb +51 -0
  29. data/lib/rubocop/migration/cop_concerns/batch_processing.rb +34 -0
  30. data/lib/rubocop/migration/cop_concerns/column_type_method.rb +28 -0
  31. data/lib/rubocop/migration/cop_concerns/disable_ddl_transaction.rb +51 -0
  32. data/lib/rubocop/migration/cop_concerns.rb +11 -0
  33. data/lib/rubocop/migration/rubocop_extension.rb +15 -0
  34. data/lib/rubocop/migration/version.rb +4 -2
  35. data/lib/rubocop/migration.rb +23 -0
  36. data/rubocop-migration.gemspec +25 -31
  37. metadata +49 -137
  38. data/.gitignore +0 -15
  39. data/bin/console +0 -14
  40. data/bin/setup +0 -8
  41. data/circle.yml +0 -6
  42. data/lib/rubocop/cop/migration/unsafe_migration.rb +0 -69
  43. data/lib/rubocop/migration/strong_migrations_checker.rb +0 -47
  44. data/lib/rubocop-migration.rb +0 -16
  45. data/vendor/.gitkeep +0 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Migration
5
+ module CopConcerns
6
+ module BatchProcessing
7
+ BATCH_PROCESSING_METHOD_NAMES = ::Set.new(
8
+ %i[
9
+ delete_all
10
+ update_all
11
+ ]
12
+ ).freeze
13
+
14
+ class << self
15
+ def included(klass)
16
+ super
17
+ klass.class_eval do
18
+ # @!method batch_processing?(node)
19
+ # @param node [RuboCop::AST::SendNode]
20
+ # @return [Boolean]
21
+ def_node_matcher :batch_processing?, <<~PATTERN
22
+ (send
23
+ !nil?
24
+ BATCH_PROCESSING_METHOD_NAMES
25
+ ...
26
+ )
27
+ PATTERN
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Migration
5
+ module CopConcerns
6
+ module ColumnTypeMethod
7
+ COLUMN_TYPE_METHOD_NAMES = ::Set.new(
8
+ %i[
9
+ bigint
10
+ binary
11
+ blob
12
+ boolean
13
+ date
14
+ datetime
15
+ decimal
16
+ float
17
+ integer
18
+ numeric
19
+ primary_key
20
+ string
21
+ text
22
+ time
23
+ ]
24
+ ).freeze
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Migration
5
+ module CopConcerns
6
+ module DisableDdlTransaction
7
+ class << self
8
+ def included(klass)
9
+ super
10
+ klass.class_eval do
11
+ # @!method disable_ddl_transaction?(node)
12
+ # @param node [RuboCop::AST::SendNode]
13
+ # @return [Boolean]
14
+ def_node_matcher :disable_ddl_transaction?, <<~PATTERN
15
+ (send
16
+ nil?
17
+ :disable_ddl_transaction!
18
+ ...
19
+ )
20
+ PATTERN
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ # @param corrector [RuboCop::Cop::Corrector]
28
+ # @param node [RuboCop::AST::SendNode]
29
+ # @return [void]
30
+ def insert_disable_ddl_transaction(
31
+ corrector,
32
+ node
33
+ )
34
+ corrector.insert_before(
35
+ node.each_ancestor(:def).first,
36
+ "disable_ddl_transaction!\n\n "
37
+ )
38
+ end
39
+
40
+ # @param node [RuboCop::AST::SendNode]
41
+ # @return [Boolean]
42
+ 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
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Migration
5
+ module CopConcerns
6
+ autoload :BatchProcessing, 'rubocop/migration/cop_concerns/batch_processing'
7
+ autoload :ColumnTypeMethod, 'rubocop/migration/cop_concerns/column_type_method'
8
+ autoload :DisableDdlTransaction, 'rubocop/migration/cop_concerns/disable_ddl_transaction'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop'
4
+
5
+ require_relative 'config_loader'
6
+
7
+ RuboCop::ConfigLoader.instance_variable_set(
8
+ :@default_configuration,
9
+ RuboCop::Migration::ConfigLoader.call(
10
+ path: ::File.expand_path(
11
+ '../../../config/default.yml',
12
+ __dir__
13
+ )
14
+ )
15
+ )
@@ -1,5 +1,7 @@
1
- module RuboCop
1
+ # frozen_string_literal: true
2
+
3
+ module Rubocop
2
4
  module Migration
3
- VERSION = "0.2.0"
5
+ VERSION = '0.4.0'
4
6
  end
5
7
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'migration/cop_concerns'
4
+ require_relative 'migration/rubocop_extension'
5
+ require_relative 'migration/version'
6
+
7
+ require_relative 'cop/migration/add_check_constraint'
8
+ require_relative 'cop/migration/add_column_with_default_value'
9
+ require_relative 'cop/migration/add_foreign_key'
10
+ require_relative 'cop/migration/add_index_columns_count'
11
+ require_relative 'cop/migration/add_index_concurrently'
12
+ require_relative 'cop/migration/add_index_duplicate'
13
+ require_relative 'cop/migration/batch_in_batches'
14
+ require_relative 'cop/migration/batch_in_transaction'
15
+ require_relative 'cop/migration/batch_with_throttling'
16
+ require_relative 'cop/migration/change_column'
17
+ require_relative 'cop/migration/change_column_null'
18
+ require_relative 'cop/migration/create_table_force'
19
+ require_relative 'cop/migration/jsonb'
20
+ require_relative 'cop/migration/remove_column'
21
+ require_relative 'cop/migration/rename_column'
22
+ require_relative 'cop/migration/rename_table'
23
+ require_relative 'cop/migration/reserved_word_mysql'
@@ -1,38 +1,32 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "rubocop/migration/version"
1
+ # frozen_string_literal: true
5
2
 
6
- Gem::Specification.new do |spec|
7
- spec.name = "rubocop-migration"
8
- spec.version = RuboCop::Migration::VERSION
9
- spec.authors = ["Peter Graham"]
10
- spec.email = ["peter@wealthsimple.com"]
3
+ require_relative 'lib/rubocop/migration/version'
11
4
 
12
- spec.summary = %q{RuboCop extension for ActiveRecord migrations.}
13
- spec.description = %q{RuboCop extension to catch common pitfalls in ActiveRecord migrations.}
14
- spec.homepage = "https://github.com/wealthsimple/rubocop-migration"
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'rubocop-migration'
7
+ spec.version = Rubocop::Migration::VERSION
8
+ spec.authors = ['Ryo Nakamura']
9
+ spec.email = ['r7kamura@gmail.com']
15
10
 
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
18
- end
19
- spec.bindir = "exe"
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ["lib"]
22
- spec.license = "MIT"
11
+ spec.summary = 'RuboCop extension focused on ActiveRecord migration.'
12
+ spec.homepage = 'https://github.com/r7kamura/rubocop-migration'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '>= 2.7'
23
15
 
24
- spec.required_ruby_version = ">= 2.3.0"
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = spec.homepage
18
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
25
19
 
26
- spec.add_dependency "activesupport", ">= 4"
27
- spec.add_dependency "activerecord", ">= 4"
28
- spec.add_dependency "strong_migrations", "~> 0.1"
29
- spec.add_dependency "rubocop", ">= 0.48.0"
20
+ spec.files = Dir.chdir(__dir__) do
21
+ `git ls-files -z`.split("\x0").reject do |f|
22
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
23
+ end
24
+ end
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
30
28
 
31
- spec.add_development_dependency "bundler", "~> 1.14"
32
- spec.add_development_dependency "rake", "~> 10.0"
33
- spec.add_development_dependency "rspec", "~> 3.0"
34
- spec.add_development_dependency "rspec-its"
35
- spec.add_development_dependency "rspec-collection_matchers"
36
- spec.add_development_dependency "rspec_junit_formatter", "~> 0.2"
37
- spec.add_development_dependency "pry"
29
+ spec.add_dependency 'activesupport'
30
+ spec.add_dependency 'rubocop', '>= 1.34'
31
+ spec.add_dependency 'rubocop-rails'
38
32
  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.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
- - Peter Graham
7
+ - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-10 00:00:00.000000000 Z
11
+ date: 2022-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,179 +16,92 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '4'
27
- - !ruby/object:Gem::Dependency
28
- name: activerecord
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '4'
19
+ version: '0'
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - ">="
39
25
  - !ruby/object:Gem::Version
40
- version: '4'
41
- - !ruby/object:Gem::Dependency
42
- name: strong_migrations
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.1'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.1'
26
+ version: '0'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: rubocop
57
29
  requirement: !ruby/object:Gem::Requirement
58
30
  requirements:
59
31
  - - ">="
60
32
  - !ruby/object:Gem::Version
61
- version: 0.48.0
33
+ version: '1.34'
62
34
  type: :runtime
63
35
  prerelease: false
64
36
  version_requirements: !ruby/object:Gem::Requirement
65
37
  requirements:
66
38
  - - ">="
67
39
  - !ruby/object:Gem::Version
68
- version: 0.48.0
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.14'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.14'
40
+ version: '1.34'
83
41
  - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '10.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '10.0'
97
- - !ruby/object:Gem::Dependency
98
- name: rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '3.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '3.0'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec-its
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rspec-collection_matchers
42
+ name: rubocop-rails
127
43
  requirement: !ruby/object:Gem::Requirement
128
44
  requirements:
129
45
  - - ">="
130
46
  - !ruby/object:Gem::Version
131
47
  version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: rspec_junit_formatter
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.2'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '0.2'
153
- - !ruby/object:Gem::Dependency
154
- name: pry
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
48
+ type: :runtime
161
49
  prerelease: false
162
50
  version_requirements: !ruby/object:Gem::Requirement
163
51
  requirements:
164
52
  - - ">="
165
53
  - !ruby/object:Gem::Version
166
54
  version: '0'
167
- description: RuboCop extension to catch common pitfalls in ActiveRecord migrations.
55
+ description:
168
56
  email:
169
- - peter@wealthsimple.com
57
+ - r7kamura@gmail.com
170
58
  executables: []
171
59
  extensions: []
172
60
  extra_rdoc_files: []
173
61
  files:
174
- - ".gitignore"
175
62
  - ".rspec"
63
+ - ".rubocop.yml"
64
+ - CODE_OF_CONDUCT.md
176
65
  - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
177
68
  - README.md
178
69
  - Rakefile
179
- - bin/console
180
- - bin/setup
181
- - circle.yml
182
- - lib/rubocop-migration.rb
183
- - lib/rubocop/cop/migration/unsafe_migration.rb
184
- - lib/rubocop/migration/strong_migrations_checker.rb
70
+ - config/default.yml
71
+ - data/reserved_words_mysql.txt
72
+ - lib/rubocop/cop/migration/add_check_constraint.rb
73
+ - lib/rubocop/cop/migration/add_column_with_default_value.rb
74
+ - lib/rubocop/cop/migration/add_foreign_key.rb
75
+ - lib/rubocop/cop/migration/add_index_columns_count.rb
76
+ - lib/rubocop/cop/migration/add_index_concurrently.rb
77
+ - lib/rubocop/cop/migration/add_index_duplicate.rb
78
+ - lib/rubocop/cop/migration/batch_in_batches.rb
79
+ - lib/rubocop/cop/migration/batch_in_transaction.rb
80
+ - lib/rubocop/cop/migration/batch_with_throttling.rb
81
+ - lib/rubocop/cop/migration/change_column.rb
82
+ - lib/rubocop/cop/migration/change_column_null.rb
83
+ - lib/rubocop/cop/migration/create_table_force.rb
84
+ - lib/rubocop/cop/migration/jsonb.rb
85
+ - lib/rubocop/cop/migration/remove_column.rb
86
+ - lib/rubocop/cop/migration/rename_column.rb
87
+ - lib/rubocop/cop/migration/rename_table.rb
88
+ - lib/rubocop/cop/migration/reserved_word_mysql.rb
89
+ - lib/rubocop/migration.rb
90
+ - lib/rubocop/migration/config_loader.rb
91
+ - lib/rubocop/migration/cop_concerns.rb
92
+ - lib/rubocop/migration/cop_concerns/batch_processing.rb
93
+ - lib/rubocop/migration/cop_concerns/column_type_method.rb
94
+ - lib/rubocop/migration/cop_concerns/disable_ddl_transaction.rb
95
+ - lib/rubocop/migration/rubocop_extension.rb
185
96
  - lib/rubocop/migration/version.rb
186
97
  - rubocop-migration.gemspec
187
- - vendor/.gitkeep
188
- homepage: https://github.com/wealthsimple/rubocop-migration
98
+ homepage: https://github.com/r7kamura/rubocop-migration
189
99
  licenses:
190
100
  - MIT
191
- metadata: {}
101
+ metadata:
102
+ homepage_uri: https://github.com/r7kamura/rubocop-migration
103
+ source_code_uri: https://github.com/r7kamura/rubocop-migration
104
+ changelog_uri: https://github.com/r7kamura/rubocop-migration/releases
192
105
  post_install_message:
193
106
  rdoc_options: []
194
107
  require_paths:
@@ -197,16 +110,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
110
  requirements:
198
111
  - - ">="
199
112
  - !ruby/object:Gem::Version
200
- version: 2.3.0
113
+ version: '2.7'
201
114
  required_rubygems_version: !ruby/object:Gem::Requirement
202
115
  requirements:
203
116
  - - ">="
204
117
  - !ruby/object:Gem::Version
205
118
  version: '0'
206
119
  requirements: []
207
- rubyforge_project:
208
- rubygems_version: 2.5.1
120
+ rubygems_version: 3.3.7
209
121
  signing_key:
210
122
  specification_version: 4
211
- summary: RuboCop extension for ActiveRecord migrations.
123
+ summary: RuboCop extension focused on ActiveRecord migration.
212
124
  test_files: []
data/.gitignore DELETED
@@ -1,15 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- # rspec failure tracking
12
- .rspec_status
13
-
14
- /vendor/rubocop
15
- *.gem
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "rubocop-migration"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/circle.yml DELETED
@@ -1,6 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.3.0
4
- dependencies:
5
- pre:
6
- - git clone --depth 1 git://github.com/bbatsov/rubocop.git vendor/rubocop
@@ -1,69 +0,0 @@
1
- module RuboCop
2
- module Cop
3
- module Migration
4
- class UnsafeMigration < Cop
5
- # List of all public methods that can be used within a migration method,
6
- # like `add_index`, `rename_table`, etc.
7
- SCHEMA_STATEMENTS = ActiveRecord::ConnectionAdapters::SchemaStatements
8
- .public_instance_methods
9
- .freeze
10
- SCHEMA_STATEMENTS_PATTERN = SCHEMA_STATEMENTS.map { |s| ":#{s}" }.join(" ")
11
-
12
- ERROR_NOTICE = "Ignore this warning by inserting `# rubocop:disable UnsafeMigration`\nabove your code and `# rubocop:enable UnsafeMigration` below code.".freeze
13
-
14
- # Match `ActiveRecord::Migration` and `ActiveRecord::Migration[5.0]`
15
- def_node_matcher :migration_class?, <<-PATTERN
16
- {
17
- (class
18
- (const nil _)
19
- (const
20
- (const nil :ActiveRecord) :Migration) ...)
21
-
22
- (class
23
- (const nil _)
24
- (send
25
- (const
26
- (const nil :ActiveRecord) :Migration) :[] _) ...)
27
- }
28
- PATTERN
29
-
30
- # `down` migrations can be ignored as they should not be run in
31
- # production environments per:
32
- # https://github.com/ankane/strong_migrations/commit/fcfbcb4b1bef6a1ed9ec4808268ed0e684ec4389
33
- def_node_matcher :migration_method_match, <<-PATTERN
34
- (def {:change :up} args $...)
35
- PATTERN
36
-
37
- def_node_search :schema_statement_match, <<-PATTERN
38
- $(send nil ${#{SCHEMA_STATEMENTS_PATTERN}} $...)
39
- PATTERN
40
-
41
- def investigate(processed_source)
42
- ast = processed_source.ast
43
- return if !ast || !migration_class?(ast)
44
- ast.each_child_node do |child_node|
45
- migration_methods = migration_method_match(child_node)
46
- migration_methods&.each { |method_node| investigate_migration_method(method_node) }
47
- end
48
- end
49
-
50
- private
51
-
52
- def investigate_migration_method(method_node)
53
- schema_statement_match(method_node) do |statement_node, method_name, args_nodes|
54
- # TODO: Better/safer way to do this?
55
- args_source = "[#{args_nodes.map(&:source).join(', ')}]"
56
- args = eval(args_source)
57
-
58
- checker = RuboCop::Migration::StrongMigrationsChecker.new
59
- error = checker.check_operation(method_name, *args)
60
- if error
61
- error += "\n#{ERROR_NOTICE}"
62
- add_offense(statement_node, :expression, error)
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,47 +0,0 @@
1
- module RuboCop
2
- module Migration
3
- class StrongMigrationsChecker
4
- include StrongMigrations::Migration
5
-
6
- # StrongMigrations raises errors for potentially unsafe code, and relies
7
- # on the user to add a `safety_assured { }` block to supress this warning.
8
- # These warnings are unsupported by rubocop-migration for now.
9
- SAFETY_ASSURED_WARNINGS = [
10
- :add_column_json,
11
- :add_index_columns,
12
- :change_table,
13
- :execute,
14
- :remove_column,
15
- ].freeze
16
-
17
- def version_safe?
18
- false
19
- end
20
-
21
- def postgresql?
22
- true
23
- end
24
-
25
- def check_operation(method_name, *args)
26
- send(method_name, *args)
27
- rescue StrongMigrations::UnsafeMigration => e
28
- strip_wait_message(e.message)
29
- rescue NoMethodError
30
- # Do nothing, this method is unrecognized by StrongMigrations unsafe
31
- # operations and is likely safe.
32
- end
33
-
34
- private
35
-
36
- def raise_error(message_key)
37
- return if SAFETY_ASSURED_WARNINGS.include?(message_key)
38
- super(message_key)
39
- end
40
-
41
- # Strip large "WAIT!" ASCII art from the StrongMigrations error message.
42
- def strip_wait_message(error_message)
43
- error_message.split("\n\n", 2).last
44
- end
45
- end
46
- end
47
- end