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 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
- DEFAULT_MIGRATIONS_PATH = Rails.root + 'lib/migrations'
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,14 @@
1
+ module Migratrix
2
+ module Loggable
3
+ module ClassMethods
4
+ def logger
5
+ ::Migratrix::Logger.logger
6
+ end
7
+ end
8
+
9
+ def logger
10
+ ::Migratrix::Logger.logger
11
+ end
12
+
13
+ end
14
+ end
@@ -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
@@ -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
- attr_accessor :options, :logger
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.dup.tap {|h| @logger = h.delete("logger")}.deep_copy
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
 
@@ -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 logger)
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::DEFAULT_MIGRATIONS_PATH
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
@@ -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
@@ -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", "logger"]
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
- Migratrix::MarblesMigration.should be_migrated
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.5
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: &2153520180 !ruby/object:Gem::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: *2153520180
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