migratrix 0.0.5 → 0.0.6
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/lib/migratrix.rb +5 -2
- data/lib/migratrix/loggable.rb +14 -0
- data/lib/migratrix/logger.rb +56 -0
- data/lib/migratrix/migration.rb +5 -18
- data/lib/migratrix/migratrix.rb +17 -22
- data/spec/lib/logger_spec.rb +89 -0
- data/spec/lib/migration_spec.rb +0 -12
- data/spec/lib/migratrix_spec.rb +26 -16
- data/spec/migratrix_module_spec.rb +41 -0
- data/spec/spec_helper.rb +31 -0
- metadata +7 -3
data/lib/migratrix.rb
CHANGED
@@ -5,12 +5,15 @@ module Migratrix
|
|
5
5
|
APP=Pathname.new(__FILE__).dirname + "migratrix"
|
6
6
|
EXT=Pathname.new(__FILE__).dirname + "patches"
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
def self.default_migrations_path
|
9
|
+
Rails.root + 'lib/migrations'
|
10
|
+
end
|
10
11
|
|
11
12
|
require EXT + 'string_ext'
|
12
13
|
require EXT + 'object_ext'
|
13
14
|
require EXT + 'andand'
|
15
|
+
require APP + 'logger'
|
16
|
+
require APP + 'loggable'
|
14
17
|
require APP + 'exceptions'
|
15
18
|
require APP + 'migration'
|
16
19
|
require APP + 'migratrix'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Migratrix
|
2
|
+
class Logger
|
3
|
+
attr_accessor :level, :stream
|
4
|
+
|
5
|
+
FATAL = 0
|
6
|
+
ERROR = 1
|
7
|
+
WARN = 2
|
8
|
+
DEBUG = 3
|
9
|
+
INFO = 4
|
10
|
+
|
11
|
+
@@singleton_instance = new
|
12
|
+
|
13
|
+
def self.logger
|
14
|
+
@@singleton_instance
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.set_logger(stream=$stdout, level=INFO)
|
18
|
+
self.logger.stream=stream
|
19
|
+
self.logger.level=level
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(stream, level)
|
23
|
+
# :nocov: SimpleCov can't see into this method.
|
24
|
+
@stream, @level = stream, level
|
25
|
+
end
|
26
|
+
|
27
|
+
def fatal(msg)
|
28
|
+
log(msg, FATAL)
|
29
|
+
end
|
30
|
+
|
31
|
+
def error(msg)
|
32
|
+
log(msg, ERROR)
|
33
|
+
end
|
34
|
+
|
35
|
+
def warn(msg)
|
36
|
+
log(msg, WARN)
|
37
|
+
end
|
38
|
+
|
39
|
+
def debug(msg)
|
40
|
+
log(msg, DEBUG)
|
41
|
+
end
|
42
|
+
|
43
|
+
def info(msg)
|
44
|
+
log(msg, INFO)
|
45
|
+
end
|
46
|
+
|
47
|
+
def log(msg, level)
|
48
|
+
if level <= @level
|
49
|
+
@stream.puts "%c %s: %s" % ["FEWDI"[level], Time.now.strftime("%F %T"), msg]
|
50
|
+
@stream.flush
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private_class_method :new
|
55
|
+
end
|
56
|
+
end
|
data/lib/migratrix/migration.rb
CHANGED
@@ -2,21 +2,14 @@ module Migratrix
|
|
2
2
|
# Superclass for all migrations. Migratrix COULD check to see that a
|
3
3
|
# loaded migration inherits from this class, but hey, duck typing.
|
4
4
|
class Migration
|
5
|
-
|
5
|
+
include ::Migratrix::Loggable
|
6
|
+
extend ::Migratrix::Loggable::ClassMethods
|
7
|
+
|
8
|
+
attr_accessor :options
|
6
9
|
|
7
10
|
def initialize(options={})
|
8
11
|
# cannot make a deep copy of an IO stream (e.g. logger) so make a shallow copy of it and move it out of the way
|
9
|
-
@options = options.
|
10
|
-
|
11
|
-
# if options["logger"]
|
12
|
-
# @logger = options["logger"]
|
13
|
-
# options = options.dup
|
14
|
-
# options.delete["logger"]
|
15
|
-
# end
|
16
|
-
# @options = options.deep_copy
|
17
|
-
# This should only be loaded if a) the Migration uses the AR
|
18
|
-
# extract strategy and b) it's not already loaded
|
19
|
-
# ::ActiveRecord::Base.send(:include, MigrationHelpers) unless ::ActiveRecord::Base.const_defined?("MigrationHelpers")
|
12
|
+
@options = options.deep_copy
|
20
13
|
end
|
21
14
|
|
22
15
|
# Load this data from source
|
@@ -41,12 +34,6 @@ module Migratrix
|
|
41
34
|
transform
|
42
35
|
load
|
43
36
|
end
|
44
|
-
|
45
|
-
def self.log(msg="", level=:info)
|
46
|
-
return unless logger
|
47
|
-
level = :info unless level.in? [:debug, :info, :warn, :error, :fatal, :unknown]
|
48
|
-
logger.send level, "#{Time.now.strftime('%T')}: #{msg}"
|
49
|
-
end
|
50
37
|
end
|
51
38
|
end
|
52
39
|
|
data/lib/migratrix/migratrix.rb
CHANGED
@@ -2,12 +2,25 @@
|
|
2
2
|
# and integrating all the parts of a migration.
|
3
3
|
|
4
4
|
module Migratrix
|
5
|
-
|
6
|
-
def migrate(name, options={})
|
5
|
+
def self.migrate!(name, options={})
|
7
6
|
::Migratrix::Migratrix.migrate(name, options)
|
8
7
|
end
|
9
8
|
|
9
|
+
def self.logger
|
10
|
+
::Migratrix::Migratrix.logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.logger=(new_logger)
|
14
|
+
::Migratrix::Migratrix.logger= new_logger
|
15
|
+
end
|
16
|
+
|
10
17
|
class Migratrix
|
18
|
+
include ::Migratrix::Loggable
|
19
|
+
extend ::Migratrix::Loggable::ClassMethods
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
end
|
23
|
+
|
11
24
|
def self.migrate(name, options={})
|
12
25
|
migratrix = self.new()
|
13
26
|
migration = migratrix.create_migration(name, options)
|
@@ -46,7 +59,7 @@ module Migratrix
|
|
46
59
|
end
|
47
60
|
|
48
61
|
def valid_options
|
49
|
-
%w(limit where
|
62
|
+
%w(limit where)
|
50
63
|
end
|
51
64
|
|
52
65
|
# ----------------------------------------------------------------------
|
@@ -69,30 +82,12 @@ module Migratrix
|
|
69
82
|
# End MigrationRegistry
|
70
83
|
# ----------------------------------------------------------------------
|
71
84
|
|
72
|
-
# ----------------------------------------------------------------------
|
73
|
-
# Migration path class accessors. Defaults to lib/migrations.
|
74
85
|
def migrations_path
|
75
|
-
@migrations_path ||= ::Migratrix
|
86
|
+
@migrations_path ||= ::Migratrix.default_migrations_path
|
76
87
|
end
|
77
88
|
|
78
89
|
def migrations_path=(new_path)
|
79
90
|
@migrations_path = Pathname.new new_path
|
80
91
|
end
|
81
|
-
|
82
|
-
# def self.migrations_path
|
83
|
-
# @@migrations_path ||= ::Migratrix::DEFAULT_MIGRATIONS_PATH
|
84
|
-
# end
|
85
|
-
|
86
|
-
# def self.migrations_path=(new_path)
|
87
|
-
# @@migrations_path = Pathname.new new_path
|
88
|
-
# end
|
89
|
-
# End Migration path management
|
90
|
-
# ----------------------------------------------------------------------
|
91
|
-
|
92
|
-
# def self.log(msg="", level=:info)
|
93
|
-
# return if quiet
|
94
|
-
# level = :info unless level.in? [:debug, :info, :warn, :error, :fatal, :unknown]
|
95
|
-
# logger.send level, "#{Time.now.strftime('%T')}: #{msg}"
|
96
|
-
# end
|
97
92
|
end
|
98
93
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Migratrix::Logger do
|
4
|
+
let(:logger) { Migratrix::Logger.logger }
|
5
|
+
|
6
|
+
describe "sanity check kitty" do
|
7
|
+
it "is sanity checked" do
|
8
|
+
Migratrix::Logger.should_not be_nil
|
9
|
+
Migratrix::Logger.class.should == Class
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "singleton-ness" do
|
14
|
+
it "is singleton-y" do
|
15
|
+
Migratrix::Logger.logger.class.should == Migratrix::Logger
|
16
|
+
end
|
17
|
+
|
18
|
+
it "cannot be new'ed" do
|
19
|
+
lambda { Migratrix::Logger.new }.should raise_error(NoMethodError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "default" do
|
24
|
+
it "logs to $stdout" do
|
25
|
+
logger.stream == $stdout
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe "logging" do
|
31
|
+
let(:buffer) { StringIO.new }
|
32
|
+
|
33
|
+
before do
|
34
|
+
Timecop.freeze(Time.local(2011, 6, 28, 3, 14, 15))
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
Timecop.return
|
39
|
+
end
|
40
|
+
|
41
|
+
it "formats info message with level and timestamp" do
|
42
|
+
with_logger_streaming_to(buffer) do
|
43
|
+
logger.info("Test Message")
|
44
|
+
buffer.string.should == "I 2011-06-28 03:14:15: Test Message\n"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "formats debug message with level and timestamp" do
|
49
|
+
with_logger_streaming_to(buffer) do
|
50
|
+
logger.debug("Test Message")
|
51
|
+
buffer.string.should == "D 2011-06-28 03:14:15: Test Message\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "formats warning message with level and timestamp" do
|
56
|
+
with_logger_streaming_to(buffer) do
|
57
|
+
logger.warn("Test Message")
|
58
|
+
buffer.string.should == "W 2011-06-28 03:14:15: Test Message\n"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "formats error message with level and timestamp" do
|
63
|
+
with_logger_streaming_to(buffer) do
|
64
|
+
logger.error("Test Message")
|
65
|
+
buffer.string.should == "E 2011-06-28 03:14:15: Test Message\n"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "formats fatal message with level and timestamp" do
|
70
|
+
with_logger_streaming_to(buffer) do
|
71
|
+
logger.fatal("Test Message")
|
72
|
+
buffer.string.should == "F 2011-06-28 03:14:15: Test Message\n"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "rejects messages below logger level" do
|
77
|
+
with_logger_streaming_to(buffer, Migratrix::Logger::ERROR) do
|
78
|
+
logger.info("Test Message")
|
79
|
+
logger.debug("Test Message")
|
80
|
+
logger.warn("Test Message")
|
81
|
+
buffer.size.should == 0
|
82
|
+
logger.error("Test Error")
|
83
|
+
logger.fatal("Test Fatal")
|
84
|
+
buffer.string.should == "E 2011-06-28 03:14:15: Test Error\nF 2011-06-28 03:14:15: Test Fatal\n"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
data/spec/lib/migration_spec.rb
CHANGED
@@ -17,18 +17,6 @@ describe Migratrix::Migration do
|
|
17
17
|
migration.options["where"].should == ["id=? AND approved=? AND pants=?", 42, true, false]
|
18
18
|
conditions.should == ["id=? AND approved=?", 42, true]
|
19
19
|
end
|
20
|
-
|
21
|
-
it "safely moves logger option out of its options and into logger attribute" do
|
22
|
-
conditions = ["id=? AND approved=?", 42, true]
|
23
|
-
logger = Logger.new(StringIO.new)
|
24
|
-
options = { "where" => conditions, "logger" => logger }
|
25
|
-
|
26
|
-
migration = Migratrix::TestMigration.new(options)
|
27
|
-
|
28
|
-
migration.options.should_not have_key("logger")
|
29
|
-
migration.logger.should == logger
|
30
|
-
options.should == { "where" => conditions, "logger" => logger }
|
31
|
-
end
|
32
20
|
end
|
33
21
|
|
34
22
|
describe "#migrate" do
|
data/spec/lib/migratrix_spec.rb
CHANGED
@@ -1,19 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
# Migatrix loads Migration classes into its namespace. In order to
|
4
|
-
# test collision prevention, I needed to reach into Migratrix and
|
5
|
-
# mindwipe it of any migrations. Here's the shiv to do that. I
|
6
|
-
# originally put an API to do this on Migratrix but these specs are
|
7
|
-
# the only clients of it so I removed it again. If you find a
|
8
|
-
# legitimate use for it, feel free to re-add a remove_migration
|
9
|
-
# method and send me a patch.
|
10
|
-
def reset_migratrix!(migratrix)
|
11
|
-
Migratrix.constants.map(&:to_s).select {|m| m =~ /.+Migration$/}.each do |migration|
|
12
|
-
Migratrix.send(:remove_const, migration.to_sym)
|
13
|
-
end
|
14
|
-
migratrix.registered_migrations.clear
|
15
|
-
end
|
16
|
-
|
17
3
|
describe Migratrix::Migratrix do
|
18
4
|
let (:migratrix) { Migratrix::Migratrix.new }
|
19
5
|
|
@@ -60,7 +46,7 @@ describe Migratrix::Migratrix do
|
|
60
46
|
|
61
47
|
describe "#valid_options" do
|
62
48
|
it "returns the valid set of option keys" do
|
63
|
-
migratrix.valid_options.should == ["limit", "where"
|
49
|
+
migratrix.valid_options.should == ["limit", "where"]
|
64
50
|
end
|
65
51
|
end
|
66
52
|
|
@@ -110,7 +96,31 @@ describe Migratrix::Migratrix do
|
|
110
96
|
it "loads migration and migrates it" do
|
111
97
|
Migratrix::Migratrix.stub!(:new).and_return(migratrix)
|
112
98
|
Migratrix::Migratrix.migrate :marbles
|
113
|
-
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe ".logger" do
|
103
|
+
it "sets up a default logger to stdout" do
|
104
|
+
migratrix.logger.class.should == ::Migratrix::Logger
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe ".logger=" do
|
109
|
+
let (:migration) { migratrix.create_migration :marbles }
|
110
|
+
let (:buffer) { StringIO.new }
|
111
|
+
|
112
|
+
before do
|
113
|
+
reset_migratrix! migratrix
|
114
|
+
migratrix.migrations_path = SPEC + "fixtures/migrations"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "sets logger globally across all Migratrices, the Migratrix module, Migrators and Models" do
|
118
|
+
with_logger_streaming_to(buffer) do
|
119
|
+
Migratrix.logger.stream.should == buffer
|
120
|
+
Migratrix::Migratrix.logger.stream.should == buffer
|
121
|
+
migratrix.logger.stream.should == buffer
|
122
|
+
migration.logger.stream.should == buffer
|
123
|
+
end
|
114
124
|
end
|
115
125
|
end
|
116
126
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Migratrix do
|
4
|
+
describe "sanity check kitty" do
|
5
|
+
it "is sanity checked" do
|
6
|
+
Migratrix.should_not be_nil
|
7
|
+
Migratrix.class.should == Module
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".migrate!" do
|
12
|
+
let (:migratrix) { Migratrix::Migratrix.new }
|
13
|
+
|
14
|
+
before do
|
15
|
+
reset_migratrix! migratrix
|
16
|
+
Migratrix::Migratrix.stub!(:new).and_return(migratrix)
|
17
|
+
migratrix.migrations_path = SPEC + "fixtures/migrations"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "delegates to Migratrix::Migratrix" do
|
21
|
+
Migratrix.migrate! :marbles
|
22
|
+
Migratrix::MarblesMigration.should be_migrated
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".logger" do
|
27
|
+
it "delegates to Migratrix::Migratrix" do
|
28
|
+
Migratrix::Migratrix.should_receive(:logger).and_return nil
|
29
|
+
Migratrix.logger
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".logger=" do
|
34
|
+
let (:logger) { Logger.new(StringIO.new) }
|
35
|
+
it "delegates to Migratrix::Migratrix" do
|
36
|
+
Migratrix::Migratrix.should_receive(:logger=).with(logger).and_return nil
|
37
|
+
Migratrix.logger = logger
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -6,6 +6,7 @@ end
|
|
6
6
|
require 'pathname'
|
7
7
|
require 'ruby-debug'
|
8
8
|
require 'rails'
|
9
|
+
require 'timecop'
|
9
10
|
require 'logger'
|
10
11
|
|
11
12
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
@@ -26,6 +27,36 @@ Dir[SPEC + "support/**/*.rb"].each {|f| require f}
|
|
26
27
|
|
27
28
|
require LIB + 'migratrix'
|
28
29
|
|
30
|
+
# Migatrix loads Migration classes into its namespace. In order to
|
31
|
+
# test collision prevention, I needed to reach into Migratrix and
|
32
|
+
# mindwipe it of any migrations. Here's the shiv to do that. I
|
33
|
+
# originally put an API to do this on Migratrix but these specs are
|
34
|
+
# the only clients of it so I removed it again. If you find a
|
35
|
+
# legitimate use for it, feel free to re-add a remove_migration
|
36
|
+
# method and send me a patch.
|
37
|
+
def reset_migratrix!(migratrix)
|
38
|
+
Migratrix.constants.map(&:to_s).select {|m| m =~ /.+Migration$/}.each do |migration|
|
39
|
+
Migratrix.send(:remove_const, migration.to_sym)
|
40
|
+
end
|
41
|
+
migratrix.registered_migrations.clear
|
42
|
+
end
|
43
|
+
|
44
|
+
# Redirect singleton logger to stream and level of our choice, then
|
45
|
+
# release it after the spec finishes or crashes.
|
46
|
+
def with_logger_streaming_to(stream, level=Migratrix::Logger::INFO, &block)
|
47
|
+
begin
|
48
|
+
old_stream, old_level = Migratrix::Logger.logger.stream, Migratrix::Logger.logger.level
|
49
|
+
Migratrix::Logger.set_logger(stream, level)
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
Migratrix::Logger.set_logger old_stream, old_level
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
29
60
|
RSpec.configure do |config|
|
30
61
|
# == Mock Framework
|
31
62
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: migratrix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-10-14 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: trollop
|
16
|
-
requirement: &
|
16
|
+
requirement: &2161683820 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2161683820
|
25
25
|
description: Migratrix, a Rails legacy database migration tool supporting multiple
|
26
26
|
strategies, including arbitrary n-ary migrations (1->n, n->1, n->m), arbitrary inputs
|
27
27
|
and outputs (ActiveRecord, bare SQL, CSV) and migration logging
|
@@ -38,15 +38,19 @@ files:
|
|
38
38
|
- lib/migratrix.rb
|
39
39
|
- lib/migratrix/active_record_migration_helpers.rb
|
40
40
|
- lib/migratrix/exceptions.rb
|
41
|
+
- lib/migratrix/loggable.rb
|
42
|
+
- lib/migratrix/logger.rb
|
41
43
|
- lib/migratrix/migration.rb
|
42
44
|
- lib/migratrix/migratrix.rb
|
43
45
|
- lib/patches/andand.rb
|
44
46
|
- lib/patches/object_ext.rb
|
45
47
|
- lib/patches/string_ext.rb
|
46
48
|
- spec/fixtures/migrations/marbles_migration.rb
|
49
|
+
- spec/lib/logger_spec.rb
|
47
50
|
- spec/lib/migration_spec.rb
|
48
51
|
- spec/lib/migrator_spec.rb
|
49
52
|
- spec/lib/migratrix_spec.rb
|
53
|
+
- spec/migratrix_module_spec.rb
|
50
54
|
- spec/patches/object_ext_spec.rb
|
51
55
|
- spec/patches/string_ext_spec.rb
|
52
56
|
- spec/spec_helper.rb
|