mongration 0.0.3.pre.beta → 0.0.4.pre.beta

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +11 -4
  4. data/README.md +9 -2
  5. data/Rakefile +5 -0
  6. data/lib/mongration.rb +81 -26
  7. data/lib/mongration/configuration.rb +27 -4
  8. data/lib/mongration/create_migration.rb +11 -16
  9. data/lib/mongration/create_migration/migration_file_writer.rb +43 -0
  10. data/lib/mongration/file.rb +52 -9
  11. data/lib/mongration/migrate_all_up.rb +20 -0
  12. data/lib/mongration/migrate_down.rb +20 -0
  13. data/lib/mongration/migrate_up.rb +20 -0
  14. data/lib/mongration/migration.rb +37 -0
  15. data/lib/mongration/null_output.rb +6 -0
  16. data/lib/mongration/rake_tasks.rb +40 -0
  17. data/lib/mongration/rollback.rb +5 -16
  18. data/lib/mongration/status.rb +27 -0
  19. data/lib/mongration/version.rb +1 -1
  20. data/lib/os_check.rb +7 -0
  21. data/spec/fixtures/integration.rb +23 -27
  22. data/spec/integration/{template_spec.rb → create_migration_spec.rb} +5 -1
  23. data/spec/integration/migrate_spec.rb +76 -0
  24. data/spec/integration/migrate_with_version_spec.rb +38 -0
  25. data/spec/integration/{mongration_spec.rb → rollback_spec.rb} +11 -36
  26. data/spec/integration/status_spec.rb +61 -0
  27. data/spec/integration/version_spec.rb +20 -0
  28. data/spec/spec_helper.rb +16 -4
  29. data/spec/unit/mongration/{data_store/mongoid/migration_spec.rb → migration_spec.rb} +9 -3
  30. data/spec/unit/mongration/rake_tasks_spec.rb +95 -0
  31. metadata +40 -35
  32. data/lib/mongration/data_store/in_memory/store.rb +0 -32
  33. data/lib/mongration/data_store/mongoid/migration.rb +0 -24
  34. data/lib/mongration/data_store/mongoid/store.rb +0 -53
  35. data/lib/mongration/migrate.rb +0 -52
  36. data/lib/mongration/migration_file_writer.rb +0 -40
  37. data/lib/mongration/null_migration.rb +0 -16
  38. data/lib/mongration/rake_task.rb +0 -18
  39. data/spec/support/store_interface.rb +0 -18
  40. data/spec/unit/mongration/data_store/in_memory/store_spec.rb +0 -10
  41. data/spec/unit/mongration/data_store/mongoid/store_spec.rb +0 -12
@@ -0,0 +1,20 @@
1
+ module Mongration
2
+
3
+ # @private
4
+ class MigrateAllUp
5
+
6
+ def self.perform
7
+ new.perform
8
+ end
9
+
10
+ def perform
11
+ files_to_migrate.take_while(&:up)
12
+ end
13
+
14
+ private
15
+
16
+ def files_to_migrate
17
+ File.pending
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongration
2
+
3
+ # @private
4
+ class MigrateDown
5
+
6
+ def initialize(version)
7
+ @version = version
8
+ end
9
+
10
+ def perform
11
+ files_to_rollback.each(&:down)
12
+ end
13
+
14
+ private
15
+
16
+ def files_to_rollback
17
+ File.migrated.select { |f| f.version > @version }.reverse
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongration
2
+
3
+ # @private
4
+ class MigrateUp
5
+
6
+ def initialize(version)
7
+ @version = version
8
+ end
9
+
10
+ def perform
11
+ files_to_migrate.take_while(&:up)
12
+ end
13
+
14
+ private
15
+
16
+ def files_to_migrate
17
+ File.pending.select { |f| f.version <= @version }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Mongration
2
+
3
+ # @private
4
+ class Migration
5
+ include Mongoid::Document
6
+
7
+ store_in({ collection: 'mongration_migrations' })
8
+
9
+ field :file_name, type: String
10
+
11
+ field :created_at, type: Time, default: -> { Time.now }
12
+ field :deleted_at, type: Time
13
+
14
+ default_scope -> { where(deleted_at: nil) }
15
+
16
+ def self.create_by_file_name(file_name)
17
+ create(file_name: file_name)
18
+ end
19
+
20
+ def self.destroy_by_file_name(file_name)
21
+ where(file_name: file_name).first.destroy
22
+ end
23
+
24
+ def self.file_names
25
+ Migration.pluck(:file_name)
26
+ end
27
+
28
+ def self.last
29
+ all.to_a.max
30
+ end
31
+
32
+ def destroy(*)
33
+ self.deleted_at = Time.now
34
+ save!
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ module Mongration
2
+ class NullOutput
3
+ def puts(*); end
4
+ def write(*); end
5
+ end
6
+ end
@@ -0,0 +1,40 @@
1
+ namespace :db do
2
+
3
+ desc 'Runs #up on any migration files found that have not already been run'
4
+ task migrate: :environment do
5
+ version = ENV['VERSION']
6
+ Mongration.migrate(version)
7
+ end
8
+
9
+ desc 'Runs #down on all migration files from the most recent migration'
10
+ task rollback: :environment do
11
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
12
+ Mongration.rollback(step)
13
+ end
14
+
15
+ desc 'Returns the version for the most recent migration (i.e. the number of migrations that have been run, not the number of migration files)'
16
+ task version: :environment do
17
+ version = Mongration.version
18
+ Mongration.out.puts "Current version: #{version}"
19
+ end
20
+
21
+ namespace :migrate do
22
+
23
+ desc 'Creates a new migration file in the migration directory'
24
+ task :create, [:name] => [:environment] do |t, args|
25
+ name = args[:name] || ENV['NAME']
26
+ path = Mongration.create_migration(name)
27
+ Mongration.out.puts "Created #{path}"
28
+ end
29
+
30
+ desc 'Outputs a list of files and whether or not they have been migrated'
31
+ task status: :environment do
32
+ migrations = Mongration.status
33
+ Mongration.out.puts ['Status', 'Migration ID' 'Migration Name'].join("\t")
34
+ Mongration.out.puts '-' * 50
35
+ migrations.each do |migration|
36
+ Mongration.out.puts [migration.status, migration.migration_id, migration.migration_name].join("\t")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -3,25 +3,14 @@ module Mongration
3
3
  # @private
4
4
  class Rollback
5
5
 
6
- def self.perform(migration)
7
- new(migration).perform
8
- end
9
-
10
- def initialize(migration)
11
- @migration = migration
6
+ def self.perform
7
+ new.perform
12
8
  end
13
9
 
14
10
  def perform
15
- files_to_rollback.sort.reverse.each(&:down)
16
- @migration.destroy
17
- end
18
-
19
- private
20
-
21
- def files_to_rollback
22
- @migration.file_names.map do |file_name|
23
- Mongration::File.new(file_name)
24
- end
11
+ return unless Migration.exists?
12
+ file = File.migrated.last
13
+ file.down
25
14
  end
26
15
  end
27
16
  end
@@ -0,0 +1,27 @@
1
+ module Mongration
2
+
3
+ # @private
4
+ module Status
5
+ extend self
6
+
7
+ FileStatus = Struct.new(:status, :migration_id, :migration_name)
8
+
9
+ def migrations
10
+ performed_migrations + pending_migrations
11
+ end
12
+
13
+ private
14
+
15
+ def performed_migrations
16
+ File.migrated.map do |file|
17
+ FileStatus.new('up', file.version, file.name)
18
+ end
19
+ end
20
+
21
+ def pending_migrations
22
+ File.pending.map do |file|
23
+ FileStatus.new('down', file.version, file.name)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Mongration
2
- VERSION = '0.0.3-beta'
2
+ VERSION = '0.0.4-beta'
3
3
  end
data/lib/os_check.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rbconfig'
2
+
3
+ module OsCheck
4
+ def self.mac_osx?
5
+ RbConfig::CONFIG['host_os'] =~ /darwin|mac os/
6
+ end
7
+ end
@@ -1,39 +1,39 @@
1
1
  module IntegrationFixtures
2
- def create(file_name, up, down)
3
- Mongration::MigrationFileWriter.
4
- write(file_name, up: up, down: down, dir: Mongration.configuration.dir)
2
+ def create_migration(file_name, options = {})
3
+ Mongration::CreateMigration::MigrationFileWriter.
4
+ write(file_name + '.rb', options.merge(dir: Mongration.configuration.dir))
5
5
  end
6
6
 
7
7
  def foo_create_migration
8
- create(
9
- '001_add_foo.rb',
10
- 'Foo.instances << Foo.new',
11
- 'Foo.instances.pop'
12
- )
8
+ create_migration(
9
+ '001_add_foo',
10
+ up: 'Foo.instances << Foo.new',
11
+ down: 'Foo.instances.pop'
12
+ )
13
13
  end
14
14
 
15
15
  def bar_create_migration
16
- create(
17
- '002_add_bar.rb',
18
- 'Bar.instances << Bar.new',
19
- 'Bar.instances.pop'
20
- )
16
+ create_migration(
17
+ '002_add_bar',
18
+ up: 'Bar.instances << Bar.new',
19
+ down: 'Bar.instances.pop'
20
+ )
21
21
  end
22
22
 
23
23
  def foo_update_migration
24
- create(
25
- '0003_add_name_to_foo.rb',
26
- 'foo = Foo.instances.first; foo.name = "Test"',
27
- 'foo = Foo.instances.first; foo.name = ""'
28
- )
24
+ create_migration(
25
+ '0003_add_name_to_foo',
26
+ up: 'foo = Foo.instances.first; foo.name = "Test"',
27
+ down: 'foo = Foo.instances.first; foo.name = ""'
28
+ )
29
29
  end
30
30
 
31
31
  def bar_update_migration
32
- create(
33
- '004_add_name_to_bar.rb',
34
- 'bar = Bar.instances.first; bar.name = "Test"',
35
- 'bar = Bar.instances.first; bar.name = ""'
36
- )
32
+ create_migration(
33
+ '004_add_name_to_bar',
34
+ up: 'bar = Bar.instances.first; bar.name = "Test"',
35
+ down: 'bar = Bar.instances.first; bar.name = ""'
36
+ )
37
37
  end
38
38
  end
39
39
 
@@ -64,7 +64,3 @@ class Bar
64
64
 
65
65
  attr_accessor :name
66
66
  end
67
-
68
- RSpec.configure do |config|
69
- config.include(IntegrationFixtures)
70
- end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Mongration do
3
+ describe 'Mongration.create_migration' do
4
4
 
5
5
  it 'creates number-based template with CamelCase file name' do
6
6
  Mongration.create_migration('AddFoo')
@@ -67,4 +67,8 @@ end
67
67
  EOS
68
68
  )
69
69
  end
70
+
71
+ it 'returns file name of the migration created' do
72
+ expect(Mongration.create_migration('add_foo')).to eq(File.join('spec', 'db', 'migrate', '001_add_foo.rb'))
73
+ end
70
74
  end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Mongration.migrate' do
4
+
5
+ context 'when the migration is successful' do
6
+ before do
7
+ foo_create_migration
8
+ end
9
+
10
+ let(:migrate) { Mongration.migrate }
11
+
12
+ it 'runs a single migration' do
13
+ migrate
14
+ expect(Foo.count).to eq(1)
15
+ end
16
+
17
+ it 'includes success message' do
18
+ expect(Mongration.out).to receive(:puts).with('001 AddFoo: migrating')
19
+ expect(Mongration.out).to receive(:puts).with('001 AddFoo: migrated')
20
+ migrate
21
+ end
22
+ end
23
+
24
+ context 'when there is an error in the first migration' do
25
+ before do
26
+ create_migration(
27
+ '1_migration_with_error',
28
+ up: 'raise StandardError'
29
+ )
30
+ create_migration(
31
+ '2_migration_without_error',
32
+ up: 'Foo.instances << Foo.new'
33
+ )
34
+ end
35
+
36
+ let(:migrate) { Mongration.migrate }
37
+
38
+ it 'does not run later migrations' do
39
+ migrate
40
+ expect(Foo.instances).to be_empty
41
+ end
42
+
43
+ it 'includes failed message' do
44
+ expect(Mongration.out).to receive(:puts).with('1 MigrationWithError: migrating')
45
+ expect(Mongration.out).to receive(:puts).with(/StandardError: An error has occured, this and all later migrations cancelled/)
46
+ migrate
47
+ end
48
+ end
49
+
50
+ it 'skips the first migration and runs a second migration' do
51
+ foo_create_migration
52
+ Mongration.migrate
53
+
54
+ bar_create_migration
55
+ Mongration.migrate
56
+
57
+ expect(Foo.count).to eq(1)
58
+ expect(Bar.count).to eq(1)
59
+ end
60
+
61
+ it 'does not migrate when there are no migrations' do
62
+ foo_create_migration
63
+ Mongration.migrate
64
+ Mongration.migrate
65
+ expect(Foo.count).to eq(1)
66
+ end
67
+
68
+ it 'migrates files in order' do
69
+ foo_update_migration
70
+ foo_create_migration
71
+ Mongration.migrate
72
+
73
+ foo = Foo.instances.first
74
+ expect(foo.name).to eq('Test')
75
+ end
76
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Mongration.migrate(version)' do
4
+
5
+ context 'when the given version is above the current version' do
6
+ it 'migrates up to the given version' do
7
+ foo_create_migration
8
+ bar_create_migration
9
+ Mongration.migrate('001')
10
+
11
+ expect(Foo.count).to eq(1)
12
+ expect(Bar.count).to eq(0)
13
+ end
14
+ end
15
+
16
+ context 'when the given version is below the current version' do
17
+ it 'migrates down to the given version' do
18
+ foo_create_migration
19
+ bar_create_migration
20
+ Mongration.migrate
21
+
22
+ Mongration.migrate('001')
23
+
24
+ expect(Foo.count).to eq(1)
25
+ expect(Bar.count).to eq(0)
26
+ end
27
+ end
28
+
29
+ context 'when the version does not exist' do
30
+ it 'outputs message' do
31
+ foo_create_migration
32
+ bar_create_migration
33
+
34
+ expect(Mongration.out).to receive(:puts).with('Invalid Version: 003 does not exist.')
35
+ Mongration.migrate('003')
36
+ end
37
+ end
38
+ end
@@ -1,25 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Mongration do
4
-
5
- it 'runs a single migration' do
6
- foo_create_migration
7
-
8
- Mongration.migrate
9
-
10
- expect(Foo.count).to eq(1)
11
- end
12
-
13
- it 'skips the first migration and runs a second migration' do
14
- foo_create_migration
15
- Mongration.migrate
16
-
17
- bar_create_migration
18
- Mongration.migrate
19
-
20
- expect(Foo.count).to eq(1)
21
- expect(Bar.count).to eq(1)
22
- end
3
+ describe 'Mongration.rollback' do
23
4
 
24
5
  it 'rollsback a migration' do
25
6
  foo_create_migration
@@ -31,8 +12,6 @@ describe Mongration do
31
12
 
32
13
  it 'can rollback twice' do
33
14
  foo_create_migration
34
- Mongration.migrate
35
-
36
15
  bar_create_migration
37
16
  Mongration.migrate
38
17
 
@@ -49,28 +28,24 @@ describe Mongration do
49
28
  expect(Foo.count).to eq(1)
50
29
  end
51
30
 
52
- it 'does not migrate when there are no migrations' do
53
- foo_create_migration
54
- Mongration.migrate
31
+ it 'rolls back files in order' do
32
+ bar_create_migration
33
+ bar_update_migration
55
34
  Mongration.migrate
56
- expect(Foo.count).to eq(1)
57
- end
58
35
 
59
- it 'migrates files in order' do
60
- foo_update_migration
61
- foo_create_migration
62
- Mongration.migrate
36
+ Mongration.rollback
37
+ Mongration.rollback
63
38
 
64
- foo = Foo.instances.first
65
- expect(foo.name).to eq('Test')
39
+ expect(Bar.count).to eq(0)
66
40
  end
67
41
 
68
- it 'rollbacks files in order' do
42
+ it 'rolls back multiple times when passed a step' do
43
+ foo_create_migration
69
44
  bar_create_migration
70
- bar_update_migration
71
45
  Mongration.migrate
72
- Mongration.rollback
73
46
 
47
+ Mongration.rollback(2)
48
+ expect(Foo.count).to eq(0)
74
49
  expect(Bar.count).to eq(0)
75
50
  end
76
51
  end