rubocop-migration 0.1.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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +6 -0
- data/lib/rubocop-migration.rb +11 -0
- data/lib/rubocop/cop/migration/add_index_non_concurrently.rb +66 -0
- data/lib/rubocop/migration/version.rb +5 -0
- data/rubocop-migration.gemspec +36 -0
- data/vendor/.gitkeep +0 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 85aebed56d23b5b864f2be24cff92db854c04214
|
4
|
+
data.tar.gz: e1d42ca0ebfea2ee641820dcaaca204d2506b0ae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 297517f1ec4b2395419075356cdc2219f10db378bf814fa143cdbfed01bfeec49e5ba168bb2d187695a428dd27e21a1a878d8de2fc06c50185a8752997c776f4
|
7
|
+
data.tar.gz: d4b33de1abaafb04c9e30ea2064c08ead9efc6b126ab6f013b1e9f3a1d770e83f7a7e69ecaa6f02e0ab61a98cb409ae464fe31b905b2de48e336b6d4e3a3cf99
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# rubocop-migration [](https://circleci.com/gh/wealthsimple/rubocop-migration)
|
2
|
+
|
3
|
+
RuboCop extension to catch common pitfalls in ActiveRecord migrations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile and then execute `bundle`:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
group :development do
|
11
|
+
gem 'rubocop-migration'
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Configure RuboCop to load the extension in `.rubocop.yml`.
|
18
|
+
|
19
|
+
```yaml
|
20
|
+
require: rubocop-migration
|
21
|
+
```
|
22
|
+
|
23
|
+
## Development
|
24
|
+
|
25
|
+
For running the spec files, this project depends on RuboCop's spec helpers. This means that in order to run the specs locally, you need a (shallow) clone of the RuboCop repository:
|
26
|
+
|
27
|
+
```
|
28
|
+
git clone --depth 1 git://github.com/bbatsov/rubocop.git vendor/rubocop
|
29
|
+
```
|
30
|
+
|
31
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
32
|
+
|
33
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
34
|
+
|
35
|
+
## TODO
|
36
|
+
|
37
|
+
https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/
|
38
|
+
http://leopard.in.ua/2016/09/20/safe-and-unsafe-operations-postgresql
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
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
ADDED
data/circle.yml
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module Migration
|
4
|
+
class AddIndexNonConcurrently < Cop
|
5
|
+
MSG = 'Use `algorithm: :concurrently` to avoid locking database.'.freeze
|
6
|
+
|
7
|
+
def_node_matcher :add_index_match, <<-PATTERN
|
8
|
+
(send nil :add_index _ _ (hash $...))
|
9
|
+
PATTERN
|
10
|
+
|
11
|
+
def_node_matcher :add_reference_match, <<-PATTERN
|
12
|
+
(send nil {:add_reference :add_belongs_to} _ _ (hash $...))
|
13
|
+
PATTERN
|
14
|
+
|
15
|
+
def_node_matcher :add_reference_index_options?, <<-PATTERN
|
16
|
+
(pair (sym :index) !({:nil false}))
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
def on_send(node)
|
20
|
+
if node.method_name == :add_index
|
21
|
+
check_add_index(node)
|
22
|
+
elsif [:add_reference, :add_belongs_to].include?(node.method_name)
|
23
|
+
check_add_reference(node)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def check_add_index(node)
|
30
|
+
pairs = add_index_match(node)
|
31
|
+
if !pairs_contains_algorithm_concurrently?(pairs)
|
32
|
+
add_offense(node, :expression, MSG)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_add_reference(node)
|
37
|
+
pairs = add_reference_match(node)
|
38
|
+
index_options = pairs&.find { |pair| add_reference_index_options?(pair) }&.value
|
39
|
+
return unless index_options
|
40
|
+
|
41
|
+
valid = true
|
42
|
+
if index_options.true_type?
|
43
|
+
# `index: true` is always invalid
|
44
|
+
valid = false
|
45
|
+
elsif index_options.hash_type?
|
46
|
+
# check for `algorithm: :concurrently`
|
47
|
+
valid = pairs_contains_algorithm_concurrently?(index_options.pairs)
|
48
|
+
end
|
49
|
+
add_offense(node, :expression, MSG) if !valid
|
50
|
+
end
|
51
|
+
|
52
|
+
def pairs_contains_algorithm_concurrently?(pairs)
|
53
|
+
return false unless pairs.is_a?(Array)
|
54
|
+
pairs.each do |pair|
|
55
|
+
next unless pair.pair_type?
|
56
|
+
key = pair.key
|
57
|
+
value = pair.value
|
58
|
+
next unless (key.sym_type? || key.str_type?) && key.children.first.to_s == "algorithm"
|
59
|
+
return true if value.children.first.to_s == "concurrently"
|
60
|
+
end
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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"
|
5
|
+
|
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"]
|
11
|
+
|
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"
|
15
|
+
|
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"
|
23
|
+
|
24
|
+
spec.required_ruby_version = ">= 2.3.0"
|
25
|
+
|
26
|
+
spec.add_dependency "activesupport", ">= 4"
|
27
|
+
spec.add_dependency "rubocop", ">= 0.48.0"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
spec.add_development_dependency "rspec-its"
|
33
|
+
spec.add_development_dependency "rspec-collection_matchers"
|
34
|
+
spec.add_development_dependency "rspec_junit_formatter", "~> 0.2"
|
35
|
+
spec.add_development_dependency "pry"
|
36
|
+
end
|
data/vendor/.gitkeep
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubocop-migration
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Graham
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
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: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.48.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.48.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.14'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.14'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-its
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-collection_matchers
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec_junit_formatter
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
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
|
+
description: RuboCop extension to catch common pitfalls in ActiveRecord migrations.
|
140
|
+
email:
|
141
|
+
- peter@wealthsimple.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".rspec"
|
148
|
+
- Gemfile
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- bin/console
|
152
|
+
- bin/setup
|
153
|
+
- circle.yml
|
154
|
+
- lib/rubocop-migration.rb
|
155
|
+
- lib/rubocop/cop/migration/add_index_non_concurrently.rb
|
156
|
+
- lib/rubocop/migration/version.rb
|
157
|
+
- rubocop-migration.gemspec
|
158
|
+
- vendor/.gitkeep
|
159
|
+
homepage: https://github.com/wealthsimple/rubocop-migration
|
160
|
+
licenses:
|
161
|
+
- MIT
|
162
|
+
metadata: {}
|
163
|
+
post_install_message:
|
164
|
+
rdoc_options: []
|
165
|
+
require_paths:
|
166
|
+
- lib
|
167
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 2.3.0
|
172
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
requirements: []
|
178
|
+
rubyforge_project:
|
179
|
+
rubygems_version: 2.5.1
|
180
|
+
signing_key:
|
181
|
+
specification_version: 4
|
182
|
+
summary: RuboCop extension for ActiveRecord migrations.
|
183
|
+
test_files: []
|