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

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 884560384ec483986492aefbb946cda15136075b
4
- data.tar.gz: c40a5ede37782728919819f17c133935e728e637
3
+ metadata.gz: 20730b095053fceae0d065822f9492a8e70eb89b
4
+ data.tar.gz: 4a57e71108a1453971fc04145a31b6ba1c2bf4eb
5
5
  SHA512:
6
- metadata.gz: b2d0b356f35a8109db96d91ec16a55a2679d054fff3447436957572fcccc19576cae9b4a0cb304240c3a2592e1c81291716c2658127f5dee4426773f060698b7
7
- data.tar.gz: ff3da3716f89e2676c5351c05bc3eaece5049ea2ac17f52a22b3c9e75a2999b5ca78fac7e1565703a6848be1f92b963dd525bcad42af05f383e2667acf628d2b
6
+ metadata.gz: 7ed9c54e2a8c160eb8ca9089e83c07310dd6b916e1e8b86f460e6f753892d6f0e43a7e5ab0b340b67ec3a6cd14a6a9b53c22e878e401dd695a81bdb538a995a3
7
+ data.tar.gz: 7708282338c9c5740a675c65f1f6ee836280f59c0e03cb95d030430353500c5bed606e6cf2c3bea99dc34c46ab6b616691f90832ad3aade93831275d96b09eb6
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.0.0-p353
1
+ 2.1.2
data/Gemfile CHANGED
@@ -1,12 +1,19 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'rantly', github: 'hayeah/rantly'
4
+
3
5
  group :test do
4
6
  gem 'guard-rspec', '4.3.1', require: false
5
- gem 'rantly', github: 'hayeah/rantly'
6
7
  end
7
8
 
8
- #gem 'rspec-legacy_formatters'
9
- #gem 'rspec-nc'
9
+ # debuggers
10
+ gem 'ruby-debug', platforms: :jruby
11
+ gem 'debugger', platforms: :mri_19
12
+ gem 'byebug', platforms: [:mri_20, :mri_21]
13
+
14
+ require './lib/os_check.rb'
15
+ if OsCheck.mac_osx?
16
+ gem 'rspec-nc'
17
+ end
10
18
 
11
- # Specify your gem's dependencies in mongration.gemspec
12
19
  gemspec
data/README.md CHANGED
@@ -4,7 +4,14 @@
4
4
 
5
5
  Mongration is a tool for migrating data. It is designed to have the same interface as [ActiveRecord](https://github.com/rails/rails/tree/master/activerecord)'s migrations but be used with [Mongoid](https://github.com/mongoid/mongoid) instead of an SQL database.
6
6
 
7
- Currently, there are only two supported Rake tasks, `db:migrate` and `db:migrate:rollback`. There is a third rake task, `db:migrate:create` which takes the place of the `rails generate migration` generator.
7
+ Mongration supports the following rake tasks:
8
+ * `db:migrate` - migrates all pending migrations
9
+ * `db:migrate VERSION=123` - moves to the specified version. If the version is greater than the current version, it will move up. If the version is lesser than the current version, it will move down.
10
+ * `db:rollback` - rolls back the most recent migration
11
+ * `db:rollback STEP=N` - rolls back the N most recent migrations
12
+ * `db:version` - outputs the numeric identifier for the most recent migration
13
+ * `db:migrate:create` - takes the place of the `rails generate migration` generator
14
+ * `db:migrate:status` - outputs a table of all files and their migration status
8
15
 
9
16
  ## Support
10
17
 
@@ -31,7 +38,7 @@ Or install it yourself as:
31
38
 
32
39
  ## Usage
33
40
 
34
- The primary usage will be through the Rake tasks `db:migrate` and `db:migrate:rollback`. Migrate will run all migrations that have not been run before. Rollback will rollback the previous migration.
41
+ The primary usage will be through the Rake tasks `db:migrate` and `db:rollback`. Migrate will run all migrations that have not been run before. Rollback will rollback the previous migration.
35
42
 
36
43
  Migration files have the following structure:
37
44
 
data/Rakefile CHANGED
@@ -3,6 +3,11 @@ require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec) do |t|
5
5
  t.verbose = false
6
+
7
+ require 'os_check'
8
+ if OsCheck.mac_osx?
9
+ t.rspec_opts = '--format Nc'
10
+ end
6
11
  end
7
12
 
8
13
  require 'tailor/rake_task'
data/lib/mongration.rb CHANGED
@@ -1,34 +1,67 @@
1
- require 'mongration/version'
1
+ require 'mongoid'
2
+ require 'rake'
2
3
 
4
+ require 'mongration/version'
3
5
  require 'mongration/errors'
4
6
 
5
- require 'mongration/configuration'
6
- require 'mongration/create_migration'
7
7
  require 'mongration/file'
8
- require 'mongration/migrate'
9
- require 'mongration/migration_file_writer'
10
- require 'mongration/null_migration'
11
- require 'mongration/rake_task'
12
- require 'mongration/rollback'
8
+ require 'mongration/migration'
13
9
 
14
- require 'mongration/data_store/mongoid/store'
15
- require 'mongration/data_store/in_memory/store'
10
+ require 'mongration/rake_tasks'
11
+ require 'mongration/configuration'
16
12
 
17
13
  module Mongration
18
14
  extend self
19
15
 
20
- def migrate
21
- Migrate.perform(
22
- latest_migration.version + 1
23
- )
16
+ autoload :CreateMigration, 'mongration/create_migration'
17
+ autoload :MigrateAllUp, 'mongration/migrate_all_up'
18
+ autoload :MigrateUp, 'mongration/migrate_up'
19
+ autoload :MigrateDown, 'mongration/migrate_down'
20
+ autoload :NullOutput, 'mongration/null_output'
21
+ autoload :Rollback, 'mongration/rollback'
22
+ autoload :Status, 'mongration/status'
23
+
24
+ # Performs the migrations. If no version is provided, all pending migrations will be run. If a version is provided, migrations will be run to that version (either up or down).
25
+ #
26
+ # @param [String, nil] version
27
+ #
28
+ # @return [Boolean] true if migration was successful, false otherwise
29
+ #
30
+ def migrate(version = nil)
31
+ pending = ->(_) { File.pending.map(&:version).include?(_) }
32
+ migrated = ->(_) { File.migrated.map(&:version).include?(_) }
33
+
34
+ case version
35
+ when nil
36
+ MigrateAllUp.perform
37
+
38
+ when pending
39
+ MigrateUp.new(version).perform
40
+
41
+ when migrated
42
+ MigrateDown.new(version).perform
43
+
44
+ else
45
+ out.puts("Invalid Version: #{version} does not exist.")
46
+ end
24
47
  end
25
48
 
26
- def rollback
27
- Rollback.perform(
28
- latest_migration
29
- )
49
+ # Rolls back (calls `down`) on the most recent migration(s).
50
+ #
51
+ # @param [Integer] number of migrations to rollback
52
+ #
53
+ # @return [void]
54
+ #
55
+ def rollback(step = 1)
56
+ step.times do
57
+ Rollback.perform
58
+ end
30
59
  end
31
60
 
61
+ # Creates a migration with the given name
62
+ #
63
+ # @return [String] name of the file created
64
+ #
32
65
  def create_migration(name, options = {})
33
66
  CreateMigration.perform(
34
67
  name,
@@ -36,6 +69,34 @@ module Mongration
36
69
  )
37
70
  end
38
71
 
72
+ # Returns the version of most recently run migration. If there are no migrations that have run (all migrations are pending), it returns '0'.
73
+ #
74
+ # @return [String] version
75
+ #
76
+ def version
77
+ if File.migrated.any?
78
+ File.migrated.last.version
79
+ else
80
+ '0'
81
+ end
82
+ end
83
+
84
+ # Returns the direction (up if it has been run, down otherwise), migration ID (version), and description of the migration.
85
+ #
86
+ # @return [Array] migration statuses
87
+ #
88
+ def status
89
+ Status.migrations
90
+ end
91
+
92
+ def out
93
+ if configuration.silent?
94
+ @null_output ||= NullOutput.new
95
+ else
96
+ $stdout
97
+ end
98
+ end
99
+
39
100
  def configure
40
101
  yield configuration if block_given?
41
102
  end
@@ -43,12 +104,6 @@ module Mongration
43
104
  def configuration
44
105
  @configuration ||= Configuration.new
45
106
  end
46
-
47
- private
48
-
49
- def latest_migration
50
- configuration.data_store.migrations.max_by(&:version) || NullMigration.new
51
- end
52
107
  end
53
108
 
54
109
  Mongration.configure do |config|
@@ -56,7 +111,7 @@ Mongration.configure do |config|
56
111
  config.timestamps = true
57
112
 
58
113
  begin
59
- config.data_store = Mongration::DataStore::Mongoid::Store.new
60
- rescue Mongration::DataStore::Mongoid::ConfigNotFound
114
+ config.config_path = ::File.join('config', 'mongoid.yml')
115
+ rescue Mongration::Configuration::ConfigNotFound
61
116
  end
62
117
  end
@@ -2,22 +2,45 @@ module Mongration
2
2
 
3
3
  # @private
4
4
  class Configuration
5
- attr_reader :dir
6
- attr_writer :err_out
7
- attr_accessor :data_store, :timestamps
5
+
6
+ class ConfigNotFound < Errors
7
+ def initialize(path)
8
+ super("#{path} cannot be found.")
9
+ end
10
+ end
11
+
12
+ attr_reader :dir, :config_path
13
+ attr_writer :err_out, :timestamps, :silent
8
14
 
9
15
  def dir=(dir)
10
16
  unless ::File.exists?(dir)
11
- print_warning("Migration Directory #{dir} does not exists.")
17
+ print_warning("Migration Directory #{dir} does not exist.")
12
18
  end
13
19
 
14
20
  @dir = dir
15
21
  end
16
22
 
23
+ def config_path=(config_path)
24
+ unless ::File.exists?(config_path)
25
+ raise ConfigNotFound.new(config_path)
26
+ end
27
+
28
+ env = if defined?(Rails)
29
+ Rails.env
30
+ else
31
+ :test
32
+ end
33
+ Mongoid.load!(config_path, env)
34
+ end
35
+
17
36
  def timestamps?
18
37
  @timestamps
19
38
  end
20
39
 
40
+ def silent?
41
+ @silent
42
+ end
43
+
21
44
  private
22
45
 
23
46
  def print_warning(message)
@@ -1,36 +1,35 @@
1
+ require 'mongration/create_migration/migration_file_writer'
2
+
1
3
  module Mongration
2
4
 
3
5
  # @private
4
6
  class CreateMigration
5
7
 
6
8
  def self.perform(name, options = {})
7
- new(name, options, Mongration.configuration).perform
9
+ new(name, options).perform
8
10
  end
9
11
 
10
- def initialize(name, options, configuration)
11
- @name = name
12
+ def initialize(name, options)
12
13
  @options = options
13
- @configuration = configuration
14
+
15
+ snakecase = name.gsub(/([a-z])([A-Z0-9])/, '\1_\2').downcase
16
+ @file_name = "#{next_migration_number}_#{snakecase}.rb"
14
17
  end
15
18
 
16
19
  def perform
17
20
  MigrationFileWriter.write(
18
- file_name,
19
- { dir: @configuration.dir }.merge(@options)
21
+ @file_name,
22
+ @options
20
23
  )
21
24
  end
22
25
 
23
26
  private
24
27
 
25
- def file_name
26
- "#{next_migration_number}_#{snakecase}.rb"
27
- end
28
-
29
28
  def next_migration_number
30
- if @configuration.timestamps?
29
+ if Mongration.configuration.timestamps?
31
30
  Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
32
31
  else
33
- latest_file = Mongration::File.latest
32
+ latest_file = File.last
34
33
 
35
34
  number = if latest_file
36
35
  latest_file.number + 1
@@ -40,9 +39,5 @@ module Mongration
40
39
  '%.3d' % number
41
40
  end
42
41
  end
43
-
44
- def snakecase
45
- @name.gsub(/([a-z])([A-Z0-9])/, '\1_\2').downcase
46
- end
47
42
  end
48
43
  end
@@ -0,0 +1,43 @@
1
+ module Mongration
2
+ class CreateMigration
3
+
4
+ # @private
5
+ class MigrationFileWriter
6
+
7
+ def self.write(file_name, options = {})
8
+ new(file_name, options).write
9
+ end
10
+
11
+ def initialize(file_name, options = {})
12
+ @file_name = file_name
13
+ @up = options[:up]
14
+ @down = options[:down]
15
+ end
16
+
17
+ def write
18
+ path = ::File.join(Mongration.configuration.dir, @file_name)
19
+ ::File.open(path, 'w') do |file|
20
+ file.write(<<EOS
21
+ class #{class_name}
22
+ def self.up
23
+ #{@up}
24
+ end
25
+
26
+ def self.down
27
+ #{@down}
28
+ end
29
+ end
30
+ EOS
31
+ )
32
+ end
33
+ path
34
+ end
35
+
36
+ private
37
+
38
+ def class_name
39
+ File.new(@file_name).class_name
40
+ end
41
+ end
42
+ end
43
+ end
@@ -4,16 +4,36 @@ module Mongration
4
4
  class File
5
5
  include Comparable
6
6
 
7
- def self.all
7
+ def self.all_file_names
8
8
  Dir[::File.join(Mongration.configuration.dir, '*.rb')].map do |path|
9
9
  path.pathmap('%f')
10
- end.map { |file_name| new(file_name) }
10
+ end
11
+ end
12
+
13
+ def self.pending
14
+ wrap(all_file_names - migrated_file_names).sort
15
+ end
16
+
17
+ def self.migrated
18
+ wrap(migrated_file_names).sort
19
+ end
20
+
21
+ def self.migrated_file_names
22
+ Migration.file_names
11
23
  end
12
24
 
13
- def self.latest
25
+ def self.all
26
+ pending + migrated
27
+ end
28
+
29
+ def self.last
14
30
  all.max
15
31
  end
16
32
 
33
+ def self.wrap(file_names)
34
+ file_names.map { |file_name| new(file_name) }
35
+ end
36
+
17
37
  attr_reader :file_name
18
38
 
19
39
  def initialize(file_name)
@@ -21,35 +41,58 @@ module Mongration
21
41
  end
22
42
 
23
43
  def up
44
+ Mongration.out.puts("#{version} #{class_name}: migrating")
45
+
24
46
  load_file
25
47
  klass.up
48
+
49
+ Migration.create_by_file_name(file_name)
50
+ Mongration.out.puts("#{version} #{class_name}: migrated")
51
+ true
52
+
53
+ rescue => e
54
+ Mongration.out.puts("#{e.class}: An error has occured, this and all later migrations cancelled")
55
+ false
26
56
  end
27
57
 
28
58
  def down
29
59
  load_file
30
60
  klass.down
61
+ Migration.destroy_by_file_name(file_name)
62
+ end
63
+
64
+ def name
65
+ underscored_name.gsub('_', ' ')
66
+ end
67
+
68
+ def class_name
69
+ underscored_name.camelize
70
+ end
71
+
72
+ def version
73
+ file_name.split('_').first
31
74
  end
32
75
 
33
76
  def number
34
- @file_name.split('_').first.to_i
77
+ version.to_i
35
78
  end
36
79
 
37
80
  def <=>(other)
38
81
  number <=> other.number
39
82
  end
40
83
 
41
- def class_name
42
- @file_name.chomp('.rb').gsub(/^\d+_/, '').camelize
43
- end
44
-
45
84
  private
46
85
 
47
86
  def load_file
48
- load(::File.join(Dir.pwd, Mongration.configuration.dir, @file_name))
87
+ load(::File.join(Mongration.configuration.dir, @file_name))
49
88
  end
50
89
 
51
90
  def klass
52
91
  class_name.constantize
53
92
  end
93
+
94
+ def underscored_name
95
+ @file_name.chomp('.rb').gsub(/^\d+_/, '')
96
+ end
54
97
  end
55
98
  end