mlins-godwit 1.0.0
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.
- data/CHANGELOG +3 -0
- data/MIT-LICENSE +20 -0
- data/README +110 -0
- data/Rakefile +37 -0
- data/VERSION.yml +4 -0
- data/app_generators/godwit/godwit_generator.rb +91 -0
- data/app_generators/godwit/templates/Rakefile +8 -0
- data/app_generators/godwit/templates/config/database.yml +13 -0
- data/app_generators/godwit/templates/config/environment.rb +22 -0
- data/app_generators/godwit/templates/log/active_migration.log +0 -0
- data/app_generators/godwit/templates/log/active_record.log +0 -0
- data/app_generators/godwit/templates/script/console +8 -0
- data/app_generators/godwit/templates/script/lib/console.rb +3 -0
- data/app_generators/godwit/templates/script/migrate +6 -0
- data/bin/godwit +17 -0
- data/godwit_generators/active_migration/active_migration_generator.rb +55 -0
- data/godwit_generators/active_migration/templates/active_migration.rb +9 -0
- data/godwit_generators/active_model/active_model_generator.rb +53 -0
- data/godwit_generators/active_model/templates/active_model.rb +3 -0
- data/godwit_generators/legacy_model/legacy_model_generator.rb +53 -0
- data/godwit_generators/legacy_model/templates/legacy_model.rb +7 -0
- data/lib/godwit/active_migration.rb +97 -0
- data/lib/godwit/base.rb +43 -0
- data/lib/godwit/bootloader.rb +79 -0
- data/lib/godwit/buffer.rb +46 -0
- data/lib/godwit/callbacks.rb +34 -0
- data/lib/godwit/config.rb +120 -0
- data/lib/godwit/irb.rb +33 -0
- data/lib/godwit/legacy_record.rb +11 -0
- data/lib/godwit/version.rb +9 -0
- data/lib/godwit.rb +44 -0
- data/spec/active_migration_generator_spec.rb +23 -0
- data/spec/active_model_generator_spec.rb +23 -0
- data/spec/buffer_spec.rb +51 -0
- data/spec/callbacks_spec.rb +29 -0
- data/spec/config_spec.rb +54 -0
- data/spec/godwit_generator_spec.rb +34 -0
- data/spec/legacy_model_generator_spec.rb +23 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +28 -0
- metadata +131 -0
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Matt Lins
|
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
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
= Godwit
|
2
|
+
|
3
|
+
Github[http://github.com/mlins/godwit]
|
4
|
+
|
5
|
+
Godwit is a framework for the ActiveMigration[http://github.com/mlins/active_migration] library. It provides
|
6
|
+
a directory structure and scripts to bring ease to a migration. Godwit is a console application.
|
7
|
+
|
8
|
+
This should not be confused with Rails migrations. Godwit and
|
9
|
+
ActiveMigration[http://github.com/mlins/active_migration] are used for migrating data from a legacy dataset.
|
10
|
+
As of now it relys on ActiveRecord. You must define models for both your legacy data and your active data.
|
11
|
+
However, Godwit can load a Rails environment so you don't have to redefine or sync your models.
|
12
|
+
|
13
|
+
Godwit and ActiveMigration[http://github.com/mlins/active_migration] were written to maintain data integrity
|
14
|
+
during a migration. Speed was of little concern. So, this is not an ideal solution for people who are just
|
15
|
+
looking for raw dumps and/or imports. I designed this to use all of the validations, callbacks and plugins
|
16
|
+
from my new(active) application. See ActiveMigration[http://github.com/mlins/active_migration] for more details.
|
17
|
+
|
18
|
+
*Features*
|
19
|
+
|
20
|
+
- Console access if a migration fails (helpful for debugging).
|
21
|
+
- Extendable via plugins (similar to Rails). You can use some Rails/ActiveRecord plugins in Godwit.
|
22
|
+
- Loads Rails environment to prevent having to write models twice.
|
23
|
+
|
24
|
+
Godwit was written by: Matt Lins.
|
25
|
+
|
26
|
+
== Installation
|
27
|
+
|
28
|
+
$ gem sources -a http://gems.github.com
|
29
|
+
|
30
|
+
$ sudo gem install mlins-godwit
|
31
|
+
|
32
|
+
== Usage
|
33
|
+
|
34
|
+
You'll first want to create a base application with the Godwit binary:
|
35
|
+
|
36
|
+
$ godwit myapp
|
37
|
+
|
38
|
+
If you plan on migrating to a database that is used by a Rails application, you can load the Rails environment
|
39
|
+
so you don't have to redefine your models. Inside of *config/environment.rb* set the path to the root of the
|
40
|
+
Rails app:
|
41
|
+
|
42
|
+
config[:rails_root] = '/my/new/rails/app'
|
43
|
+
|
44
|
+
You can than test that the environment was loaded properly by starting a console session within Godwit:
|
45
|
+
|
46
|
+
$ ./script/console
|
47
|
+
|
48
|
+
If you're not using a Rails application then you can define your models in *app/models*. There is a generator
|
49
|
+
to help with this:
|
50
|
+
|
51
|
+
$ ./script/generate active_model my_model
|
52
|
+
|
53
|
+
Next, you'll need to define some models (ActiveRecord) for your legacy tables. Godwit namespaces legacy models
|
54
|
+
with the Legacy module. They live in the *app/models/legacy* directory. There is a generator for this:
|
55
|
+
|
56
|
+
$ ./script/generate legacy_model my_model
|
57
|
+
|
58
|
+
When you have all your models defined and tested, you can start creating migrations. They live in *app/migrations*.
|
59
|
+
See ActiveMigration[http://github.com/mlins/active_migration] for more details. There is a generator to create
|
60
|
+
migrations:
|
61
|
+
|
62
|
+
$ ./script/generate active_migration my_migration
|
63
|
+
|
64
|
+
When you're actually ready to run your migrations, you can use the *migrate* script. This script has a few
|
65
|
+
options, so run this for help:
|
66
|
+
|
67
|
+
$ ./script/migrate -h
|
68
|
+
|
69
|
+
If you run *migrate* without any options, it'll run all of your migrations. It will respect any dependencies
|
70
|
+
defined in your migrations.
|
71
|
+
|
72
|
+
If you need to debug a migration, Godwit provides a handy IRB session if #save fails during the migration
|
73
|
+
of a specific model. You can inspect the entire binding of the migration. Use the -D option to run in debug mode.
|
74
|
+
|
75
|
+
$ ./script/migrate -D
|
76
|
+
|
77
|
+
Once you drop to a IRB session you can inspect @active_record or @legacy_record. Ideally you want to get
|
78
|
+
@active_record #valid? before you're done. When you're done, you can just type 'exit' and the migration will continue.
|
79
|
+
If you failed to resolve the issue, Godwit will continue to drop back to the IRB session. You can type 'skip' and
|
80
|
+
then 'exit' to skip this particular record.
|
81
|
+
|
82
|
+
== Requirements
|
83
|
+
|
84
|
+
- ActiveSupport
|
85
|
+
- ActiveMigration
|
86
|
+
|
87
|
+
== License
|
88
|
+
|
89
|
+
(The MIT License)
|
90
|
+
|
91
|
+
Copyright (c) 2008 Matt Lins
|
92
|
+
|
93
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
94
|
+
a copy of this software and associated documentation files (the
|
95
|
+
'Software'), to deal in the Software without restriction, including
|
96
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
97
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
98
|
+
permit persons to whom the Software is furnished to do so, subject to
|
99
|
+
the following conditions:
|
100
|
+
|
101
|
+
The above copyright notice and this permission notice shall be
|
102
|
+
included in all copies or substantial portions of the Software.
|
103
|
+
|
104
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
105
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
106
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
107
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
108
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
109
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
110
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
desc 'Run the specs'
|
6
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
7
|
+
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
8
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
Rake::RDocTask.new do |t|
|
12
|
+
t.rdoc_dir = 'doc'
|
13
|
+
t.rdoc_files.include('README')
|
14
|
+
t.rdoc_files.include('lib/**/*.rb')
|
15
|
+
t.options << '--inline-source'
|
16
|
+
t.options << '--all'
|
17
|
+
t.options << '--line-numbers'
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
require 'jeweler'
|
22
|
+
Jeweler::Tasks.new do |s|
|
23
|
+
s.name = "godwit"
|
24
|
+
s.summary = "A framework to assist in the migration of data from legacy databases."
|
25
|
+
s.email = "mattlins@gmail.com"
|
26
|
+
s.homepage = "http://github.com/mlins/godwit"
|
27
|
+
s.description = "A framework to assist in the migration of data from legacy databases."
|
28
|
+
s.authors = ["Matt Lins"]
|
29
|
+
s.files = FileList["[A-Z]*", "{lib,spec,app_generators,godwit_generators,tmp}/**/*"]
|
30
|
+
s.executables = ['godwit']
|
31
|
+
s.add_dependency 'activesupport', '>= 2.1.0'
|
32
|
+
s.add_dependency 'mlins-active_migration', '>= 1.0.4'
|
33
|
+
s.add_dependency 'rubigen', '>= 1.3.4'
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
37
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
class GodwitGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
4
|
+
Config::CONFIG['ruby_install_name'])
|
5
|
+
|
6
|
+
default_options :author => nil
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(runtime_args, runtime_options = {})
|
11
|
+
super
|
12
|
+
usage if args.empty?
|
13
|
+
@destination_root = File.expand_path(args.shift)
|
14
|
+
@name = base_name
|
15
|
+
extract_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def manifest
|
19
|
+
record do |m|
|
20
|
+
# Ensure appropriate folder(s) exists
|
21
|
+
m.directory ''
|
22
|
+
BASEDIRS.each { |path| m.directory path }
|
23
|
+
|
24
|
+
script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
|
25
|
+
|
26
|
+
# Create stubs
|
27
|
+
# m.template "template.rb", "some_file_after_erb.rb"
|
28
|
+
# m.file "file", "some_file_copied"
|
29
|
+
|
30
|
+
# Config
|
31
|
+
%w(environment.rb database.yml).each do |file|
|
32
|
+
m.file "config/#{file}", "config/#{file}"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Scripts
|
36
|
+
%w(console migrate).each do |file|
|
37
|
+
m.file "script/#{file}", "script/#{file}", script_options
|
38
|
+
end
|
39
|
+
|
40
|
+
# Script Helper
|
41
|
+
m.file "script/lib/console.rb", "script/lib/console.rb"
|
42
|
+
|
43
|
+
# Blank Log
|
44
|
+
m.file "log/active_migration.log", "log/active_migration.log"
|
45
|
+
m.file "log/active_record.log", "log/active_record.log"
|
46
|
+
|
47
|
+
m.file "Rakefile", "Rakefile"
|
48
|
+
|
49
|
+
m.dependency "install_rubigen_scripts", [destination_root, 'godwit'],
|
50
|
+
:shebang => options[:shebang], :collision => :force
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def banner
|
56
|
+
'USAGE: godwit [application_name]'
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_options!(opts)
|
60
|
+
opts.separator ''
|
61
|
+
opts.separator 'Options:'
|
62
|
+
# For each option below, place the default
|
63
|
+
# at the top of the file next to "default_options"
|
64
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
65
|
+
# "Some comment about this option",
|
66
|
+
# "Default: none") { |options[:author]| }
|
67
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_options
|
71
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
72
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
73
|
+
# raw instance variable value.
|
74
|
+
# @author = options[:author]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Installation skeleton. Intermediate directories are automatically
|
78
|
+
# created so don't sweat their absence here.
|
79
|
+
BASEDIRS = %w(
|
80
|
+
lib
|
81
|
+
vendor
|
82
|
+
vendor/plugins
|
83
|
+
data
|
84
|
+
log
|
85
|
+
script/lib
|
86
|
+
tmp
|
87
|
+
config
|
88
|
+
app/models/legacy
|
89
|
+
app/migrations
|
90
|
+
)
|
91
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'godwit'
|
2
|
+
|
3
|
+
Godwit::Config.setup
|
4
|
+
Godwit::Config[:silence] = true
|
5
|
+
Godwit::Base.new
|
6
|
+
|
7
|
+
Dir["#{Godwit::Config[:godwit_root]}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
|
8
|
+
Dir["#{Godwit::Config[:godwit_root]}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Godwit::Config.use do |config|
|
2
|
+
|
3
|
+
# Change this if you would like to store key maps somewhere else.
|
4
|
+
#
|
5
|
+
#config[:key_mapper_path] = File.join(Godwit::Config[:godwit_root], 'tmp')
|
6
|
+
|
7
|
+
# This will load a Rails instance to use for your active dataset.
|
8
|
+
#
|
9
|
+
#config[:rails_root] = '/my/new/rails/app'
|
10
|
+
|
11
|
+
config[:active_record_log] = Logger.new(File.open(File.join(Godwit::Config[:godwit_root], 'log', 'active_record.log'), File::WRONLY | File::APPEND))
|
12
|
+
|
13
|
+
config[:active_record_log_level] = Logger::INFO
|
14
|
+
|
15
|
+
config[:active_migration_log] = Logger.new(File.open(File.join(Godwit::Config[:godwit_root], 'log', 'active_migration.log'), File::WRONLY | File::APPEND))
|
16
|
+
|
17
|
+
config[:active_migration_log_level] = Logger::INFO
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# This is usually just a dep warning, but we want it to fail.
|
22
|
+
Object.send :undef_method, :id
|
File without changes
|
File without changes
|
data/bin/godwit
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rubigen'
|
5
|
+
|
6
|
+
if %w(-v --version).include? ARGV.first
|
7
|
+
require 'godwit/version'
|
8
|
+
puts "#{File.basename($0)} #{Godwit::VERSION::STRING}"
|
9
|
+
exit(0)
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rubigen/scripts/generate'
|
13
|
+
source = RubiGen::PathSource.new(:application,
|
14
|
+
File.join(File.dirname(__FILE__), "../app_generators"))
|
15
|
+
RubiGen::Base.reset_sources
|
16
|
+
RubiGen::Base.append_sources source
|
17
|
+
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'godwit')
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class ActiveMigrationGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name, :active_model, :legacy_model
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
@active_model = args.shift
|
13
|
+
@legacy_model = args.shift
|
14
|
+
end
|
15
|
+
|
16
|
+
def manifest
|
17
|
+
record do |m|
|
18
|
+
# Ensure appropriate folder(s) exists
|
19
|
+
m.directory 'app/migrations/'
|
20
|
+
|
21
|
+
# Create stubs
|
22
|
+
m.template "active_migration.rb", "app/migrations/#{@name}_migration.rb"
|
23
|
+
# m.template_copy_each ["template.rb", "template2.rb"]
|
24
|
+
# m.file "file", "some_file_copied"
|
25
|
+
# m.file_copy_each ["path/to/file", "path/to/file2"]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def banner
|
31
|
+
<<-EOS
|
32
|
+
Creates an active migration
|
33
|
+
|
34
|
+
USAGE: #{$0} #{spec.name} name
|
35
|
+
EOS
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_options!(opts)
|
39
|
+
# opts.separator ''
|
40
|
+
# opts.separator 'Options:'
|
41
|
+
# For each option below, place the default
|
42
|
+
# at the top of the file next to "default_options"
|
43
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
44
|
+
# "Some comment about this option",
|
45
|
+
# "Default: none") { |options[:author]| }
|
46
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
47
|
+
end
|
48
|
+
|
49
|
+
def extract_options
|
50
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
51
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
52
|
+
# raw instance variable value.
|
53
|
+
# @author = options[:author]
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class ActiveModelGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest
|
15
|
+
record do |m|
|
16
|
+
# Ensure appropriate folder(s) exists
|
17
|
+
m.directory 'app/models/'
|
18
|
+
|
19
|
+
# Create stubs
|
20
|
+
m.template "active_model.rb", "app/models/#{@name}.rb"
|
21
|
+
# m.template_copy_each ["template.rb", "template2.rb"]
|
22
|
+
# m.file "file", "some_file_copied"
|
23
|
+
# m.file_copy_each ["path/to/file", "path/to/file2"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def banner
|
29
|
+
<<-EOS
|
30
|
+
Creates a active model
|
31
|
+
|
32
|
+
USAGE: #{$0} #{spec.name} name
|
33
|
+
EOS
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_options!(opts)
|
37
|
+
# opts.separator ''
|
38
|
+
# opts.separator 'Options:'
|
39
|
+
# For each option below, place the default
|
40
|
+
# at the top of the file next to "default_options"
|
41
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
42
|
+
# "Some comment about this option",
|
43
|
+
# "Default: none") { |options[:author]| }
|
44
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_options
|
48
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
49
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
50
|
+
# raw instance variable value.
|
51
|
+
# @author = options[:author]
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class LegacyModelGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest
|
15
|
+
record do |m|
|
16
|
+
# Ensure appropriate folder(s) exists
|
17
|
+
m.directory 'app/models/legacy'
|
18
|
+
|
19
|
+
# Create stubs
|
20
|
+
m.template "legacy_model.rb", "app/models/legacy/#{@name}.rb"
|
21
|
+
# m.template_copy_each ["template.rb", "template2.rb"]
|
22
|
+
# m.file "file", "some_file_copied"
|
23
|
+
# m.file_copy_each ["path/to/file", "path/to/file2"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def banner
|
29
|
+
<<-EOS
|
30
|
+
Creates a legacy model
|
31
|
+
|
32
|
+
USAGE: #{$0} #{spec.name} name
|
33
|
+
EOS
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_options!(opts)
|
37
|
+
# opts.separator ''
|
38
|
+
# opts.separator 'Options:'
|
39
|
+
# For each option below, place the default
|
40
|
+
# at the top of the file next to "default_options"
|
41
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
42
|
+
# "Some comment about this option",
|
43
|
+
# "Default: none") { |options[:author]| }
|
44
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_options
|
48
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
49
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
50
|
+
# raw instance variable value.
|
51
|
+
# @author = options[:author]
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module ActiveMigration #:nodoc:
|
2
|
+
class Base #:nodoc:
|
3
|
+
|
4
|
+
def initialize #:nodoc:
|
5
|
+
@error = false
|
6
|
+
@count = 0
|
7
|
+
@backspaces = -1
|
8
|
+
@percentage = 0
|
9
|
+
@printed_class = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle_error #:nodoc:
|
13
|
+
if Godwit::Config[:silence] || !Godwit::Config[:debug]
|
14
|
+
puts "\n\n\n"
|
15
|
+
raise ActiveMigrationError, 'Failed to save the active record. You should check the logs or run migrate with the -D option to debug.'
|
16
|
+
end
|
17
|
+
unless @error || @skip
|
18
|
+
debugger
|
19
|
+
@error = true
|
20
|
+
else
|
21
|
+
no_resolve
|
22
|
+
@error = false
|
23
|
+
handle_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def handle_success() #:nodoc:
|
28
|
+
return if Godwit::Config[:silence]
|
29
|
+
unless @error
|
30
|
+
success
|
31
|
+
else
|
32
|
+
resolve
|
33
|
+
success
|
34
|
+
@error = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def resolve #:nodoc:
|
39
|
+
system('clear')
|
40
|
+
puts "The error has been resolved."
|
41
|
+
puts "\nGodwit will continue the migration in 5 seconds..."
|
42
|
+
sleep(5)
|
43
|
+
system('clear')
|
44
|
+
print Godwit::Buffer.buffer
|
45
|
+
end
|
46
|
+
|
47
|
+
def no_resolve #:nodoc:
|
48
|
+
system('clear')
|
49
|
+
puts "You have not resolved the error!"
|
50
|
+
puts "Please make sure you check that @active_record.valid? is true before you type 'exit'."
|
51
|
+
puts "\nYou will return to the debug console in 5 seconds..."
|
52
|
+
sleep(5)
|
53
|
+
end
|
54
|
+
|
55
|
+
def debugger #:nodoc:
|
56
|
+
system('clear')
|
57
|
+
puts "Godwit " + Godwit::VERSION::STRING
|
58
|
+
puts "\nCurrent Migration: " + self.class.to_s
|
59
|
+
puts "\nYou encountered an invalid record while trying to save. You can attempt to reconcile this in the debug console."
|
60
|
+
puts "When you are done type 'exit' and godwit will try to save the record again. Do not try to save the record with #save yourself!"
|
61
|
+
puts "Use methods like #valid? and #errors to determine the problem."
|
62
|
+
puts "\nYou have the following instance variables available to manipulate:"
|
63
|
+
puts "\n@active_record\t\tThis is the record that failed to save. You should fix this record."
|
64
|
+
puts "@legacy_record\t\tThis should only be used for information. It is unwise to manipulate this object."
|
65
|
+
puts "@mapping\t\tThis should only be used for information. It is unwise to manipulate this object."
|
66
|
+
puts "\nLoading Debug Console..."
|
67
|
+
puts "\n"
|
68
|
+
IRB.start_session(binding)
|
69
|
+
end
|
70
|
+
|
71
|
+
def success #:nodoc:
|
72
|
+
if @active_record.is_a?(Array)
|
73
|
+
if @active_array
|
74
|
+
if @active_array != @active_record.object_id
|
75
|
+
@count += 1
|
76
|
+
@active_array = @active_record.object_id
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@count += 1
|
80
|
+
@active_array = @active_record.object_id
|
81
|
+
end
|
82
|
+
else
|
83
|
+
@count += 1
|
84
|
+
end
|
85
|
+
percent = ((@count.to_f / @num_of_records.to_f) * 100).to_i.to_s
|
86
|
+
return if (@percentage == percent) && @count > 1
|
87
|
+
@percentage = percent
|
88
|
+
if @count == 1 && !@printed_class
|
89
|
+
Godwit::Buffer.print("\n" + self.class.to_s + "\t\t\t")
|
90
|
+
@printed_class = true
|
91
|
+
end
|
92
|
+
Godwit::Buffer.print(("\b" * (@backspaces + 1)) + @percentage + '%')
|
93
|
+
@backspaces = @percentage.length
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|