mince_migrator 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +20 -58
- data/bin/mince_migrator +125 -0
- data/lib/mince_migrator/cli_helper.rb +72 -0
- data/lib/mince_migrator/config.rb +30 -0
- data/lib/mince_migrator/creator.rb +48 -0
- data/lib/mince_migrator/deleter.rb +42 -0
- data/lib/mince_migrator/list.rb +46 -0
- data/lib/mince_migrator/list_report.rb +67 -0
- data/lib/mince_migrator/migration.rb +66 -0
- data/lib/mince_migrator/migrations/file.rb +74 -0
- data/lib/mince_migrator/migrations/loader.rb +52 -0
- data/lib/mince_migrator/migrations/name.rb +48 -0
- data/lib/mince_migrator/migrations/runner.rb +39 -0
- data/lib/mince_migrator/migrations/runner_validator.rb +47 -0
- data/lib/mince_migrator/migrations/template.mustache +24 -0
- data/lib/mince_migrator/migrations/template.rb +16 -0
- data/lib/mince_migrator/migrations/versioned_file.rb +38 -0
- data/lib/mince_migrator/ran_migration.rb +27 -0
- data/lib/mince_migrator/reverter.rb +57 -0
- data/lib/mince_migrator/status_report.rb +41 -0
- data/lib/mince_migrator/version.rb +18 -1
- data/lib/mince_migrator.rb +5 -4
- data/spec/integration/create_a_migration_spec.rb +57 -0
- data/spec/integration/deleting_a_migration_spec.rb +40 -0
- data/spec/integration/list_all_migrations_spec.rb +57 -0
- data/spec/integration/reverting_a_migration_spec.rb +59 -0
- data/spec/integration/running_a_migration_spec.rb +66 -0
- data/spec/integration_helper.rb +17 -0
- data/spec/support/db/a_second_migration.rb +24 -0
- data/spec/support/db/a_second_migration_2.rb +24 -0
- data/spec/support/db/create_seeded_admin_users.rb +24 -0
- data/spec/support/db/first_migration.rb +24 -0
- data/spec/support/db/first_migration_2.rb +24 -0
- data/spec/support/db/first_migration_3.rb +24 -0
- data/spec/support/db/first_migration_4.rb +24 -0
- data/spec/support/db/name_of_migration.rb +24 -0
- data/spec/support/invalid_interface_migration.rb +7 -0
- data/spec/support/not_a_migration.rb +2 -0
- data/spec/support/test_migration.rb +30 -0
- data/spec/units/mince_migrator/cli_helper_spec.rb +147 -0
- data/spec/units/mince_migrator/creator_spec.rb +80 -0
- data/spec/units/mince_migrator/deleter_spec.rb +52 -0
- data/spec/units/mince_migrator/list_spec.rb +53 -0
- data/spec/units/mince_migrator/migration_spec.rb +119 -0
- data/spec/units/mince_migrator/migrations/file_spec.rb +85 -0
- data/spec/units/mince_migrator/migrations/loader_spec.rb +47 -0
- data/spec/units/mince_migrator/migrations/name_spec.rb +47 -0
- data/spec/units/mince_migrator/migrations/runner_spec.rb +70 -0
- data/spec/units/mince_migrator/migrations/runner_validator_spec.rb +46 -0
- data/spec/units/mince_migrator/migrations/template_spec.rb +42 -0
- data/spec/units/mince_migrator/migrations/versioned_file_spec.rb +48 -0
- data/spec/units/mince_migrator/ran_migration_spec.rb +60 -0
- data/spec/units/mince_migrator/reverter_spec.rb +78 -0
- metadata +298 -26
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/Rakefile +0 -12
- data/mince_migrator.gemspec +0 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 41b113ade7cbebb55bd8640f1f1a49739a1ba0c0
|
4
|
+
data.tar.gz: cb22a342cd4f20d89ecf0d0bd99a1b577566bde2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a02d661a150eb49a28aea7e37ab96f9d69e979e9531bb0072aac2de525e1bb56eda2c31675f16e6285e95f7e46bfad678b13be914cfcb0579b1302feb7458a2f
|
7
|
+
data.tar.gz: 2d58ae4f149108c101ac01e939ddba2f5afc37e224d2fb6133054bdb4588cc559d3b1625563da847447e21fe3c46ca62b20882c87f9be2a835cad077d09bed2a
|
data/README.md
CHANGED
@@ -1,89 +1,51 @@
|
|
1
1
|
# Mince Migrator
|
2
2
|
|
3
|
-
|
3
|
+
[![Travis CI](https://travis-ci.org/coffeencoke/mince_migrator.png)](https://travis-ci.org/#!/coffeencoke/mince_migrator)
|
4
4
|
|
5
|
-
Mince Migrator is a library that provides a way to run database
|
5
|
+
Mince Migrator is a library that provides a way to run database
|
6
|
+
migrations for your ruby applications.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
gem 'mince_migrator'
|
12
|
-
|
13
|
-
And then execute:
|
14
|
-
|
15
|
-
$ bundle install
|
16
|
-
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
10
|
$ gem install mince_migrator
|
20
11
|
|
21
12
|
## Usage
|
22
13
|
|
23
14
|
### Generate a migration
|
24
15
|
|
25
|
-
$
|
16
|
+
$ mince_migrator create "Load admin users"
|
26
17
|
|
27
18
|
### Implement your migration
|
28
19
|
|
29
|
-
The
|
30
|
-
|
31
|
-
|
32
|
-
module MinceMigrator
|
33
|
-
module Migration
|
34
|
-
module LoadAdminUsers
|
35
|
-
def self.run
|
36
|
-
# Actual migration goes here
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.revert
|
40
|
-
# In case you need to revert this one migration
|
41
|
-
end
|
42
|
-
|
43
|
-
# So you can change the order to run more easily
|
44
|
-
def self.time_created
|
45
|
-
"2013-02-23 19:03:27 UTC"
|
46
|
-
end
|
47
|
-
|
48
|
-
module Temporary
|
49
|
-
# Migration dependent classes go here
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
```
|
55
|
-
|
56
|
-
For an evolving explanation for the Temporary module, view [Migrating With Temporary Classes](https://github.com/coffeencoke/mince_migrator/wiki/migrating-with-temporary-classes).
|
20
|
+
The output of creating the migration will tell you where the migration was created.
|
21
|
+
|
22
|
+
Implement the `run` method with the behavior of your migration.
|
57
23
|
|
58
24
|
### Run your single migration
|
59
25
|
|
60
|
-
$
|
26
|
+
$ mince_migrator run "Load admin users"
|
61
27
|
|
62
|
-
*You can use any of the following as the name for the above command:*
|
63
|
-
|
64
|
-
* `Load admin users` (in quotes)*
|
65
|
-
* `LoadAdminUsers`
|
66
|
-
* `load_admin_users`
|
67
|
-
|
68
28
|
### Revert your single migration
|
69
29
|
|
70
|
-
$
|
30
|
+
$ mince_migrator revert "Load admin users"
|
71
31
|
|
72
32
|
### Run all migrations that have not yet been ran
|
73
33
|
|
74
|
-
$
|
75
|
-
|
34
|
+
$ mince_migrator run_all
|
35
|
+
|
36
|
+
### View all migrations
|
37
|
+
|
38
|
+
*My favorite!*
|
39
|
+
|
40
|
+
$ mince_migrator list
|
41
|
+
|
76
42
|
### Check the status of a migration
|
77
43
|
|
78
|
-
$
|
44
|
+
$ mince_migrator show "Load admin users"
|
79
45
|
|
80
46
|
### View all available commands
|
81
47
|
|
82
|
-
|
83
|
-
|
84
|
-
$ bundle exec mince_migrator
|
85
|
-
$ bundle exec mince_migrator --help
|
86
|
-
$ bundle exec mince_migrator help
|
48
|
+
$ mince_migrator --help
|
87
49
|
|
88
50
|
## Contributing
|
89
51
|
|
@@ -108,4 +70,4 @@ Copyright (c) 2013 Matt Simpson
|
|
108
70
|
|
109
71
|
MIT License
|
110
72
|
|
111
|
-
View the LICENSE.txt file included in the source
|
73
|
+
View the LICENSE.txt file included in the source
|
data/bin/mince_migrator
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require 'mince_migrator/version'
|
4
|
+
require 'mince_migrator/list'
|
5
|
+
require 'mince_migrator/cli_helper'
|
6
|
+
|
7
|
+
include GLI::App
|
8
|
+
include MinceMigrator::CliHelper
|
9
|
+
|
10
|
+
program_desc 'Manages database migrations for ruby applications'
|
11
|
+
version MinceMigrator.version
|
12
|
+
|
13
|
+
desc 'Creates a migration'
|
14
|
+
arg_name 'Name of migration'
|
15
|
+
command :create do |c|
|
16
|
+
c.action do |global_options,options,args|
|
17
|
+
name = args.join(" ")
|
18
|
+
create_migration(name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Lists all migrations and their statuses'
|
23
|
+
command :list do |c|
|
24
|
+
c.action do |global_options,options,args|
|
25
|
+
list_migrations(MinceMigrator::List.new)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Reverts a migration'
|
30
|
+
arg_name 'Name of migration'
|
31
|
+
command :revert do |c|
|
32
|
+
c.action do |global_options,options,args|
|
33
|
+
name = args.join(" ")
|
34
|
+
revert_migration(name: name)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'Deletes all migrations that have already ran'
|
39
|
+
command :delete_ran do |c|
|
40
|
+
c.action do |global_options,options,args|
|
41
|
+
list = MinceMigrator::List.new('ran')
|
42
|
+
if list.all.any?
|
43
|
+
list.all.each do |migration|
|
44
|
+
delete_migration(migration: migration)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
puts "No migrations were found."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'Deletes a migration'
|
53
|
+
arg_name 'Name of migration'
|
54
|
+
command :delete do |c|
|
55
|
+
c.action do |global_options,options,args|
|
56
|
+
name = args.join(" ")
|
57
|
+
|
58
|
+
delete_migration(name: name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'Runs a migration'
|
63
|
+
arg_name 'Name of migration'
|
64
|
+
command :run do |c|
|
65
|
+
c.action do |global_options,options,args|
|
66
|
+
name = args.join(" ")
|
67
|
+
|
68
|
+
run_migration(name: name)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Runs all migrations that have not yet been ran'
|
73
|
+
command :run_all do |c|
|
74
|
+
c.action do
|
75
|
+
list = MinceMigrator::List.new('not ran')
|
76
|
+
if list.all.any?
|
77
|
+
list.all.each do |migration|
|
78
|
+
run_migration(migration: migration)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
puts "There were no migrations to run."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
desc 'Shows the details of a migration'
|
87
|
+
arg_name 'Name of migration'
|
88
|
+
command :show do |c|
|
89
|
+
c.action do |global_options,options,args|
|
90
|
+
name = args.join(" ")
|
91
|
+
|
92
|
+
if args.any?
|
93
|
+
show_migration(name)
|
94
|
+
else
|
95
|
+
puts "You must provide a name"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
pre do |global,command,options,args|
|
101
|
+
# Pre logic here
|
102
|
+
# Return true to proceed; false to abort and not call the
|
103
|
+
# chosen command
|
104
|
+
# Use skips_pre before a command to skip this block
|
105
|
+
# on that command only
|
106
|
+
if File.exists?(MinceMigrator::Config.config_file)
|
107
|
+
require MinceMigrator::Config.config_file
|
108
|
+
end
|
109
|
+
|
110
|
+
true
|
111
|
+
end
|
112
|
+
|
113
|
+
post do |global,command,options,args|
|
114
|
+
# Post logic here
|
115
|
+
# Use skips_post before a command to skip this
|
116
|
+
# block on that command only
|
117
|
+
end
|
118
|
+
|
119
|
+
on_error do |exception|
|
120
|
+
# Error logic here
|
121
|
+
# return false to skip default error handling
|
122
|
+
true
|
123
|
+
end
|
124
|
+
|
125
|
+
exit run(ARGV)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require_relative 'deleter'
|
3
|
+
require_relative 'creator'
|
4
|
+
require_relative 'reverter'
|
5
|
+
require_relative 'list'
|
6
|
+
require_relative 'migrations/runner'
|
7
|
+
require_relative 'list_report'
|
8
|
+
|
9
|
+
module CliHelper
|
10
|
+
def delete_migration(options)
|
11
|
+
deleter = MinceMigrator::Deleter.new(options)
|
12
|
+
if deleter.can_delete_migration?
|
13
|
+
puts "Deleting #{deleter.name}..."
|
14
|
+
deleter.delete_migration
|
15
|
+
puts "Migration deleted successfully"
|
16
|
+
else
|
17
|
+
help_now!(deleter.reasons_for_failure)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_migration(options)
|
22
|
+
runner = MinceMigrator::Migrations::Runner.new(options)
|
23
|
+
if runner.can_run_migration?
|
24
|
+
puts "Running #{runner.name}..."
|
25
|
+
runner.run_migration
|
26
|
+
puts "Migration finished."
|
27
|
+
else
|
28
|
+
help_now!(runner.reasons_for_failure)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_migration(name)
|
33
|
+
creator = MinceMigrator::Creator.new(name)
|
34
|
+
if creator.can_create_migration?
|
35
|
+
puts "Creating #{creator.name}..."
|
36
|
+
creator.create_migration
|
37
|
+
puts "Migration created at #{creator.migration_file_relative_path}"
|
38
|
+
else
|
39
|
+
help_now!(creator.reasons_for_failure)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def list_migrations(list)
|
44
|
+
if list.all.any?
|
45
|
+
MinceMigrator::ListReport.new(list).run
|
46
|
+
else
|
47
|
+
puts "\nThere are no migrations in the '#{MinceMigrator::Config.migration_relative_dir}' directory.\n".red
|
48
|
+
puts "run the following for more info to create a migration:\n\n"
|
49
|
+
puts " mince_migrator create --help\n\n".green
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def revert_migration(options)
|
54
|
+
reverter = MinceMigrator::Reverter.new(options)
|
55
|
+
if reverter.can_revert_migration?
|
56
|
+
puts "Reverting #{reverter.name}..."
|
57
|
+
reverter.revert_migration
|
58
|
+
puts "Migration reverted successfully"
|
59
|
+
else
|
60
|
+
help_now!(reverter.reasons_for_failure)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def show_migration(name)
|
65
|
+
if migration = MinceMigrator::Migration.find(name)
|
66
|
+
MinceMigrator::StatusReport.new(migration).run
|
67
|
+
else
|
68
|
+
puts "No migration was found with name: '#{name}'"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
attr_reader :migration_relative_dir, :migration_dir
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.migration_relative_dir = ::File.join("db", "migrations")
|
11
|
+
end
|
12
|
+
|
13
|
+
def migration_relative_dir=(val)
|
14
|
+
@migration_relative_dir = val
|
15
|
+
@migration_dir = ::File.join(Dir.pwd, migration_relative_dir)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.migration_relative_dir
|
19
|
+
instance.migration_relative_dir
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.migration_dir
|
23
|
+
instance.migration_dir
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.config_file
|
27
|
+
::File.join(Dir.pwd, 'config', 'mince_migrator.rb')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require 'fileutils'
|
3
|
+
require_relative 'migrations/versioned_file'
|
4
|
+
require_relative 'migrations/name'
|
5
|
+
require_relative 'config'
|
6
|
+
|
7
|
+
class Creator
|
8
|
+
attr_reader :name, :migration_name
|
9
|
+
|
10
|
+
def initialize(name=nil)
|
11
|
+
@migration_name = Migrations::Name.new(name)
|
12
|
+
@name = migration_name.value
|
13
|
+
end
|
14
|
+
|
15
|
+
def can_create_migration?
|
16
|
+
migration_name.valid?
|
17
|
+
end
|
18
|
+
|
19
|
+
def reasons_for_failure
|
20
|
+
migration_name.reasons_for_failure
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_migration
|
24
|
+
FileUtils.mkdir_p(Config.migration_dir)
|
25
|
+
file = ::File.open(migration_file.full_path, 'w+')
|
26
|
+
file.write migration_file.body
|
27
|
+
file.close
|
28
|
+
end
|
29
|
+
|
30
|
+
def migration_file
|
31
|
+
@migration_file ||= versioned_file.next_unused_version
|
32
|
+
end
|
33
|
+
|
34
|
+
def versioned_file
|
35
|
+
@versioned_file ||= Migrations::VersionedFile.new(name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def migration_file_relative_path
|
39
|
+
migration_file.full_relative_path
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.create(name)
|
43
|
+
new(name).tap do |creator|
|
44
|
+
creator.create_migration if creator.can_create_migration?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require_relative 'config'
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative 'migrations/name'
|
5
|
+
require_relative 'ran_migration'
|
6
|
+
|
7
|
+
class Deleter
|
8
|
+
attr_reader :name, :filename, :migration_name, :migration
|
9
|
+
|
10
|
+
def initialize(options)
|
11
|
+
if options[:migration]
|
12
|
+
@migration = options[:migration]
|
13
|
+
@migration_name = Migrations::Name.new(migration.name)
|
14
|
+
elsif options[:name]
|
15
|
+
@migration_name = Migrations::Name.new(options[:name])
|
16
|
+
end
|
17
|
+
@name = migration_name.value
|
18
|
+
@filename = migration_name.filename
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete_migration
|
22
|
+
::FileUtils.rm(migration_path)
|
23
|
+
ran_migration.delete if ran_migration
|
24
|
+
end
|
25
|
+
|
26
|
+
def can_delete_migration?
|
27
|
+
::File.exists?(migration_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
def reasons_for_failure
|
31
|
+
"Migration does not exist with name '#{name}'" unless can_delete_migration?
|
32
|
+
end
|
33
|
+
|
34
|
+
def migration_path
|
35
|
+
::File.join Config.migration_dir, filename
|
36
|
+
end
|
37
|
+
|
38
|
+
def ran_migration
|
39
|
+
@ran_migration ||= RanMigration.find_by_name(name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require_relative 'config'
|
3
|
+
require_relative 'migration'
|
4
|
+
|
5
|
+
class List
|
6
|
+
attr_reader :status
|
7
|
+
|
8
|
+
def initialize(status=:any)
|
9
|
+
@status = status
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
@all ||= all_for_status
|
14
|
+
end
|
15
|
+
|
16
|
+
def number_of_migrations
|
17
|
+
all.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def filelist
|
21
|
+
@filelist ||= Dir.glob(filelist_pattern)
|
22
|
+
end
|
23
|
+
|
24
|
+
def filelist_pattern
|
25
|
+
File.join(Config.migration_dir, '*')
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def all_for_status
|
31
|
+
filtered_by_status(all_for_any_status).sort_by(&:time_created)
|
32
|
+
end
|
33
|
+
|
34
|
+
def all_for_any_status
|
35
|
+
filelist.map{|a| Migration.load_from_file(a) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def filtered_by_status(migrations)
|
39
|
+
migrations.select { |m| matches_status?(m) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def matches_status?(migration)
|
43
|
+
status == :any || migration.status == status
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
require 'command_line_reporter'
|
3
|
+
|
4
|
+
class ListReport
|
5
|
+
include CommandLineReporter
|
6
|
+
|
7
|
+
attr_reader :sum_ran, :sum_not_ran
|
8
|
+
|
9
|
+
def initialize(list)
|
10
|
+
@list = list
|
11
|
+
@sum_ran = 0
|
12
|
+
@sum_not_ran = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
vertical_spacing 2
|
17
|
+
header title: 'List Of All Migrations', bold: true, rule: true, align: 'center', width: 70, timestamp: true
|
18
|
+
|
19
|
+
table border: false do
|
20
|
+
row header: true do
|
21
|
+
column 'Name', width: 40
|
22
|
+
column 'Status', width: 10
|
23
|
+
column 'Age', width: 5
|
24
|
+
column 'Date Created', width: 15
|
25
|
+
end
|
26
|
+
@list.all.each do |migration|
|
27
|
+
row do
|
28
|
+
column migration.name
|
29
|
+
status_column(migration)
|
30
|
+
column migration.age
|
31
|
+
column migration.time_created.strftime("%m/%d/%Y")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
vertical_spacing 2
|
37
|
+
|
38
|
+
table border: false do
|
39
|
+
row do
|
40
|
+
column "Ran", width: 6
|
41
|
+
column sum_ran, color: 'green', width: 5
|
42
|
+
column "Not ran", width: 8
|
43
|
+
column sum_not_ran, color: 'red', width: 5
|
44
|
+
end
|
45
|
+
row bold: true do
|
46
|
+
column "Total", width: 6
|
47
|
+
column total_number_of_migrations, width: 5
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def total_number_of_migrations
|
53
|
+
sum_ran + sum_not_ran
|
54
|
+
end
|
55
|
+
|
56
|
+
def status_column(migration)
|
57
|
+
if migration.ran?
|
58
|
+
@sum_ran += 1
|
59
|
+
color = 'green'
|
60
|
+
else
|
61
|
+
@sum_not_ran += 1
|
62
|
+
color = 'red'
|
63
|
+
end
|
64
|
+
column migration.status, color: color
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'debugger'
|
2
|
+
|
3
|
+
module MinceMigrator
|
4
|
+
require_relative 'migrations/file'
|
5
|
+
require_relative 'ran_migration'
|
6
|
+
require_relative 'migrations/name'
|
7
|
+
|
8
|
+
class Migration
|
9
|
+
attr_reader :time_created, :name, :status, :relative_path, :path
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
@klass = options[:klass]
|
13
|
+
@time_created = @klass.time_created
|
14
|
+
self.name = options[:name]
|
15
|
+
@relative_path = options[:relative_path]
|
16
|
+
@path = options[:path]
|
17
|
+
end
|
18
|
+
|
19
|
+
def age
|
20
|
+
@age ||= "#{(Time.now.utc.to_date - time_created.to_date).to_i}d"
|
21
|
+
end
|
22
|
+
|
23
|
+
def name=(val)
|
24
|
+
@name ||= Migrations::Name.new(val).value
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
@klass.run
|
29
|
+
end
|
30
|
+
|
31
|
+
def revert
|
32
|
+
@klass.revert
|
33
|
+
end
|
34
|
+
|
35
|
+
def ran?
|
36
|
+
!!ran_migration
|
37
|
+
end
|
38
|
+
|
39
|
+
def status
|
40
|
+
ran? ? 'ran' : 'not ran'
|
41
|
+
end
|
42
|
+
|
43
|
+
def ran_migration
|
44
|
+
@ran_migration ||= RanMigration.find_by_name(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.find(name)
|
48
|
+
if file = Migrations::File.find(name)
|
49
|
+
new_from_file file
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.load_from_file(path_to_file)
|
54
|
+
new_from_file Migrations::File.load_from_file(path_to_file)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.new_from_file(file)
|
58
|
+
new(
|
59
|
+
klass: file.klass,
|
60
|
+
name: file.name,
|
61
|
+
relative_path: file.full_relative_path,
|
62
|
+
path: file.full_path
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require_relative 'template'
|
4
|
+
require_relative '../config'
|
5
|
+
require_relative 'versioned_file'
|
6
|
+
require_relative 'loader'
|
7
|
+
|
8
|
+
class File
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@original_name = name
|
13
|
+
@version = 1
|
14
|
+
self.name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
def full_relative_path
|
18
|
+
::File.join(Config.migration_relative_dir, filename)
|
19
|
+
end
|
20
|
+
|
21
|
+
def name=(val)
|
22
|
+
@name = val.gsub(" ", "_").downcase
|
23
|
+
end
|
24
|
+
|
25
|
+
def filename
|
26
|
+
"#{name}.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
def full_path
|
30
|
+
::File.join Config.migration_dir, filename
|
31
|
+
end
|
32
|
+
|
33
|
+
def klass_name
|
34
|
+
name.split("_").map(&:capitalize).join
|
35
|
+
end
|
36
|
+
|
37
|
+
def klass
|
38
|
+
loader.klass
|
39
|
+
end
|
40
|
+
|
41
|
+
def body
|
42
|
+
@body ||= Template.new(klass_name).render
|
43
|
+
end
|
44
|
+
|
45
|
+
def persisted?
|
46
|
+
::File.exists?(full_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
def load
|
50
|
+
loader.call
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.load_from_file(path_to_file)
|
54
|
+
name = convert_path_to_name(path_to_file)
|
55
|
+
find(name)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.find(name)
|
59
|
+
file = new(name)
|
60
|
+
file.tap(&:load) if file.persisted?
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.convert_path_to_name(path)
|
64
|
+
path.split("/")[-1].gsub('.rb', '')
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def loader
|
70
|
+
@loader ||= Loader.new(full_path: full_path, klass_name: klass_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|