migratrix 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|