pg_migrate 0.0.1 → 0.1.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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pg_migrate (0.0.1)
4
+ pg_migrate (0.1.0)
5
5
  logging (= 1.7.2)
6
6
  pg (= 0.14.0)
7
7
  thor (= 0.15.4)
@@ -8,10 +8,8 @@ module PgMigrate
8
8
  # takes a unprocessed manifest directory, and adds before/after headers to each file
9
9
  class Builder
10
10
 
11
-
12
11
  attr_accessor :manifest_reader, :sql_reader
13
12
 
14
-
15
13
  def initialize(manifest_reader, sql_reader)
16
14
  @log = Logging.logger[self]
17
15
  @manifest_reader = manifest_reader
@@ -26,7 +24,7 @@ module PgMigrate
26
24
  def build(input_dir, output_dir, options={:force=>true})
27
25
  input_dir = File.expand_path(input_dir)
28
26
  output_dir = File.expand_path(output_dir)
29
-
27
+
30
28
  if input_dir == output_dir
31
29
  raise 'input_dir can not be same as output_dir: #{input_dir}'
32
30
  end
@@ -36,7 +34,7 @@ module PgMigrate
36
34
  output = Pathname.new(output_dir)
37
35
  if !output.exist?
38
36
  if !options[:force]
39
- raise "Output directory '#{output_dir}' does not exist. Create it or specify create_output_dir=true"
37
+ raise "Output directory '#{output_dir}' does not exist. Create it or specify force=true"
40
38
  else
41
39
  output.mkpath
42
40
  end
@@ -64,6 +62,18 @@ module PgMigrate
64
62
  end
65
63
  end
66
64
 
65
+ # if .pg_migrate file exists, copy it
66
+ input_pg_config = File.join(input_dir, PG_CONFIG)
67
+ if FileTest::exist? input_pg_config
68
+ output_pg_config = File.join(output_dir, PG_CONFIG)
69
+
70
+ File.open(output_pg_config, 'w') do |fout|
71
+ IO.readlines(input_pg_config).each do |input|
72
+ fout.puts input
73
+ end
74
+ end
75
+ end
76
+
67
77
  # in order array of manifest declarations
68
78
  loaded_manifest = @manifest_reader.load_input_manifest(input_dir)
69
79
  # hashed on migration name hash of manifest
@@ -71,13 +81,17 @@ module PgMigrate
71
81
  loaded_manifest_hash = @manifest_reader.hash_loaded_manifest(loaded_manifest)
72
82
  @manifest_reader.validate_migration_paths(input_dir, loaded_manifest)
73
83
 
74
- build_up(input_dir, output_dir, loaded_manifest_hash)
84
+ build_up(input_dir, output_dir, loaded_manifest_hash, loaded_manifest)
75
85
  end
76
86
 
77
- def build_up(input_dir, output_dir, loaded_manifest_hash)
87
+ def build_up(input_dir, output_dir, loaded_manifest_hash, loaded_manifest)
78
88
  migrations_input = File.join(input_dir, UP_DIRNAME)
79
89
  migrations_output = File.join(output_dir, UP_DIRNAME)
80
90
 
91
+ if(!FileTest::exist? migrations_input)
92
+ raise "'up' directory must exist at #{migrations_input}"
93
+ end
94
+
81
95
  # iterate through files in input migrations path, wrapping files with transactions and other required bits
82
96
 
83
97
  Find.find(migrations_input) do |path|
@@ -95,7 +109,7 @@ module PgMigrate
95
109
  # create the filename correct for the output directory, for this file
96
110
  migration_out_path = File.join(migrations_output, relative_path)
97
111
 
98
- process_and_copy_up(migration_in_path, migration_out_path, relative_path, loaded_manifest_hash)
112
+ process_and_copy_up(migration_in_path, migration_out_path, relative_path, loaded_manifest_hash, loaded_manifest)
99
113
  end
100
114
  end
101
115
 
@@ -107,10 +121,11 @@ module PgMigrate
107
121
  run_template("bootstrap.erb", binding, File.join(migration_out_path, BOOTSTRAP_FILENAME))
108
122
  end
109
123
 
110
- def create_wrapped_up_migration(migration_in_filepath, migration_out_filepath, migration_def)
111
- builder_version="pg_migrate_ruby-#{PgMigrate::VERSION}"
124
+ def create_wrapped_up_migration(migration_in_filepath, migration_out_filepath, migration_def, loaded_manifest)
125
+ builder_version="pg_migrate_ruby-#{PgMigrate::VERSION}"
126
+ manifest_version=loaded_manifest[-1].ordinal
112
127
  migration_content = nil
113
- File.open(migration_in_filepath, 'r') {|reader| migration_content = reader.read }
128
+ File.open(migration_in_filepath, 'r') { |reader| migration_content = reader.read }
114
129
  run_template("up.erb", binding, File.join(migration_out_filepath))
115
130
  end
116
131
 
@@ -129,7 +144,7 @@ module PgMigrate
129
144
  end
130
145
  end
131
146
 
132
- def process_and_copy_up(migration_in_path, migration_out_path, relative_path, loaded_manifest_hash)
147
+ def process_and_copy_up(migration_in_path, migration_out_path, relative_path, loaded_manifest_hash, loaded_manifest)
133
148
 
134
149
  if FileTest.directory?(migration_in_path)
135
150
  # copy over directories
@@ -147,7 +162,7 @@ module PgMigrate
147
162
 
148
163
  migration_def = loaded_manifest_hash[manifest_name]
149
164
 
150
- create_wrapped_up_migration(migration_in_path, migration_out_path, migration_def)
165
+ create_wrapped_up_migration(migration_in_path, migration_out_path, migration_def, loaded_manifest)
151
166
  else
152
167
  # if not a .sql file, just copy it over
153
168
  FileUtils.cp(migration_in_path, migration_out_path)
@@ -1,31 +1,56 @@
1
1
  module PgMigrate
2
2
  class CommandLine < Thor
3
3
 
4
+ @@packaged_source = '.'
5
+
6
+ def initialize(*args)
7
+ super
8
+ end
9
+
10
+ def self.packaged_source
11
+ @@packaged_source
12
+ end
13
+
14
+ def self.packaged_source=(value)
15
+ @@packaged_source = value
16
+ end
17
+
18
+
4
19
  desc "up", "migrates the database forwards, applying migrations found in the source directory"
5
- method_option :source, :aliases => "-s", :default => '.', :lazy_default => '.', :banner => 'input directory', :desc => "a pg_migrate built manifest. Should contain your processed manifest and up|down|test folders"
6
- method_option :connopts, :aliases => "-o", :type => :hash, :required => true, :banner => "connection options", :desc => "database connection options used by gem 'pg': dbname|host|hostaddr|port|user|password|connection_timeout|options|sslmode|krbsrvname|gsslib|service"
7
- method_option :verbose, :aliases => "-v", :type => :boolean, :default => false, :banner => "verbose", :desc=> "set to raise verbosity"
20
+ method_option :source, :aliases => "-s", :default => nil, :banner => 'input directory', :desc => "a pg_migrate built manifest. Should contain your processed manifest and up|down|test folders"
21
+ method_option :connopts, :aliases => "-c", :type => :hash, :required => true, :banner => "connection options", :desc => "database connection options used by gem 'pg': dbname|host|hostaddr|port|user|password|connection_timeout|options|sslmode|krbsrvname|gsslib|service"
22
+ method_option :verbose, :aliases => "-v", :type => :boolean, :banner => "verbose", :desc=> "set to raise verbosity"
8
23
 
9
24
  def up
10
- bootstrap_logger(options[:verbose])
25
+ source = options[:source]
26
+
27
+ if source.nil?
28
+ source = @@packaged_source
29
+ end
30
+
31
+ method_defaults = {"verbose" => false}
32
+ local_options = set_defaults_from_file(method_defaults, "up", source)
33
+ local_options = local_options.merge(options)
34
+
35
+ bootstrap_logger(local_options["verbose"])
11
36
 
12
37
  manifest_reader = ManifestReader.new
13
38
  sql_reader = SqlReader.new
14
39
 
15
- connopts = options[:connopts]
16
- if !connopts[:port].nil?
40
+ connopts = local_options["connopts"]
41
+ if !connopts["port"].nil?
17
42
  connopts[:port] = connopts[:port].to_i
18
43
  end
19
44
 
20
45
  migrator = Migrator.new(manifest_reader, sql_reader, connopts)
21
46
 
22
47
  begin
23
- migrator.migrate(options[:source])
48
+ migrator.migrate(source)
24
49
  rescue Exception => e
25
- if !options[:verbose]
50
+ if !local_options["verbose"]
26
51
  # catch common exceptions and make pretty on command-line
27
52
  if !e.message.index("ManifestReader: code=unloadable_manifest").nil?
28
- puts "Unable to load manifest in source directory '#{options[:source]}' . Check -s|--source option and run again."
53
+ puts "Unable to load manifest in source directory '#{source}' . Check -s|--source option and run again."
29
54
  exit 1
30
55
  else
31
56
  raise e
@@ -41,25 +66,81 @@ module PgMigrate
41
66
  desc "down", "not implemented"
42
67
 
43
68
  def down
69
+ local_options = options
70
+ options = set_defaults_from_file(location_options)
44
71
  bootstrap_logger(options[:verbose])
45
72
 
46
73
  raise 'Not implemented'
47
74
  end
48
75
 
49
76
  desc "build", "processes a pg_migrate source directory and places the result in the specified output directory"
50
- method_option :source, :aliases => "-s", :default => '.', :lazy_default => '.', :banner => 'input directory', :desc => "the input directory containing a manifest file and up|down|test folders"
51
- method_option :out, :aliases => "-o", :required => true, :banner => "output directory", :desc => "where the processed migrations will be placed"
52
- method_option :force, :aliases => "-f", :default => false, :type => :boolean, :banner => "overwrite out", :desc => "if specified, the out directory will be created before processing occurs, replacing any existing directory"
53
- method_option :verbose, :aliases => "-v", :type => :boolean, :default => false, :banner => "verbose", :desc=> "set to raise verbosity"
77
+ method_option :source, :aliases => "-s", :default => nil, :banner => 'input directory', :desc => "the input directory containing a manifest file and up|down|test folders"
78
+ method_option :out, :aliases => "-o", :banner => "output directory", :desc => "where the processed migrations will be placed"
79
+ method_option :force, :aliases => "-f", :type => :boolean, :banner => "overwrite out", :desc => "if specified, the out directory will be created before processing occurs, replacing any existing directory"
80
+ method_option :verbose, :aliases => "-v", :type => :boolean, :banner => "verbose", :desc=> "set to raise verbosity"
54
81
 
55
82
  def build
83
+ source = options[:source]
56
84
 
57
- bootstrap_logger(options[:verbose])
85
+ if source.nil?
86
+ source = @@packaged_source
87
+ end
88
+
89
+ method_defaults = {"force" => false, "verbose" => false}
90
+ local_options = set_defaults_from_file(method_defaults, "build", source)
91
+ local_options = local_options.merge(options)
92
+
93
+ bootstrap_logger(local_options["verbose"])
94
+
95
+ if !local_options["out"]
96
+ puts "error: --out not specified"
97
+ exit 1
98
+ end
58
99
 
59
100
  manifest_reader = ManifestReader.new
60
101
  sql_reader = SqlReader.new
61
102
  builder = Builder.new(manifest_reader, sql_reader)
62
- builder.build(options[:source], options[:out], :force => options[:force])
103
+ builder.build(source, local_options["out"], :force => local_options["force"])
104
+ end
105
+
106
+
107
+ desc "package", "packages a built pg_migrate project into a custom gem containing schemas and simpler migration interface"
108
+ method_option :source, :aliases => "-s", :default => nil, :banner => 'input directory', :desc => "the input directory containing a manifest file and up|down|test folders that has been previously built by pg_migrate build"
109
+ method_option :out, :aliases => "-o", :banner => "output directory", :desc => "where the gem will be placed (as well as the exploded gem's contents)"
110
+ method_option :name, :aliases => "-n", :banner => "the name of the schema gem", :desc => "the name of the gem"
111
+ method_option :version, :aliases => "-e", :banner => "the version of the schema gem", :desc => "the version of the gem"
112
+ method_option :force, :aliases => "-f", :type => :boolean, :banner => "overwrite out", :desc => "if specified, the out directory will be created before processing occurs, replacing any existing directory"
113
+ method_option :verbose, :aliases => "-v", :type => :boolean, :banner => "verbose", :desc=> "set to raise verbosity"
114
+
115
+ def package
116
+ source = options[:source]
117
+
118
+ if source.nil?
119
+ source = @@packaged_source
120
+ end
121
+
122
+ method_defaults = {"force" => false, "verbose" => false}
123
+ local_options = set_defaults_from_file(method_defaults, "package", source)
124
+ local_options = local_options.merge(options)
125
+
126
+ if !local_options["out"]
127
+ puts "error: --out not specified"
128
+ exit 1
129
+ end
130
+ if !local_options["name"]
131
+ puts "error: --version not specified"
132
+ exit 1
133
+ end
134
+ if !local_options["version"]
135
+ puts "error: --version not specified"
136
+ exit 1
137
+ end
138
+
139
+ bootstrap_logger(local_options["verbose"])
140
+
141
+ manifest_reader = ManifestReader.new
142
+ builder = Package.new(manifest_reader)
143
+ builder.package(source, local_options["out"], local_options["name"], local_options["version"], :force => local_options["force"])
63
144
  end
64
145
 
65
146
  no_tasks do
@@ -73,6 +154,40 @@ module PgMigrate
73
154
 
74
155
  Logging.logger.root.appenders = Logging.appenders.stdout
75
156
  end
157
+
158
+
159
+ def set_defaults_from_file(default_options, context, source)
160
+ @file_defaults = @file_defaults ||= load_file(context, source)
161
+ merged = default_options.merge(@file_defaults)
162
+ end
163
+
164
+ def load_file(context, source)
165
+
166
+ defaults = nil
167
+ config = File.join(source, PG_CONFIG)
168
+ if FileTest::exist? (config)
169
+ puts "found #{PG_CONFIG}"
170
+ defaults = Properties.new(config)
171
+ else
172
+ defaults = Properties.new
173
+ end
174
+
175
+ map = {}
176
+ defaults.each_pair do |k, v|
177
+ map[k.upcase] = v
178
+
179
+ # make a context-removed version of a key, if it starts with 'context.'
180
+ prefix = "#{context}."
181
+ if k.start_with? prefix
182
+ map[k[prefix.length..-1]] = v
183
+ end
184
+ end
185
+
186
+ return map
187
+
188
+ end
76
189
  end
190
+
191
+
77
192
  end
78
193
  end
@@ -52,18 +52,17 @@ module PgMigrate
52
52
 
53
53
  manifest_filepath = File.join(manifest_path, MANIFEST_FILENAME)
54
54
 
55
- @log.debug "loading manifest from #{manifest_path}"
55
+ @log.debug "loading manifest from #{manifest_filepath}"
56
56
 
57
+ # there should be a file called 'manifest' at this location
57
58
  if !FileTest::exist?(manifest_filepath)
58
- raise "ManifestReader: code=unloadable_manifest: manifest not found at #{manifest_path}"
59
+ raise "ManifestReader: code=unloadable_manifest: manifest not found at #{manifest_filepath}"
59
60
  end
60
61
 
61
- # there should be a file called 'manifest' at this location
62
62
  manifest_lines = IO.readlines(manifest_filepath)
63
63
 
64
64
  ordinal = 0
65
65
  manifest_lines.each_with_index do |line, index|
66
- # ignore comments
67
66
  migration_name = line.strip
68
67
 
69
68
  @log.debug "processing line:#{index} #{line}"
@@ -76,15 +75,16 @@ module PgMigrate
76
75
  version = migration_name[BUILDER_VERSION_HEADER.length..-1]
77
76
  @log.debug "manifest has builder_version #{version}"
78
77
  else
79
- raise "manifest invalid: missing/malformed version. expecting '# pg_migrate-VERSION' to begin first line '#{line}' of manifest file: '#{manifest_path}'"
78
+ raise "manifest invalid: missing/malformed version. expecting '# pg_migrate-VERSION' to begin first line '#{line}' of manifest file: '#{manifest_filepath}'"
80
79
  end
81
80
  end
82
81
  end
83
82
 
83
+ # ignore comments
84
84
  if migration_name.empty? or migration_name.start_with?('#')
85
85
  # ignored!
86
86
  else
87
- @log.debug "adding manifest #{migration_name} with ordinal #{ordinal}"
87
+ @log.debug "adding migration #{migration_name} with ordinal #{ordinal}"
88
88
  manifest.push(Migration.new(migration_name, ordinal, build_migration_path(manifest_path, migration_name)))
89
89
  ordinal += 1
90
90
  end
@@ -1,6 +1,6 @@
1
1
  module PgMigrate
2
2
  class Migration
3
- attr_accessor :name, :ordinal, :md5, :created, :production, :filepath
3
+ attr_accessor :name, :ordinal, :created, :production, :filepath
4
4
 
5
5
  def initialize(name, ordinal, filepath)
6
6
  @name = name
@@ -72,7 +72,7 @@ module PgMigrate
72
72
 
73
73
  statements = @sql_reader.load_migration(filepath)
74
74
  if statements.length == 0
75
- raise 'no statements found in migration #{migration_path}'
75
+ raise 'no statements found in migration #{filepath}'
76
76
  end
77
77
  run_migration(name, statements)
78
78
  end
@@ -86,7 +86,7 @@ module PgMigrate
86
86
  end
87
87
  rescue Exception => e
88
88
  # we make a special allowance for one exception; it just means this migration
89
- # has already occured, and we should just treat it like a continue
89
+ # has already occurred, and we should just treat it like a continue
90
90
  if e.message.index('pg_migrate: code=migration_exists').nil?
91
91
  conn.exec("ROLLBACK")
92
92
  raise e
@@ -0,0 +1,142 @@
1
+ require 'erb'
2
+ require 'fileutils'
3
+ require 'rubygems'
4
+ require 'rubygems/builder'
5
+ #require 'rubygems/package'
6
+
7
+ module PgMigrate
8
+ class Package
9
+
10
+ attr_accessor :manifest_reader
11
+
12
+ def initialize(manifest_reader)
13
+ @log = Logging.logger[self]
14
+ @manifest_reader = manifest_reader
15
+ @template_dir = File.join(File.dirname(__FILE__), 'package_templates')
16
+ end
17
+
18
+ def package(built_migration_path, output_dir, name, version, options={:force=>true})
19
+ gemspec = create_gem(built_migration_path, output_dir, name, version, options[:force])
20
+ build_gem(gemspec, output_dir)
21
+ end
22
+
23
+ def create_gem (built_migration_path, output_dir, name, version, force)
24
+ # validate that manifest is valid
25
+ @log.debug "validating output dir is manifest"
26
+
27
+ if !FileTest::exist?(built_migration_path)
28
+ raise "built manifest path does not exist #{built_migration_path}"
29
+ end
30
+
31
+ if built_migration_path == output_dir
32
+ raise "source and destination can not be the same path"
33
+ end
34
+
35
+ loaded_manifest = @manifest_reader.load_input_manifest(built_migration_path)
36
+ @manifest_reader.validate_migration_paths(built_migration_path, loaded_manifest)
37
+
38
+ @log.debug "preparing to build gem"
39
+
40
+ target = File.join(output_dir, name)
41
+
42
+ # stolen almost verbatim from bundler: https://github.com/carlhuda/bundler/blob/master/lib/bundler/cli.rb
43
+ constant_name = name.split('_').map { |p| p[0..0].upcase + p[1..-1] }.join
44
+ constant_name = constant_name.split('-').map { |q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
45
+ constant_array = constant_name.split('::')
46
+ # end stolen
47
+
48
+ author = "pgmigrate"
49
+ email = "pgmigrate@pgmigrate.io"
50
+ pg_migrate_version = PgMigrate::VERSION
51
+ gemfiles = ["Gemfile", "#{name}.gemspec", "lib/#{name}.rb", "lib/#{name}/version.rb", "bin/#{name}"]
52
+ gemfiles += userfiles(built_migration_path, name)
53
+ gemspec_path = File.join(output_dir, "#{name}.gemspec")
54
+
55
+ @log.debug "building gem"
56
+
57
+ output = Pathname.new(output_dir)
58
+ if !output.exist?
59
+ if !force
60
+ raise "Output directory '#{output_dir}' does not exist. Create it or specify force=true"
61
+ else
62
+ output.mkpath
63
+ end
64
+ else
65
+ # verify that it's is a directory
66
+ if !output.directory?
67
+ raise "output_dir #{output_dir} is a file; not a directory."
68
+ else
69
+ @log.debug("deleting & recreating existing output_dir #{output_dir}")
70
+ output.rmtree
71
+ output.mkpath
72
+ end
73
+ end
74
+
75
+ FileUtils.mkdir_p(output_dir)
76
+ FileUtils.mkdir_p(File.join(output_dir, "bin"))
77
+ FileUtils.mkdir_p(File.join(output_dir, "lib", name))
78
+ run_template("Gemfile.erb", binding, File.join(output_dir, "Gemfile"))
79
+ run_template("gemspec.erb", binding, gemspec_path)
80
+ run_template("lib/gem.rb", binding, File.join(output_dir, "lib", "#{name}.rb"))
81
+ run_template("lib/gem/version.rb", binding, File.join(output_dir, "lib", name, "version.rb"))
82
+ run_template("bin/migrate.rb", binding, File.join(output_dir, "bin", "#{name}"))
83
+ copy_schema(built_migration_path, File.join(output_dir, "lib", name, "schemas"))
84
+
85
+ return gemspec_path
86
+ end
87
+
88
+ def copy_schema(built_migration_path, output_dir)
89
+ FileUtils.cp_r(File.join(built_migration_path, '.'), output_dir)
90
+ end
91
+
92
+ def build_gem(gemspec_path, output_dir)
93
+ @log.debug "building gem"
94
+
95
+ @log.debug "loading gem specification #{gemspec_path}"
96
+ spec = Gem::Specification.load(gemspec_path)
97
+
98
+ if spec.nil?
99
+ raise 'unable to build gem from specification'
100
+ end
101
+
102
+ @log.debug "packaging gem"
103
+ Dir.chdir(output_dir) do
104
+ Gem::Builder.new(spec).build
105
+ end
106
+ #Gem::Package.build spec, false
107
+ end
108
+
109
+ def userfiles(built_migration_path, name)
110
+
111
+ gempaths = []
112
+ Find.find(built_migration_path) do |path|
113
+ if path == ".."
114
+ Find.prune
115
+ else
116
+ # make relative
117
+
118
+ relative = path[built_migration_path.length..-1]
119
+ gempath = File.join("lib", name, "schemas", relative)
120
+ gempaths.push(gempath)
121
+ end
122
+ end
123
+
124
+ return gempaths
125
+ end
126
+
127
+ # given an input template and binding, writes to an output file
128
+ def run_template(template, opt, output_filepath)
129
+ bootstrap_template = nil
130
+ File.open(File.join(@template_dir, template), 'r') do |reader|
131
+ bootstrap_template = reader.read
132
+ end
133
+
134
+
135
+ template = ERB.new(bootstrap_template, 0, "%<>")
136
+ content = template.result(opt)
137
+ File.open(output_filepath, 'w') do |writer|
138
+ writer.syswrite(content)
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg_migrate'
4
+ require '<%= name %>'
5
+
6
+ include PgMigrate
7
+
8
+ CommandLine.packaged_source = File.expand_path('../../lib/<%= name %>/schemas', __FILE__)
9
+
10
+ CommandLine.start
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/<%= name %>/version', __FILE__)
3
+ lib=File.expand_path('../lib', __FILE__)
4
+
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.authors = ["<%= author %>"]
8
+ gem.email = ["<%= email %> "]
9
+ gem.description = %q{A pg_migrate bundle for <%= name %>}
10
+ gem.summary = %q{A pg_migrate bundle built by pg_migrate, containing the schemas of <%= name %>)}
11
+ gem.homepage = "https://github.com/sethcall/pg_migrate"
12
+
13
+ gem.files = <%= gemfiles %>
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.name = "<%= name %>"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = <%= constant_name %>::VERSION
19
+
20
+ gem.add_dependency('pg_migrate', '<%= pg_migrate_version %>')
21
+ end
@@ -0,0 +1,3 @@
1
+ module <%= constant_name %>
2
+ VERSION = "<%= version %>"
3
+ end
@@ -0,0 +1,12 @@
1
+ require '<%= name %>/version'
2
+ require 'pg_migrate'
3
+
4
+ module <%= constant_name %>
5
+
6
+ class Migrator
7
+ def migrate options={}
8
+ pgMigrator = PgMigrate::Migrator.new(PgMigrate::ManifestReader.new, PgMigrate::SqlReader.new, options)
9
+ pgMigrator.migrate(File.expand_path('../<%= name %>/schemas', __FILE__))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ # from comment at http://devender.wordpress.com/2006/05/01/reading-and-writing-java-property-files-with-ruby/
2
+
3
+ module PgMigrate
4
+ class Properties < Hash
5
+ def initialize(filename = nil)
6
+ if (filename) then
7
+ File.open(filename).select { |line| not line=~/^[ \t]*(#.+)*$/ }.# ignore comments and blank lines
8
+ each { |line|
9
+ (k, v) = line.chomp.split('=', 2)
10
+ self[k.strip] = v.strip
11
+ }
12
+ end
13
+ end
14
+
15
+ def to_s
16
+ self.map { |k, v| " #{k}=#{v}" }.join("\n")
17
+ end
18
+ end
19
+ end
@@ -26,12 +26,13 @@ module PgMigrate
26
26
  current_statement += " " + line_stripped;
27
27
 
28
28
  if line_stripped.end_with?(";")
29
- if current_statement =~ /^\s*CREATE\s+(OR\s+REPLACE\s+)?FUNCTION/i
29
+ if current_statement =~ /^\s*CREATE\s+(OR\s+REPLACE\s+)?FUNCTION/i || current_statement =~ /^\s*DO\s+/i
30
30
  # if we are in a function, a ';' isn't enough to end. We need to see if the last word was one of
31
- # pltcl, plperl, plpgsql, plpythonu, sql.
31
+ # pltcl, plperl, plpgsql, plpythonu, sql
32
32
  # you can extend languages in postgresql; detecting these isn't supported yet.
33
33
 
34
- if current_statement =~ /(plpgsql|plperl|plpythonu|pltcl|sql)\s*;$/i
34
+ # we also detect anonymous functions (DO) and their ending sequence.
35
+ if current_statement =~ /(plpgsql|plperl|plpythonu|pltcl|sql)\s*;$/i || current_statement =~ /END\s*\$\$\s+(LANGUAGE\s+(plpgsql|plperl|plpythonu|pltcl|sql))?\s*;$/i
35
36
  statements.push(current_statement[0...-1]) # strip off last ;
36
37
  current_statement = ""
37
38
  end
@@ -9,35 +9,48 @@
9
9
 
10
10
  BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
11
11
 
12
- CREATE OR REPLACE FUNCTION bootstrap_pg_migrate() RETURNS void AS $$
12
+ -- bootstrap in the pgmigrate schema namespace, if it doesn't exist
13
+ DO $$DECLARE already_exists boolean;
14
+ BEGIN
15
+
16
+ SELECT exists INTO STRICT already_exists (select * from pg_catalog.pg_namespace where nspname = 'pgmigrate');
17
+
18
+ IF NOT already_exists THEN
19
+ create schema pgmigrate;
20
+ END IF;
21
+
22
+ END$$;
23
+
24
+
25
+ CREATE OR REPLACE FUNCTION pgmigrate.bootstrap_pg_migrate() RETURNS void AS $$
13
26
  DECLARE
14
27
  found_pg_migrate information_schema.tables;
15
28
  found_pg_migrations information_schema.tables;
16
29
 
17
30
  BEGIN
18
31
  BEGIN
19
- SELECT * INTO STRICT found_pg_migrate FROM information_schema.tables WHERE table_name = 'pg_migrate';
32
+ SELECT * INTO STRICT found_pg_migrate FROM information_schema.tables WHERE table_name = 'pg_migrate' and table_schema = 'pgmigrate';
20
33
 
21
34
  EXCEPTION
22
35
  WHEN NO_DATA_FOUND THEN
23
- CREATE TABLE pg_migrate (id BIGSERIAL PRIMARY KEY, template_version VARCHAR(255), builder_version VARCHAR(255), migrator_version VARCHAR(255), database_version VARCHAR(1024));
24
- CREATE INDEX pg_migrate_unique_index ON pg_migrate (template_version, builder_version, migrator_version, database_version);
36
+ CREATE TABLE pgmigrate.pg_migrate (id BIGSERIAL PRIMARY KEY, template_version VARCHAR(255), builder_version VARCHAR(255), migrator_version VARCHAR(255), database_version VARCHAR(1024));
37
+ CREATE INDEX pg_migrate_unique_index ON pgmigrate.pg_migrate (template_version, builder_version, migrator_version, database_version);
25
38
 
26
39
  WHEN TOO_MANY_ROWS THEN
27
40
  RAISE EXCEPTION 'Multiple pg_migrate tables. Unique key on information_schema.tables should have prevented this.';
28
41
  END;
29
42
 
30
43
  BEGIN
31
- SELECT * INTO STRICT found_pg_migrations FROM information_schema.tables WHERE table_name = 'pg_migrations';
44
+ SELECT * INTO STRICT found_pg_migrations FROM information_schema.tables WHERE table_name = 'pg_migrations' and table_schema = 'pgmigrate';
32
45
 
33
46
  EXCEPTION
34
47
  WHEN NO_DATA_FOUND THEN
35
- CREATE TABLE pg_migrations(
48
+ CREATE TABLE pgmigrate.pg_migrations(
36
49
  name VARCHAR(255) PRIMARY KEY,
37
50
  ordinal INTEGER NOT NULL,
38
51
  created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
39
52
  finalized SMALLINT DEFAULT 1,
40
- pg_migrate_id BIGINT NOT NULL REFERENCES pg_migrate(id));
53
+ pg_migrate_id BIGINT NOT NULL REFERENCES pgmigrate.pg_migrate(id));
41
54
  WHEN TOO_MANY_ROWS THEN
42
55
  RAISE EXCEPTION 'Multiple pg_migrations tables. Unique key on information_schema.tables should have prevented this.';
43
56
  END;
@@ -46,23 +59,23 @@ END;
46
59
  $$ LANGUAGE plpgsql;
47
60
 
48
61
 
49
- SELECT bootstrap_pg_migrate();
62
+ SELECT pgmigrate.bootstrap_pg_migrate();
50
63
 
51
64
  -- verifies that the specified migration name has the expected ordinal. No exception is thrown if no migration
52
65
  -- of this name exists, and no exception is thrown if the migration + ordinal pair is found on a single row.
53
66
  -- Only if the migrtion is found with the wrong row is an exception thrown.
54
- CREATE OR REPLACE FUNCTION verify_against_existing_migrations(migration varchar(255), ordinal integer) RETURNS VOID AS $$
67
+ CREATE OR REPLACE FUNCTION pgmigrate.verify_against_existing_migrations(migration varchar(255), ordinal integer) RETURNS VOID AS $$
55
68
  DECLARE
56
- found_migration pg_migrations;
69
+ found_migration pgmigrate.pg_migrations;
57
70
  BEGIN
58
71
  BEGIN
59
- EXECUTE 'SELECT * FROM pg_migrations WHERE name=$1' INTO STRICT found_migration USING migration;
72
+ EXECUTE 'SELECT * FROM pgmigrate.pg_migrations WHERE name=$1' INTO STRICT found_migration USING migration;
60
73
  EXCEPTION
61
74
  WHEN NO_DATA_FOUND THEN
62
75
  -- if no data, then this migration is unrun. One more check remains...
63
76
  -- if the last run migration's ordinal is 1 less than this one, we are ready to go.
64
- IF coalesce((SELECT MAX(p.ordinal) FROM pg_migrations as p), -1) <> ordinal - 1 THEN
65
- RAISE EXCEPTION 'pg_migrate: code=missing_migration, migration=%, ordinal=%, last_ordinal=%', migration, ordinal, (SELECT MAX(p.ordinal) FROM pg_migrations as p);
77
+ IF coalesce((SELECT MAX(p.ordinal) FROM pgmigrate.pg_migrations as p), -1) <> ordinal - 1 THEN
78
+ RAISE EXCEPTION 'pg_migrate: code=missing_migration, migration=%, ordinal=%, last_ordinal=%', migration, ordinal, (SELECT MAX(p.ordinal) FROM pgmigrate.pg_migrations as p);
66
79
  END IF;
67
80
 
68
81
  RETURN;
@@ -83,12 +96,12 @@ $$ LANGUAGE plpgsql;
83
96
  -- checks if the current script has been executed or not, and throws an exception if so
84
97
  -- callers should check for 'pg_migrate: code=migration_exists' to know whether they should quietly ignore exception.
85
98
  -- psql can only do this by calling \set ON_ERROR_STOP 1 (which is done by templates already)
86
- CREATE OR REPLACE FUNCTION bypass_existing_migration(migration varchar(255)) RETURNS VOID AS $$
99
+ CREATE OR REPLACE FUNCTION pgmigrate.bypass_existing_migration(migration varchar(255)) RETURNS VOID AS $$
87
100
  DECLARE
88
- found_migration pg_migrations;
101
+ found_migration pgmigrate.pg_migrations;
89
102
  BEGIN
90
103
  BEGIN
91
- EXECUTE 'SELECT * FROM pg_migrations WHERE name=$1' INTO STRICT found_migration USING migration ;
104
+ EXECUTE 'SELECT * FROM pgmigrate.pg_migrations WHERE name=$1' INTO STRICT found_migration USING migration ;
92
105
  EXCEPTION
93
106
  WHEN NO_DATA_FOUND THEN
94
107
  -- if no data, then success. just return with no exception thrown
@@ -103,8 +116,25 @@ END;
103
116
  $$ LANGUAGE plpgsql;
104
117
 
105
118
 
119
+ -- used to verify that the migration being applied is the same as this set or newer. While the parameter
120
+ -- today is called 'manifest_version', in reality this is just the highest ordinal from the manifest.
121
+ -- so if we find that the database has a higher ordinal than the manifest that built this migration,
122
+ -- then we can kick this out
123
+ CREATE OR REPLACE FUNCTION pgmigrate.verify_manifest_is_not_old(manifest_version INTEGER) RETURNS VOID AS $$
124
+ DECLARE
125
+ max_ordinal INTEGER;
126
+ BEGIN
127
+ EXECUTE 'SELECT max(ordinal) FROM pgmigrate.pg_migrations' INTO max_ordinal;
128
+
129
+ IF max_ordinal > manifest_version THEN
130
+ RAISE EXCEPTION 'pg_migrate: code=old_manifest, max_ordinal_in_db=%, manifest_version=%', max_ordinal, manifest_version;
131
+ END IF;
132
+ END;
133
+ $$ LANGUAGE plpgsql;
134
+
135
+
106
136
  -- used to mark a migration as finished
107
- CREATE OR REPLACE FUNCTION record_migration(migration varchar(255), ordinal INTEGER, template_version VARCHAR(255), builder_version VARCHAR(255)) RETURNS VOID AS $$
137
+ CREATE OR REPLACE FUNCTION pgmigrate.record_migration(migration varchar(255), ordinal INTEGER, template_version VARCHAR(255), builder_version VARCHAR(255)) RETURNS VOID AS $$
108
138
  DECLARE
109
139
  found_pg_migrate_id BIGINT;
110
140
  migrator_version VARCHAR(255);
@@ -116,7 +146,7 @@ BEGIN
116
146
  -- first look for existing pg_migrate row satisfying version columns
117
147
  -- but if not found, create that row
118
148
  -- in either case, found_pg_migrate_id will have the row id
119
- EXECUTE 'SELECT id FROM pg_migrate WHERE
149
+ EXECUTE 'SELECT id FROM pgmigrate.pg_migrate WHERE
120
150
  template_version=$1 and builder_version=$2 and migrator_version=$3 and database_version=$4'
121
151
  INTO found_pg_migrate_id USING template_version, builder_version, migrator_version, (select version());
122
152
  EXCEPTION
@@ -128,12 +158,12 @@ BEGIN
128
158
  END;
129
159
 
130
160
  IF found_pg_migrate_id IS NULL THEN
131
- INSERT INTO pg_migrate(id, template_version, builder_version, migrator_version, database_version)
161
+ INSERT INTO pgmigrate.pg_migrate(id, template_version, builder_version, migrator_version, database_version)
132
162
  VALUES (default, template_version, builder_version, migrator_version, (select version())) RETURNING id INTO found_pg_migrate_id;
133
163
  END IF;
134
164
 
135
165
  -- create a new record in pg_migrations table, ensuring this migration won't be run again
136
- EXECUTE 'INSERT INTO pg_migrations(name, ordinal, created, finalized, pg_migrate_id)
166
+ EXECUTE 'INSERT INTO pgmigrate.pg_migrations(name, ordinal, created, finalized, pg_migrate_id)
137
167
  VALUES ($1, $2, CURRENT_TIMESTAMP, 1, $3)' USING migration, ordinal, found_pg_migrate_id;
138
168
 
139
169
  END;
@@ -4,14 +4,16 @@
4
4
  BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
5
5
 
6
6
  -- we want to ensure no one else is running this migration concurrently
7
- LOCK TABLE pg_migrations IN ACCESS EXCLUSIVE MODE;
7
+ LOCK TABLE pgmigrate.pg_migrations IN ACCESS EXCLUSIVE MODE;
8
8
 
9
- SELECT verify_against_existing_migrations('<%= migration_def.name %>', <%= migration_def.ordinal %>);
9
+ SELECT pgmigrate.verify_manifest_is_not_old(<%= manifest_version %>);
10
+
11
+ SELECT pgmigrate.verify_against_existing_migrations('<%= migration_def.name %>', <%= migration_def.ordinal %>);
10
12
 
11
13
  -- to allow exception in CHECK_IF_MIGRATED to cause rollback, not failure
12
14
  \set ON_ERROR_STOP 0
13
15
 
14
- SELECT bypass_existing_migration('<%= migration_def.name %>');
16
+ SELECT pgmigrate.bypass_existing_migration('<%= migration_def.name %>');
15
17
 
16
18
  -- if the content of the migration is bad, we want psql to stop.
17
19
  \set ON_ERROR_STOP 1
@@ -22,7 +24,7 @@ SELECT bypass_existing_migration('<%= migration_def.name %>');
22
24
 
23
25
  -- beginning pg_migrate footer, migration=<%= migration_def.name %>
24
26
 
25
- SELECT record_migration('<%= migration_def.name %>', <%= migration_def.ordinal %>, '0.0.1', '<%= builder_version %>');
27
+ SELECT pgmigrate.record_migration('<%= migration_def.name %>', <%= migration_def.ordinal %>, '0.1.0', '<%= builder_version %>');
26
28
 
27
29
  COMMIT;
28
30
  -- end pg_migrate migration, migration=<%= migration_def.name %>
@@ -1,3 +1,3 @@
1
1
  module PgMigrate
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/pg_migrate.rb CHANGED
@@ -2,12 +2,14 @@ require 'logging'
2
2
  require 'pg'
3
3
  require 'thor'
4
4
  require "pg_migrate/version"
5
+ require "pg_migrate/props"
5
6
  require "pg_migrate/migration"
6
7
  require "pg_migrate/sql_reader"
7
8
  require "pg_migrate/manifest_reader"
8
9
  require "pg_migrate/migrator"
9
10
  require "pg_migrate/config_parser"
10
11
  require "pg_migrate/builder"
12
+ require "pg_migrate/package"
11
13
  require "pg_migrate/command_line"
12
14
 
13
15
  # name of the manifest file
@@ -21,7 +23,9 @@ TESTDIRNAME = 'test'
21
23
  # name of the bootstrap.sql file
22
24
  BOOTSTRAP_FILENAME = "bootstrap.sql"
23
25
  # built manifest version header
24
- BUILDER_VERSION_HEADER="# pg_migrate-"
26
+ BUILDER_VERSION_HEADER ="# pg_migrate-"
27
+ # name of project configuration defaults
28
+ PG_CONFIG ='.pg_migrate'
25
29
 
26
30
 
27
31
  ### SQL CONSTANTS ###
data/pg_migrate.gemspec CHANGED
@@ -12,7 +12,6 @@ Gem::Specification.new do |gem|
12
12
 
13
13
  gem.files = `git ls-files`.split($\)
14
14
  gem.files += `cd #{lib}/pg_migrate/templates; git ls-files *.erb`.split($\).map {|f| "lib/pg_migrate/templates/#{f}"}
15
- puts gem.files
16
15
  gem.files.delete("lib/pg_migrate/templates")
17
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
@@ -24,5 +23,6 @@ Gem::Specification.new do |gem|
24
23
 
25
24
  gem.add_dependency('pg', '0.14.0')
26
25
  gem.add_dependency('thor', '0.15.4')
26
+ #gem.add_dependency('rubygems', '1.8.24')
27
27
  end
28
28
 
@@ -71,6 +71,8 @@ describe Builder do
71
71
 
72
72
  output_dir = File.join('target', 'output_single_manifest')
73
73
 
74
+ FileUtils.rm_rf(output_dir)
75
+
74
76
  @standard_builder.build(input_dir, output_dir)
75
77
 
76
78
  @dbutil.create_new_test_database()
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe CommandLine do
4
+
5
+ before(:all) do
6
+ @dbutil = DbUtility.new
7
+ end
8
+
9
+
10
+ it "build using config file" do
11
+
12
+ single_manifest=File.expand_path('spec/pg_migrate/input_manifests/single_manifest')
13
+ single_manifest=File.join(single_manifest, '.')
14
+
15
+ input_dir = nil
16
+ target = Files.create :path => "target", :timestamp => false do
17
+ input_dir = dir "input_single_manifest", :src => single_manifest do
18
+
19
+ end
20
+ end
21
+
22
+ output_dir = File.join("target", 'output_single_manifest')
23
+
24
+ FileUtils.rm_rf(output_dir)
25
+
26
+ # make a properties file on the fly, with the out parameter specified
27
+ props = Properties.new
28
+ props['build.out'] = output_dir
29
+ props['build.force'] = "true"
30
+ #props['up.connopts'] = "dbname:pg_migrate_test host:localhost port:5432 user:postgres password:postgres"
31
+
32
+ # and put that properties file in the input dir
33
+ File.open(File.join(input_dir, PG_CONFIG), 'w') { |f| f.write(props) }
34
+
35
+ # invoke pg_migrate build, with the hopes that the output dir is honored
36
+ result = `bundle exec pg_migrate build -s #{input_dir}`
37
+
38
+ puts "pg_migrate build output: #{result}"
39
+
40
+ $?.exitstatus.should == 0
41
+
42
+ FileTest::exist?(output_dir).should == true
43
+ FileTest::exist?(File.join(output_dir, MANIFEST_FILENAME)).should == true
44
+ FileTest::exist?(File.join(output_dir, PG_CONFIG)).should == true
45
+ FileTest::exist?(File.join(output_dir, UP_DIRNAME)).should == true
46
+ FileTest::exist?(File.join(output_dir, UP_DIRNAME, BOOTSTRAP_FILENAME)).should == true
47
+ FileTest::exist?(File.join(output_dir, UP_DIRNAME, "single1.sql")).should == true
48
+
49
+
50
+ end
51
+
52
+
53
+ end
@@ -25,7 +25,7 @@ describe Migrator do
25
25
  end
26
26
 
27
27
  pg_migration_id = nil
28
- transaction.exec("SELECT * FROM pg_migrations") do |result|
28
+ transaction.exec("SELECT * FROM pgmigrate.pg_migrations") do |result|
29
29
  result.ntuples.should == 1
30
30
  result[0]["name"].should == "single1.sql"
31
31
  result[0]["ordinal"].should == "0"
@@ -34,9 +34,9 @@ describe Migrator do
34
34
  pg_migration_id.should_not == nil
35
35
 
36
36
  # verify that a database row in pg_migrate was created as side-effect
37
- transaction.exec("SELECT * FROM pg_migrate WHERE id = $1", [pg_migration_id]) do |result|
37
+ transaction.exec("SELECT * FROM pgmigrate.pg_migrate WHERE id = $1", [pg_migration_id]) do |result|
38
38
  result.ntuples.should == 1
39
- result[0]["template_version"].should == "0.0.1"
39
+ result[0]["template_version"].should == "0.1.0"
40
40
  result[0]["builder_version"].should == "pg_migrate_ruby-#{PgMigrate::VERSION}"
41
41
  result[0]["migrator_version"].should == "pg_migrate_ruby-#{PgMigrate::VERSION}"
42
42
  result[0]["database_version"].should_not be nil
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Package do
4
+
5
+ before(:all) do
6
+ @manifest_reader = ManifestReader.new
7
+ @sql_reader = SqlReader.new
8
+ @builder = Builder.new(@manifest_reader, @sql_reader)
9
+ @packager = Package.new(@manifest_reader)
10
+ @dbutil = DbUtility.new
11
+ end
12
+
13
+ it "package single migration project" do
14
+ single_manifest=File.expand_path('spec/pg_migrate/input_manifests/single_manifest')
15
+ single_manifest = File.join(single_manifest, '.')
16
+
17
+ input_dir = nil
18
+ target = Files.create :path => "target", :timestamp => false do
19
+ input_dir = dir "input_single_manifest", :src => single_manifest do
20
+
21
+ end
22
+ end
23
+
24
+ build_output_dir = File.join('target', 'output_single_manifest')
25
+ package_output_dir = File.join('target', 'package_single_manifest')
26
+
27
+ FileUtils.rm_rf(build_output_dir)
28
+
29
+
30
+ # build first
31
+ @builder.build(input_dir, build_output_dir)
32
+
33
+ # then attempt a package
34
+ @packager.package(build_output_dir, package_output_dir, "crazy_gem", "0.0.1")
35
+
36
+ end
37
+
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_migrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-19 00:00:00.000000000 Z
12
+ date: 2012-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: logging
@@ -82,17 +82,26 @@ files:
82
82
  - lib/pg_migrate/manifest_reader.rb
83
83
  - lib/pg_migrate/migration.rb
84
84
  - lib/pg_migrate/migrator.rb
85
+ - lib/pg_migrate/package.rb
86
+ - lib/pg_migrate/package_templates/Gemfile.erb
87
+ - lib/pg_migrate/package_templates/bin/migrate.rb
88
+ - lib/pg_migrate/package_templates/gemspec.erb
89
+ - lib/pg_migrate/package_templates/lib/gem.rb
90
+ - lib/pg_migrate/package_templates/lib/gem/version.rb
91
+ - lib/pg_migrate/props.rb
85
92
  - lib/pg_migrate/sql_reader.rb
86
93
  - lib/pg_migrate/version.rb
87
94
  - pg_migrate.gemspec
88
95
  - spec/database.yml
89
96
  - spec/pg_migrate/builder_spec.rb
97
+ - spec/pg_migrate/command_line_spec.rb
90
98
  - spec/pg_migrate/config_parser_spec.rb
91
99
  - spec/pg_migrate/db_utility.rb
92
100
  - spec/pg_migrate/input_manifests/single_manifest/manifest
93
101
  - spec/pg_migrate/input_manifests/single_manifest/up/single1.sql
94
102
  - spec/pg_migrate/manifest_reader_spec.rb
95
103
  - spec/pg_migrate/migrator_spec.rb
104
+ - spec/pg_migrate/package_spec.rb
96
105
  - spec/pg_migrate/sql_reader_spec.rb
97
106
  - spec/spec_helper.rb
98
107
  - lib/pg_migrate/templates/bootstrap.erb
@@ -126,11 +135,13 @@ summary: Create migration scripts in raw SQL that work regardless if they are ru
126
135
  test_files:
127
136
  - spec/database.yml
128
137
  - spec/pg_migrate/builder_spec.rb
138
+ - spec/pg_migrate/command_line_spec.rb
129
139
  - spec/pg_migrate/config_parser_spec.rb
130
140
  - spec/pg_migrate/db_utility.rb
131
141
  - spec/pg_migrate/input_manifests/single_manifest/manifest
132
142
  - spec/pg_migrate/input_manifests/single_manifest/up/single1.sql
133
143
  - spec/pg_migrate/manifest_reader_spec.rb
134
144
  - spec/pg_migrate/migrator_spec.rb
145
+ - spec/pg_migrate/package_spec.rb
135
146
  - spec/pg_migrate/sql_reader_spec.rb
136
147
  - spec/spec_helper.rb