migrate_safely 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e2494a037e7a7b6bd5e25eeec717e15dbed6083a
4
+ data.tar.gz: 3a6898bdaa9e22e98da53d5baa27de6ac6648578
5
+ SHA512:
6
+ metadata.gz: 76c71a3e53de068869a0fdeea418d76cf7923f392bd57b4109e221e1ed0da890fa183c4c56b3f09e5722b2d8e8b87c835799506cecde9a51eeffe74ed8363e90
7
+ data.tar.gz: 663f28a1a7fbc96d337cf2462da43fd83c1d869cb8d2d56dbd5ffdbf00360cc22cf786825ca339f5a6c41c0095fe5c2a303ec299512dd6715f8ec4217d8b0e17
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Remind
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ MigrateSafely
2
+ =============
3
+
4
+ MigrateSafely is a [railtie](http://api.rubyonrails.org/classes/Rails/Railtie.html) that
5
+ adds a confirmation prompt to the `rake db:migrate` command to prevent accidental migrations/rollbacks.
6
+
7
+ Example:
8
+
9
+ $ rake db:migrate
10
+
11
+ database: my_database
12
+
13
+ Action Migration ID Migration Name
14
+ --------------------------------------------------
15
+ apply 20150916005809 Migration1
16
+ apply 20150917011452 Migration2
17
+
18
+ Are you sure you want to proceed? [y/n]:
19
+
20
+ Accidental rollback prevention:
21
+
22
+ $ VERSION=foo20150917011452 rake db:migrate # notice the typo in VERSION
23
+
24
+ database: my_database
25
+
26
+ Action Migration ID Migration Name
27
+ --------------------------------------------------
28
+ revert 20150914175134 Migration100
29
+ revert 20150902002737 Migration099
30
+ revert 20150901221908 Migration098
31
+ revert 20150901171434 Migration097
32
+ revert 20150831194113 Migration096
33
+ ...
34
+ revert 20150101004705 Migration001
35
+
36
+ Are you sure you want to proceed? [y/n]:
37
+
38
+ ## License
39
+
40
+ [MIT License](LICENSE)
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ require 'rake/testtask'
10
+
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+
19
+ task default: :test
@@ -0,0 +1,5 @@
1
+ module MigrateSafely
2
+ end
3
+
4
+ require 'migrate_safely/migration_outliner'
5
+ require 'migrate_safely/railtie' if defined?(Rails)
@@ -0,0 +1,27 @@
1
+ module MigrateSafely
2
+ class MigrationOutliner
3
+ Action = Struct.new(:version, :action, :name)
4
+
5
+ def self.pending_actions(target_version = nil)
6
+ current_version = ActiveRecord::Migrator.current_version
7
+ return [] if current_version == 0 && target_version == 0
8
+
9
+ direction = case
10
+ when target_version.nil?
11
+ :up
12
+ when current_version > target_version
13
+ :down
14
+ else
15
+ :up
16
+ end
17
+
18
+ migrations = ActiveRecord::Migrator.migrations(ActiveRecord::Migrator.migrations_paths)
19
+ runnable_migrations = ActiveRecord::Migrator.new(direction, migrations, target_version).runnable
20
+ action = direction == :up ? "apply" : "revert"
21
+
22
+ runnable_migrations.map do |m|
23
+ Action.new(m.version, action, m.name)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module MigrateSafely
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load "migrate_safely/tasks/migrate_safely.rake"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ namespace :migrate_safely do
2
+ task :outline => :environment do
3
+ require 'migrate_safely/migration_outliner'
4
+
5
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil # to_i is intentional, replicates ActiveRecord behavior
6
+ actions = MigrateSafely::MigrationOutliner.pending_actions(version)
7
+
8
+ unless actions.any?
9
+ abort "There are no migrations to be applied or reverted"
10
+ end
11
+
12
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
13
+ puts "#{'Action'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
14
+ puts "-" * 50
15
+ actions.each do |action|
16
+ puts "#{action.action.center(8)} #{action.version.to_s.ljust(14)} #{action.name}"
17
+ end
18
+ puts
19
+ end
20
+
21
+ task :confirm do
22
+ print "Are you sure you want to proceed? [y/n]: "
23
+ input = STDIN.gets.chomp
24
+ abort "Aborting" unless %w(y yes yeah).include?(input.downcase)
25
+ end
26
+ end
27
+
28
+ Rake::Task["db:migrate"].enhance ["migrate_safely:outline", "migrate_safely:confirm"]
@@ -0,0 +1,3 @@
1
+ module MigrateSafely
2
+ VERSION = "0.0.1"
3
+ end
Binary file
@@ -0,0 +1,9 @@
1
+ class TestMigration1 < ActiveRecord::Migration
2
+ def self.up
3
+ puts "test migration1 applied"
4
+ end
5
+
6
+ def self.down
7
+ puts "test migration1 reverted"
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class TestMigration2 < ActiveRecord::Migration
2
+ def self.up
3
+ puts "test migration2 applied"
4
+ end
5
+
6
+ def self.down
7
+ puts "test migration2 reverted"
8
+ end
9
+ end
10
+
@@ -0,0 +1,11 @@
1
+ class TestMigration3 < ActiveRecord::Migration
2
+ def self.up
3
+ puts "test migration3 applied"
4
+ end
5
+
6
+ def self.down
7
+ puts "test migration3 reverted"
8
+ end
9
+ end
10
+
11
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class MigrateSafelyTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, MigrateSafely
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ module MigrateSafely
4
+ class MigrationOutlinerTest < ActiveSupport::TestCase
5
+ setup do
6
+ ActiveRecord::Base.connection.begin_transaction(joinable: false)
7
+ end
8
+
9
+ teardown do
10
+ if ActiveRecord::Base.connection.transaction_open?
11
+ ActiveRecord::Base.connection.rollback_transaction
12
+ end
13
+ end
14
+
15
+ test "lists all pending migrations when version is not specified" do
16
+ pending_actions = MigrationOutliner.pending_actions
17
+ assert_equal [
18
+ MigrationOutliner::Action.new(20150918000000, "apply", "TestMigration1"),
19
+ MigrationOutliner::Action.new(20150918000001, "apply", "TestMigration2"),
20
+ MigrationOutliner::Action.new(20150918000002, "apply", "TestMigration3")
21
+ ], pending_actions
22
+ end
23
+
24
+ test "says will apply migrations up to version (inclusive) when the version is newer than current" do
25
+ pending_actions = MigrationOutliner.pending_actions(20150918000001)
26
+ assert_equal [
27
+ MigrationOutliner::Action.new(20150918000000, "apply", "TestMigration1"),
28
+ MigrationOutliner::Action.new(20150918000001, "apply", "TestMigration2")
29
+ ], pending_actions
30
+ end
31
+
32
+ test "says will revert migrations that are newer than version (not inclusive) when version is older than current" do
33
+ ActiveRecord::SchemaMigration.create!(version: "20150918000000")
34
+ ActiveRecord::SchemaMigration.create!(version: "20150918000001")
35
+
36
+ pending_actions = MigrationOutliner.pending_actions(20150918000000)
37
+ assert_equal [
38
+ MigrationOutliner::Action.new(20150918000001, "revert", "TestMigration2")
39
+ ], pending_actions
40
+ end
41
+
42
+ test "returns an empty list of actions if the version is equal to current" do
43
+ current_version = 20150918000000
44
+ ActiveRecord::SchemaMigration.create!(version: current_version.to_s)
45
+
46
+ pending_actions = MigrationOutliner.pending_actions(current_version)
47
+ assert_equal [], pending_actions
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ FIXTURES_ROOT = File.expand_path("../fixtures", __FILE__)
2
+
3
+ require 'active_record'
4
+ require 'active_support/testing/autorun'
5
+ require 'active_support/test_case'
6
+ require 'migrate_safely'
7
+
8
+ ActiveRecord::Base.establish_connection(
9
+ adapter: "sqlite3",
10
+ database: File.join(FIXTURES_ROOT, "db.sqlite3"),
11
+ pool: 1,
12
+ timeout: 5000
13
+ )
14
+ ActiveRecord::Migrator.migrations_paths = [File.join(FIXTURES_ROOT, "migrations")]
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: migrate_safely
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vlad Yarotsky
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Adds a confirmation prompt to rake db:migrate; Lists migrations to be
42
+ applied/reverted before proceeding.
43
+ email:
44
+ - vlad@remind101.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - lib/migrate_safely.rb
53
+ - lib/migrate_safely/migration_outliner.rb
54
+ - lib/migrate_safely/railtie.rb
55
+ - lib/migrate_safely/tasks/migrate_safely.rake
56
+ - lib/migrate_safely/version.rb
57
+ - test/fixtures/db.sqlite3
58
+ - test/fixtures/migrations/20150918000000_test_migration_1.rb
59
+ - test/fixtures/migrations/20150918000001_test_migration_2.rb
60
+ - test/fixtures/migrations/20150918000002_test_migration_3.rb
61
+ - test/migrate_safely_test.rb
62
+ - test/migration_outliner_test.rb
63
+ - test/test_helper.rb
64
+ homepage:
65
+ licenses: []
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.4.5
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Adds a confirmation prompt to rake db:migrate
87
+ test_files:
88
+ - test/fixtures/db.sqlite3
89
+ - test/fixtures/migrations/20150918000000_test_migration_1.rb
90
+ - test/fixtures/migrations/20150918000001_test_migration_2.rb
91
+ - test/fixtures/migrations/20150918000002_test_migration_3.rb
92
+ - test/migrate_safely_test.rb
93
+ - test/migration_outliner_test.rb
94
+ - test/test_helper.rb