hydra-migrate 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/CONTRIBUTING.md +111 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +12 -0
- data/README.md +75 -0
- data/Rakefile +7 -0
- data/hydra-migrate.gemspec +26 -0
- data/lib/hydra/datastream/migration_info.rb +37 -0
- data/lib/hydra/migrate.rb +11 -0
- data/lib/hydra/migrate/dispatcher.rb +53 -0
- data/lib/hydra/migrate/engine.rb +13 -0
- data/lib/hydra/migrate/migration.rb +36 -0
- data/lib/hydra/migrate/version.rb +5 -0
- data/lib/hydra/model_mixins/migratable.rb +12 -0
- data/lib/railties/hydra-migrate.rake +17 -0
- data/spec/fixtures/db/hydra/test_class_migration.rb +9 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/migratable_spec.rb +19 -0
- data/spec/unit/migrate_spec.rb +119 -0
- metadata +152 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-cf doc
|
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# How to Contribute
|
2
|
+
|
3
|
+
We want your help to make Project Hydra great.
|
4
|
+
There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.
|
5
|
+
|
6
|
+
## Hydra Project Intellectual Property Licensing and Ownership
|
7
|
+
|
8
|
+
All code contributors must have an Individual Contributor License Agreement (iCLA) on file with the Hydra Project Steering Group.
|
9
|
+
If the contributor works for an institution, the institution must have a Corporate Contributor License Agreement (cCLA) on file.
|
10
|
+
|
11
|
+
https://wiki.duraspace.org/display/hydra/Hydra+Project+Intellectual+Property+Licensing+and+Ownership
|
12
|
+
|
13
|
+
You should also add yourself to the `CONTRIBUTORS.md` file in the root of the project.
|
14
|
+
|
15
|
+
## Contribution Tasks
|
16
|
+
|
17
|
+
* Reporting Issues
|
18
|
+
* Making Changes
|
19
|
+
* Submitting Changes
|
20
|
+
* Merging Changes
|
21
|
+
|
22
|
+
### Reporting Issues
|
23
|
+
|
24
|
+
* Make sure you have a [GitHub account](https://github.com/signup/free)
|
25
|
+
* Submit a [Github issue](./issues) by:
|
26
|
+
* Clearly describing the issue
|
27
|
+
* Provide a descriptive summary
|
28
|
+
* Explain the expected behavior
|
29
|
+
* Explain the actual behavior
|
30
|
+
* Provide steps to reproduce the actual behavior
|
31
|
+
|
32
|
+
### Making Changes
|
33
|
+
|
34
|
+
* Fork the repository on GitHub
|
35
|
+
* Create a topic branch from where you want to base your work.
|
36
|
+
* This is usually the master branch.
|
37
|
+
* To quickly create a topic branch based on master; `git branch fix/master/my_contribution master`
|
38
|
+
* Then checkout the new branch with `git checkout fix/master/my_contribution`.
|
39
|
+
* Please avoid working directly on the `master` branch.
|
40
|
+
* You may find the [hub suite of commands](https://github.com/defunkt/hub) helpful
|
41
|
+
* Make commits of logical units.
|
42
|
+
* Your commit should include a high level description of your work in HISTORY.textile
|
43
|
+
* Check for unnecessary whitespace with `git diff --check` before committing.
|
44
|
+
* Make sure your commit messages are [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
45
|
+
* If you created an issue, you can close it by including "Closes #issue" in your commit message. See [Github's blog post for more details](https://github.com/blog/1386-closing-issues-via-commit-messages)
|
46
|
+
|
47
|
+
```
|
48
|
+
Present tense short summary (50 characters or less)
|
49
|
+
|
50
|
+
More detailed description, if necessary. It should be wrapped to 72
|
51
|
+
characters. Try to be as descriptive as you can, even if you think that
|
52
|
+
the commit content is obvious, it may not be obvious to others. You
|
53
|
+
should add such description also if it's already present in bug tracker,
|
54
|
+
it should not be necessary to visit a webpage to check the history.
|
55
|
+
|
56
|
+
Include Closes #<issue-number> when relavent.
|
57
|
+
|
58
|
+
Description can have multiple paragraphs and you can use code examples
|
59
|
+
inside, just indent it with 4 spaces:
|
60
|
+
|
61
|
+
class PostsController
|
62
|
+
def index
|
63
|
+
respond_with Post.limit(10)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
You can also add bullet points:
|
68
|
+
|
69
|
+
- you can use dashes or asterisks
|
70
|
+
|
71
|
+
- also, try to indent next line of a point for readability, if it's too
|
72
|
+
long to fit in 72 characters
|
73
|
+
```
|
74
|
+
|
75
|
+
* Make sure you have added the necessary tests for your changes.
|
76
|
+
* Run _all_ the tests to assure nothing else was accidentally broken.
|
77
|
+
* When you are ready to submit a pull request
|
78
|
+
|
79
|
+
### Submitting Changes
|
80
|
+
|
81
|
+
* Read the article ["Using Pull Requests"](https://help.github.com/articles/using-pull-requests) on GitHub.
|
82
|
+
* Make sure your branch is up to date with its parent branch (i.e. master)
|
83
|
+
* `git checkout master`
|
84
|
+
* `git pull --rebase`
|
85
|
+
* `git checkout <your-branch>`
|
86
|
+
* `git rebase master`
|
87
|
+
* It is likely a good idea to run your tests again.
|
88
|
+
* Squash the commits for your branch into one commit
|
89
|
+
* `git rebase --interactive HEAD~<number-of-commits>` ([See Github help](https://help.github.com/articles/interactive-rebase))
|
90
|
+
* To determine the number of commits on your branch: `git log master..<your-branch> --oneline | wc -l`
|
91
|
+
* Squashing your branch's changes into one commit is "good form" and helps the person merging your request to see everything that is going on.
|
92
|
+
* Push your changes to a topic branch in your fork of the repository.
|
93
|
+
* Submit a pull request from your fork to the project.
|
94
|
+
|
95
|
+
### Merging Changes
|
96
|
+
|
97
|
+
* It is considered "poor from" to merge your own request.
|
98
|
+
* Please take the time to review the changes and get a sense of what is being changed. Things to consider:
|
99
|
+
* Does the commit message explain what is going on?
|
100
|
+
* Does the code changes have tests? _Not all changes need new tests, some changes are refactorings_
|
101
|
+
* Does the commit contain more than it should? Are two separate concerns being addressed in one commit?
|
102
|
+
* Did the Travis tests complete successfully?
|
103
|
+
* If you are uncertain, bring other contributors into the conversation by creating a comment that includes their @username.
|
104
|
+
* If you like the pull request, but want others to chime in, create a +1 comment and tag a user.
|
105
|
+
|
106
|
+
# Additional Resources
|
107
|
+
|
108
|
+
* [General GitHub documentation](http://help.github.com/)
|
109
|
+
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
|
110
|
+
* [Pro Git](http://git-scm.com/book) is both a free and excellent book about Git.
|
111
|
+
* [A Git Config for Contributing](http://ndlib.github.io/practices/my-typical-per-project-git-config/)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Copyright 2011-2013, The Trustees of Indiana University and Northwestern
|
2
|
+
University. Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
you may not use this file except in compliance with the License.
|
4
|
+
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
10
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
11
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
12
|
+
specific language governing permissions and limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Hydra::Migrate [![Build Status](https://travis-ci.org/projecthydra/hydra-migrate.png?branch=master)](https://travis-ci.org/projecthydra/hydra-migrate)
|
2
|
+
|
3
|
+
Simple migrations for Hydra models
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'hydra-migrate', :require => false
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install hydra-migrate
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### app/models/my_model.rb
|
22
|
+
|
23
|
+
class MyModel < ActiveFedora::Base
|
24
|
+
include Hydra::ModelMixins::Migratable
|
25
|
+
# ... other model code here ...
|
26
|
+
end
|
27
|
+
|
28
|
+
### Magic class naming: db/hydra/my_model_migration.rb
|
29
|
+
|
30
|
+
class MyModelMigration < Hydra::Migrate::Migration
|
31
|
+
migrate nil => 1 do |object,version,dispatcher|
|
32
|
+
# Do stuff to object to get it from unknown version to v1
|
33
|
+
end
|
34
|
+
|
35
|
+
migrate 1 => 2 do |object,version,dispatcher|
|
36
|
+
# Do stuff to object to get it from v1 to v2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
### Manual class naming: db/hydra/my_explicit_model_migration.rb
|
41
|
+
|
42
|
+
class MyExplicitModelMigration < Hydra::Migrate::Migration
|
43
|
+
migrates MyModel
|
44
|
+
|
45
|
+
migrate nil => 1 do |object,version,dispatcher|
|
46
|
+
# Do stuff to object to get it from unknown version to v1
|
47
|
+
end
|
48
|
+
|
49
|
+
migrate 1 => 2 do |object,version,dispatcher|
|
50
|
+
# Do stuff to object to get it from v1 to v2
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
### Run the migration
|
55
|
+
|
56
|
+
# Migrate everything that can be migrated
|
57
|
+
$ rake hydra:migrate
|
58
|
+
|
59
|
+
# Migrate one particular class of objects
|
60
|
+
$ rake hydra:migrate[MyModel]
|
61
|
+
|
62
|
+
## Todo
|
63
|
+
|
64
|
+
* Reversible migrations (rollback)
|
65
|
+
* Improved rake task(s):
|
66
|
+
* Specify target version (already possible in raw code)
|
67
|
+
* Migrate specific object, not entire model class
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hydra/migrate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hydra-migrate"
|
8
|
+
spec.version = Hydra::Migrate::VERSION
|
9
|
+
spec.authors = ["Michael Klein"]
|
10
|
+
spec.email = ["mbklein@gmail.com"]
|
11
|
+
spec.description = %q{Simple migrations for Hydra objects}
|
12
|
+
spec.summary = %q{Simple migrations for Hydra objects}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "Apache 2"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'active-fedora'
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "simplecov"
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_fedora'
|
2
|
+
|
3
|
+
module Hydra
|
4
|
+
module Datastream
|
5
|
+
class MigrationInfo < ActiveFedora::OmDatastream
|
6
|
+
set_terminology do |t|
|
7
|
+
t.root(:path=>"migrationInfo", :xmlns=>"http://hydra-collab.stanford.edu/schemas/migrationInfo/v1", :namespace_prefix=>nil)
|
8
|
+
t.current
|
9
|
+
t.history do
|
10
|
+
t.migration do
|
11
|
+
t.from(:path=>'@from')
|
12
|
+
t.to(:path=>'@to')
|
13
|
+
t.at(:path=>'@at')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.xml_template
|
19
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
20
|
+
xml.migrationInfo(:xmlns=>"http://hydra-collab.stanford.edu/schemas/migrationInfo/v1") {
|
21
|
+
xml.current
|
22
|
+
xml.history
|
23
|
+
}
|
24
|
+
end
|
25
|
+
builder.doc
|
26
|
+
end
|
27
|
+
|
28
|
+
define_template :migration do |xml, from, to, at=Time.now|
|
29
|
+
xml.migration :from=>from, :to=>to, :at=>at
|
30
|
+
end
|
31
|
+
|
32
|
+
def migrate(to)
|
33
|
+
add_child_node(find_by_terms(:history), :migration, current.first.to_s, to, Time.now)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "hydra/datastream/migration_info"
|
2
|
+
require "hydra/migrate/version"
|
3
|
+
require "hydra/migrate/dispatcher"
|
4
|
+
require "hydra/migrate/migration"
|
5
|
+
require "hydra/model_mixins/migratable"
|
6
|
+
require 'hydra/migrate/engine' if defined?(Rails)
|
7
|
+
|
8
|
+
module Hydra
|
9
|
+
module Migrate
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Migrate
|
3
|
+
class Dispatcher
|
4
|
+
def migrations
|
5
|
+
@migrations || reset!
|
6
|
+
end
|
7
|
+
protected :migrations
|
8
|
+
|
9
|
+
def reset!
|
10
|
+
@migrations ||= Hash.new { |h,k| h[k] = [] }
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_migrations(path)
|
14
|
+
Dir[File.join(path,'**','*.rb')].each { |migration_file|
|
15
|
+
existing_migrations = ObjectSpace.each_object(Hydra::Migrate::Migration).to_a
|
16
|
+
load(migration_file)
|
17
|
+
new_migrations = ObjectSpace.each_object(Hydra::Migrate::Migration).to_a - existing_migrations
|
18
|
+
new_migrations.each { |klass| klass.new(self) }
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_migration(signature={}, block)
|
23
|
+
self.migrations[signature[:for]] << { :from=>signature[:from].to_s, :to=>signature[:to].to_s, :block=>block }
|
24
|
+
end
|
25
|
+
|
26
|
+
def migrations_for(target, constraints={})
|
27
|
+
raise "Not a migratable object: #{target.inspect}" unless target.is_a?(Hydra::ModelMixins::Migratable)
|
28
|
+
if self.migrations.has_key?(target.class)
|
29
|
+
migrations[target.class].select { |v|
|
30
|
+
v[:from].to_s == constraints[:from].to_s and (constraints[:to].nil? or v[:to].to_s == constraints[:to].to_s)
|
31
|
+
}
|
32
|
+
else
|
33
|
+
return []
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def can_migrate?(object, constraints={})
|
38
|
+
object.is_a?(Hydra::ModelMixins::Migratable) and not migrations_for(object, {:from=>object.current_migration}.merge(constraints)).empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def migrate!(object, to=nil, opts={})
|
42
|
+
raise "Not a migratable object: #{object.inspect}" unless object.is_a?(Hydra::ModelMixins::Migratable)
|
43
|
+
migrations_for(object, :from=>object.current_migration, :to=>to).each do |migration|
|
44
|
+
migration[:block].call(object, to, self)
|
45
|
+
object.migrationInfo.migrate(migration[:to])
|
46
|
+
object.current_migration = migration[:to]
|
47
|
+
object.save unless opts[:dry_run]
|
48
|
+
end
|
49
|
+
object
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Migrate
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
# Load rake tasks
|
5
|
+
rake_tasks do
|
6
|
+
task_spec = File.join(File.expand_path('../..',File.dirname(__FILE__)),'railties', '*.rake')
|
7
|
+
Dir.glob(task_spec).each do |railtie|
|
8
|
+
load railtie
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Migrate
|
3
|
+
class Migration
|
4
|
+
class << self
|
5
|
+
def actions
|
6
|
+
@actions ||= []
|
7
|
+
end
|
8
|
+
|
9
|
+
def migrates klass
|
10
|
+
unless klass.is_a?(Class) and klass.ancestors.include?(Hydra::ModelMixins::Migratable)
|
11
|
+
raise TypeError, "Unknown migratable class: #{klass.to_s}"
|
12
|
+
end
|
13
|
+
@target_class = klass
|
14
|
+
end
|
15
|
+
|
16
|
+
def target_class
|
17
|
+
return @target_class if @target_class
|
18
|
+
klass = Module.const_get(self.name.sub(/Migration$/,'').to_sym)
|
19
|
+
migrates klass
|
20
|
+
end
|
21
|
+
|
22
|
+
def migrate opts={}, &block
|
23
|
+
unless opts.is_a?(Hash) and opts.length == 1
|
24
|
+
raise ArgumentError, "migrate <from_version> => <to_version>"
|
25
|
+
end
|
26
|
+
|
27
|
+
actions << [{:for=>target_class, :from=>opts.keys.first, :to=>opts.values.first}, block]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(migrator)
|
32
|
+
self.class.actions.each { |action| migrator.define_migration(*action) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Hydra
|
2
|
+
module ModelMixins
|
3
|
+
module Migratable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_metadata :name=>"migrationInfo", :type=>Hydra::Datastream::MigrationInfo, :autocreate=>true
|
8
|
+
delegate :current_migration, :to=>:migrationInfo, :at=>[:current], :unique=>true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace :hydra do
|
2
|
+
desc "Run ActiveFedora model migrations"
|
3
|
+
task :migrate, [:models] => :environment do |t,args|
|
4
|
+
migrator = Hydra::Migrate::Dispatcher.new
|
5
|
+
migrator.load_migrations(File.join(Rails.root,'db/hydra'))
|
6
|
+
models = (args[:models] || 'ActiveFedora::Base').split(/[,;\s]+/)
|
7
|
+
models.each do |model|
|
8
|
+
klass = model.split(/::/).inject(Module) { |k,c| k.const_find(c.to_sym) }
|
9
|
+
klass.find(:all).each do |obj|
|
10
|
+
while migrator.can_migrate? obj
|
11
|
+
$stderr.puts "Migrating #{obj.class} #{obj.pid} from #{obj.current_migration.inspect} to #{version.inspect}"
|
12
|
+
migrator.migrate! obj
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
ENV["RAILS_ENV"] ||= "test"
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'rspec'
|
8
|
+
require 'rspec/autorun'
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start
|
13
|
+
rescue LoadError
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'hydra/migrate'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Hydra::ModelMixins::Migratable do
|
4
|
+
before :all do
|
5
|
+
class TestClass < ActiveFedora::Base
|
6
|
+
include Hydra::ModelMixins::Migratable
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
Object.send(:remove_const, :TestClass)
|
12
|
+
end
|
13
|
+
|
14
|
+
subject {TestClass.new}
|
15
|
+
|
16
|
+
it "should have a migrationInfo datastream" do
|
17
|
+
subject.datastreams['migrationInfo'].should be_a(Hydra::Datastream::MigrationInfo)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Hydra::Migrate do
|
4
|
+
before :all do
|
5
|
+
class TestClass < ActiveFedora::Base
|
6
|
+
include Hydra::ModelMixins::Migratable
|
7
|
+
has_metadata name: 'myMetadata', :type => ActiveFedora::SimpleDatastream do |d|
|
8
|
+
d.field :migrated, :string
|
9
|
+
end
|
10
|
+
|
11
|
+
def save
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
after :each do
|
18
|
+
# Undefine all migration classes
|
19
|
+
ObjectSpace.each_object(Hydra::Migrate::Migration).to_a.collect { |obj|
|
20
|
+
obj.class.name.to_sym
|
21
|
+
}.uniq.each { |klass|
|
22
|
+
begin
|
23
|
+
Object.send(:remove_const, klass)
|
24
|
+
rescue NameError
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
after :all do
|
30
|
+
Object.send(:remove_const, :TestClass)
|
31
|
+
end
|
32
|
+
|
33
|
+
let!(:migrator) {Hydra::Migrate::Dispatcher.new}
|
34
|
+
subject {TestClass.new}
|
35
|
+
|
36
|
+
describe "no migrations defined" do
|
37
|
+
it "should have a nil migration version" do
|
38
|
+
expect(subject.current_migration).to be_blank
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not be able to migrate" do
|
42
|
+
expect(migrator.can_migrate?(subject)).to be_false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "TestClassMigration" do
|
47
|
+
before :each do
|
48
|
+
migrator.load_migrations(File.expand_path('../../fixtures/db',__FILE__))
|
49
|
+
end
|
50
|
+
|
51
|
+
before :each do
|
52
|
+
@migration = TestClassMigration.new(migrator)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should target the right class" do
|
56
|
+
TestClassMigration.target_class.should eq(TestClass)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be able to migrate" do
|
60
|
+
expect(subject.current_migration).to be_blank
|
61
|
+
expect(subject.myMetadata.migrated).to be_blank
|
62
|
+
expect(migrator.can_migrate?(subject)).to be_true
|
63
|
+
expect(migrator.can_migrate?(subject, :to=>1)).to be_true
|
64
|
+
expect(migrator.can_migrate?(subject, :to=>2)).to be_false
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "migrate" do
|
68
|
+
it "should perform migrations" do
|
69
|
+
migrator.migrate!(subject)
|
70
|
+
expect(subject.myMetadata.migrated).to eq(['yep'])
|
71
|
+
expect(subject.current_migration).to eq('1')
|
72
|
+
|
73
|
+
migrator.migrate!(subject)
|
74
|
+
expect(subject.myMetadata.migrated).to eq(['yep, YEP!'])
|
75
|
+
expect(subject.current_migration).to eq('2')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "ExplicitTestClassMigration" do
|
81
|
+
before :all do
|
82
|
+
class ExplicitTestClassMigration < Hydra::Migrate::Migration
|
83
|
+
migrates TestClass
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
after :all do
|
88
|
+
Object.send(:remove_const, :ExplicitTestClassMigration)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should target the right class" do
|
92
|
+
expect(ExplicitTestClassMigration.target_class).to eq(TestClass)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "IncorrectTestClassMigration" do
|
97
|
+
after :each do
|
98
|
+
Object.send(:remove_const, :IncorrectTestClassMigration)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should require a migratable class" do
|
102
|
+
expect(lambda {
|
103
|
+
class IncorrectTestClassMigration < Hydra::Migrate::Migration
|
104
|
+
migrates Object
|
105
|
+
end
|
106
|
+
}).to raise_error(TypeError)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should require a correctly-formed migration spec" do
|
110
|
+
class IncorrectTestClassMigration < Hydra::Migrate::Migration
|
111
|
+
migrates TestClass
|
112
|
+
end
|
113
|
+
expect { IncorrectTestClassMigration.migrate { } }.to raise_error(ArgumentError)
|
114
|
+
expect { IncorrectTestClassMigration.migrate(2) { } }.to raise_error(ArgumentError)
|
115
|
+
expect { IncorrectTestClassMigration.migrate(1=>2) { } }.not_to raise_error()
|
116
|
+
expect { IncorrectTestClassMigration.migrate(1=>2,2=>3) { } }.to raise_error(ArgumentError)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hydra-migrate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael Klein
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: active-fedora
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Simple migrations for Hydra objects
|
95
|
+
email:
|
96
|
+
- mbklein@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .rspec
|
103
|
+
- .travis.yml
|
104
|
+
- CONTRIBUTING.md
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- hydra-migrate.gemspec
|
110
|
+
- lib/hydra/datastream/migration_info.rb
|
111
|
+
- lib/hydra/migrate.rb
|
112
|
+
- lib/hydra/migrate/dispatcher.rb
|
113
|
+
- lib/hydra/migrate/engine.rb
|
114
|
+
- lib/hydra/migrate/migration.rb
|
115
|
+
- lib/hydra/migrate/version.rb
|
116
|
+
- lib/hydra/model_mixins/migratable.rb
|
117
|
+
- lib/railties/hydra-migrate.rake
|
118
|
+
- spec/fixtures/db/hydra/test_class_migration.rb
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
- spec/unit/migratable_spec.rb
|
121
|
+
- spec/unit/migrate_spec.rb
|
122
|
+
homepage: ''
|
123
|
+
licenses:
|
124
|
+
- Apache 2
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 1.8.23
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: Simple migrations for Hydra objects
|
147
|
+
test_files:
|
148
|
+
- spec/fixtures/db/hydra/test_class_migration.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/unit/migratable_spec.rb
|
151
|
+
- spec/unit/migrate_spec.rb
|
152
|
+
has_rdoc:
|