prick 0.19.0 → 0.20.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -6
- data/README.md +7 -7
- data/Rakefile +3 -1
- data/TODO +13 -11
- data/bin/console +2 -1
- data/doc/build-yml.txt +14 -0
- data/exe/prick +237 -19
- data/lib/builder/batch.rb +147 -0
- data/lib/builder/builder.rb +122 -0
- data/lib/builder/node.rb +189 -0
- data/lib/builder/node_pool.rb +105 -0
- data/lib/builder/parser.rb +120 -0
- data/lib/local/command.rb +193 -0
- data/lib/{prick → local}/git.rb +148 -22
- data/lib/local/timer.rb +98 -0
- data/lib/prick/constants.rb +54 -66
- data/lib/prick/diff.rb +28 -18
- data/lib/prick/prick_version.rb +161 -0
- data/lib/prick/state.rb +80 -165
- data/lib/prick/version.rb +2 -163
- data/lib/prick.rb +38 -24
- data/lib/share/init/.gitignore +10 -0
- data/lib/share/init/.prick-context +2 -0
- data/lib/share/init/.rspec +3 -0
- data/{share/schema/schema/public → lib/share/init/migration}/.keep +0 -0
- data/lib/share/init/prick.yml +6 -0
- data/lib/share/init/schema/.keep +0 -0
- data/lib/share/init/schema/build.yml +2 -0
- data/lib/share/init/schema/prick/.keep +0 -0
- data/lib/share/init/schema/prick/build.yml +5 -0
- data/lib/share/init/schema/prick/data.sql +6 -0
- data/{share/schema → lib/share/init}/schema/prick/tables.sql +2 -3
- data/lib/share/init/schema/public/.keep +0 -0
- data/lib/share/init/spec/prick_helper.rb +1 -0
- data/lib/share/init/spec/prick_spec.rb +6 -0
- data/lib/share/init/spec/spec_helper.rb +50 -0
- data/lib/share/migrate/migration/build.yml +4 -0
- data/lib/share/migrate/migration/diff.after-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.before-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.tables.sql +0 -0
- data/lib/subcommand/prick-build.rb +55 -0
- data/lib/subcommand/prick-create.rb +78 -0
- data/lib/subcommand/prick-drop.rb +25 -0
- data/lib/subcommand/prick-fox.rb +62 -0
- data/lib/subcommand/prick-init.rb +46 -0
- data/lib/subcommand/prick-make.rb +202 -0
- data/lib/subcommand/prick-migrate.rb +37 -0
- data/lib/subcommand/prick-release.rb +23 -0
- data/lib/subcommand/prick-setup.rb +20 -0
- data/lib/subcommand/prick-teardown.rb +18 -0
- data/prick.gemspec +23 -31
- metadata +69 -78
- data/.gitignore +0 -29
- data/.travis.yml +0 -7
- data/doc/create_release.txt +0 -17
- data/doc/flow.txt +0 -98
- data/doc/migra +0 -1
- data/doc/migrations.txt +0 -172
- data/doc/notes.txt +0 -116
- data/doc/prick.txt +0 -114
- data/doc/sh.prick +0 -316
- data/lib/ext/algorithm.rb +0 -14
- data/lib/ext/fileutils.rb +0 -26
- data/lib/ext/forward_method.rb +0 -18
- data/lib/ext/pg.rb +0 -18
- data/lib/ext/shortest_path.rb +0 -44
- data/lib/prick/archive.rb +0 -124
- data/lib/prick/branch.rb +0 -265
- data/lib/prick/builder.rb +0 -246
- data/lib/prick/cache.rb +0 -34
- data/lib/prick/command.rb +0 -104
- data/lib/prick/database.rb +0 -82
- data/lib/prick/dsort.rb +0 -151
- data/lib/prick/ensure.rb +0 -119
- data/lib/prick/exceptions.rb +0 -25
- data/lib/prick/head.rb +0 -189
- data/lib/prick/migration.rb +0 -70
- data/lib/prick/program.rb +0 -287
- data/lib/prick/project.rb +0 -626
- data/lib/prick/rdbms.rb +0 -137
- data/lib/prick/schema.rb +0 -27
- data/lib/prick/share.rb +0 -64
- data/libexec/strip-comments +0 -33
- data/make_releases +0 -72
- data/make_schema +0 -10
- data/share/diff/diff.after-tables.sql +0 -4
- data/share/diff/diff.before-tables.sql +0 -4
- data/share/diff/diff.tables.sql +0 -8
- data/share/features/diff.sql +0 -2
- data/share/features/feature/diff.sql +0 -2
- data/share/features/feature/migrate.sql +0 -2
- data/share/features/features.sql +0 -2
- data/share/features/features.yml +0 -2
- data/share/features/migrations.sql +0 -4
- data/share/gitignore +0 -2
- data/share/migration/diff.tables.sql +0 -8
- data/share/migration/features.yml +0 -6
- data/share/migration/migrate.sql +0 -3
- data/share/migration/migrate.yml +0 -8
- data/share/migration/tables.sql +0 -3
- data/share/schema/build.yml +0 -14
- data/share/schema/schema/build.yml +0 -3
- data/share/schema/schema/prick/build.yml +0 -14
- data/share/schema/schema/prick/data.sql +0 -7
- data/share/schema/schema/prick/schema.sql +0 -3
- data/share/schema/schema/public/build.yml +0 -13
- data/share/schema/schema.sql +0 -3
- data/test_assorted +0 -192
- data/test_feature +0 -112
- data/test_refactor +0 -34
- data/test_single_dev +0 -83
data/lib/prick/database.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
|
2
|
-
module Prick
|
3
|
-
class Database
|
4
|
-
attr_reader :name
|
5
|
-
attr_reader :user
|
6
|
-
|
7
|
-
def initialize(name, user)
|
8
|
-
name != "" or raise "Illegal database name"
|
9
|
-
@name = name
|
10
|
-
@user = user
|
11
|
-
@version = nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def version(cache: true)
|
15
|
-
if cache && @version
|
16
|
-
@version
|
17
|
-
else
|
18
|
-
@version = begin
|
19
|
-
version =
|
20
|
-
if exist? && Rdbms.exist_table?(name, "prick", "versions")
|
21
|
-
Rdbms.select(name, "select version from prick.versions")&.first&.first
|
22
|
-
else
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
version && Version.new(version)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def version=(version)
|
31
|
-
@version = version && Version.new(version)
|
32
|
-
Rdbms.exec_sql(name, %(
|
33
|
-
update prick.versions
|
34
|
-
set major = '#{@version.major}',
|
35
|
-
minor = '#{@version.minor}',
|
36
|
-
patch = '#{@version.patch}',
|
37
|
-
pre = '#{@version.pre}',
|
38
|
-
version = '#{@version.to_s}'
|
39
|
-
)) if @version
|
40
|
-
@version
|
41
|
-
end
|
42
|
-
|
43
|
-
def exist?() Rdbms.exist_database?(name) end
|
44
|
-
def create() Rdbms.create_database(name, owner: user) end
|
45
|
-
def recreate() drop if exist?; create; @version = nil end
|
46
|
-
def drop() Rdbms.drop_database(name, fail: false); @version = nil end
|
47
|
-
|
48
|
-
def loaded?() !version.nil? end
|
49
|
-
|
50
|
-
def load(file)
|
51
|
-
!loaded? or raise Internal, "Database #{name} is already loaded"
|
52
|
-
Rdbms.load(name, file, user: user)
|
53
|
-
version # Provoke load of version
|
54
|
-
end
|
55
|
-
|
56
|
-
def save(file)
|
57
|
-
loaded? or raise Internal, "Database #{name} is not loaded"
|
58
|
-
Rdbms.save(name, file)
|
59
|
-
@version = nil
|
60
|
-
end
|
61
|
-
|
62
|
-
# Hollow-out a database without dropping it. This is useful compared to a
|
63
|
-
# simple drop database since it wont block on other sessions wont block
|
64
|
-
def clean()
|
65
|
-
if exist?
|
66
|
-
schemas = Rdbms.select_values(
|
67
|
-
name,
|
68
|
-
"select nspname from pg_namespace where nspowner != 10 and nspname != 'prick'")
|
69
|
-
for schema in schemas
|
70
|
-
Rdbms.exec_sql(name, "drop schema \"#{schema}\" cascade")
|
71
|
-
end
|
72
|
-
Rdbms.exec_sql(name, "drop schema if exists public cascade")
|
73
|
-
Rdbms.exec_sql(name, "create schema public authorization postgres")
|
74
|
-
Rdbms.exec_sql(name, "grant usage, create on schema public to public")
|
75
|
-
else
|
76
|
-
create
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def to_s() name end
|
81
|
-
end
|
82
|
-
end
|
data/lib/prick/dsort.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
require 'tsort'
|
2
|
-
|
3
|
-
module DSort
|
4
|
-
# Thrown if a cyclic dependency is detected
|
5
|
-
#
|
6
|
-
# DSort::Cyclic is inherited from TSort::Cyclic so that recue handling code
|
7
|
-
# written for TSort will still work. It provides a #cycles member that lists
|
8
|
-
# the cycles
|
9
|
-
class Cyclic < TSort::Cyclic
|
10
|
-
# List of detected cycles sorted from shortest to longest cycle
|
11
|
-
attr_reader :cycles
|
12
|
-
|
13
|
-
def initialize(dsort_object)
|
14
|
-
@cycles =
|
15
|
-
dsort_object.each_strongly_connected_component \
|
16
|
-
.select { |e| e.size > 1 } \
|
17
|
-
.sort { |l,r| r <=> l }
|
18
|
-
gram = cycles.size > 1 ? "ies" : "y"
|
19
|
-
super("Cyclic depedendenc#{gram} detected")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# dsort sorts its input in "dependency" order: The input can be thought of
|
24
|
-
# depends-on relations between objects and the output as sorted in the order
|
25
|
-
# needed to safisfy those dependencies so that no object comes before an
|
26
|
-
# object it depends on
|
27
|
-
#
|
28
|
-
# dsort can take an array or a hash argument, or be supplied with a block
|
29
|
-
#
|
30
|
-
# The Array argument should consist of pairs (two-element Arrays) with the
|
31
|
-
# first element being the depending object and the second an object or an
|
32
|
-
# array of objects it depends on: For example [:a, :b] means that :a depends
|
33
|
-
# on :b, and [:b, [:c, :d]] that :b depends on both :c and :d
|
34
|
-
#
|
35
|
-
# The Hash argument should be a hash from depending object to an object or
|
36
|
-
# array of objects it depends on. If h is a Hash then dsort(h) is equivalent
|
37
|
-
# to dsort(h.to_a)
|
38
|
-
#
|
39
|
-
# Note that if the elements are arrays themselves, then you should use the
|
40
|
-
# array form to list the dependencies even if there is only one dependency.
|
41
|
-
# Ie. use [:a, [:b]] or {:a => [:b] } instead of [:a, :b] or {:a => :b}
|
42
|
-
#
|
43
|
-
# If dsort is given a block, the block is given an element as argument and
|
44
|
-
# should return an (possibly empty) array of the objects the argument depends
|
45
|
-
# on. The argument to dsort should be an element or an array of elements to
|
46
|
-
# be given to the block. Note that if the elements are arrays themselves,
|
47
|
-
# then the arguments to dsort should use the array form even if there is only
|
48
|
-
# one element. Ie. Use dsort([:a]) instead of dsort(:a)
|
49
|
-
#
|
50
|
-
# dsort raise a DSort::Cyclic exception if a cycle detected
|
51
|
-
#
|
52
|
-
# Example: If we have that dsort depends on ruby and rspec, ruby depends
|
53
|
-
# on C to compile, and rspec depends on ruby, then in what order should we
|
54
|
-
# build them ? Using dsort we could do
|
55
|
-
#
|
56
|
-
# p dsort [[:dsort, [:ruby, :rspec]]], [:ruby, :C], [:rspec, :ruby]]
|
57
|
-
# => [:C, :ruby, :rspec, :dsort]
|
58
|
-
#
|
59
|
-
# Using a hash
|
60
|
-
#
|
61
|
-
# h = {
|
62
|
-
# :dsort => [:ruby, :rspec],
|
63
|
-
# :ruby => [:C],
|
64
|
-
# :rspec => [:ruby]
|
65
|
-
# }
|
66
|
-
# p dsort(h) # Same as dsort(h.to_a)
|
67
|
-
# => [:C, :ruby, :rspec, :dsort]
|
68
|
-
#
|
69
|
-
# or using a block
|
70
|
-
#
|
71
|
-
# p dsort(:dsort) { |e| h[e] }
|
72
|
-
# => [:C, :ruby, :rspec, :dsort]
|
73
|
-
#
|
74
|
-
def dsort(a, &block)
|
75
|
-
sort_object = DSortPrivate::DSortObject.new(a, &block)
|
76
|
-
begin
|
77
|
-
sort_object.tsort
|
78
|
-
rescue TSort::Cyclic
|
79
|
-
raise Cyclic.new(sort_object)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# tsort sort its input in topological order: The input can be thought of as
|
84
|
-
# comes-before relations between objects and the output will be in
|
85
|
-
# first-to-last order. This definition corresponds to the mathemacial
|
86
|
-
# defitionnn of topological sort. See
|
87
|
-
# http://en.wikipedia.org/wiki/Topological_sorting
|
88
|
-
#
|
89
|
-
# Arguments are the same as for dsort. tsort is equivalent to
|
90
|
-
# dsort(...).reverse
|
91
|
-
#
|
92
|
-
# tsort raise a DSort::Cyclic exception if a cycle is detected (DSort::Cyclic
|
93
|
-
# is an alias for TSort::Cyclic)
|
94
|
-
#
|
95
|
-
def tsort(a, &block) dsort(a, &block).reverse end
|
96
|
-
|
97
|
-
module_function :dsort, :tsort
|
98
|
-
|
99
|
-
module DSortPrivate
|
100
|
-
class DSortObject
|
101
|
-
include TSort
|
102
|
-
|
103
|
-
# Hash from element to array of dependencies
|
104
|
-
attr_reader :deps
|
105
|
-
|
106
|
-
# Create @deps hash from object to list of dependencies
|
107
|
-
def initialize(a, &block)
|
108
|
-
@deps = {}
|
109
|
-
if block_given?
|
110
|
-
a = [a] if !a.is_a?(Array)
|
111
|
-
a.each { |elem| find_dependencies(elem, &block) }
|
112
|
-
else
|
113
|
-
a.each { |obj, deps|
|
114
|
-
(@deps[obj] ||= []).concat(deps.is_a?(Array) ? deps : [deps])
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
# Make sure all dependent objects are also represented as depending
|
119
|
-
# objects: If we're given [:a, :b] we want the @deps hash to include
|
120
|
-
# both :a and :b as keys
|
121
|
-
@deps.values.each { |deps|
|
122
|
-
(deps.is_a?(Array) ? deps : [deps]).each { |d|
|
123
|
-
@deps[d] = [] if !@deps.key?(d)
|
124
|
-
}
|
125
|
-
}
|
126
|
-
end
|
127
|
-
|
128
|
-
# TSort virtual methods
|
129
|
-
def tsort_each_node(&block) @deps.each_key(&block) end
|
130
|
-
def tsort_each_child(node, &block) @deps[node].each(&block) end
|
131
|
-
|
132
|
-
private
|
133
|
-
def find_dependencies(a, &block)
|
134
|
-
block.call(a).each { |d|
|
135
|
-
(@deps[a] ||= []) << d
|
136
|
-
find_dependencies(d, &block)
|
137
|
-
}
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
data/lib/prick/ensure.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
module Prick
|
2
|
-
# Example:
|
3
|
-
#
|
4
|
-
# class Some
|
5
|
-
# include Ensure
|
6
|
-
#
|
7
|
-
# def exist?() ... end
|
8
|
-
# def create() ... end
|
9
|
-
# def destroy() ... end
|
10
|
-
#
|
11
|
-
# def loaded?() ... end
|
12
|
-
# def load() ... end
|
13
|
-
# def unload() ... end
|
14
|
-
#
|
15
|
-
# @ensure_states = {
|
16
|
-
# exist: [:create, :destroy],
|
17
|
-
# loaded: [:exist, :load, :unload] # Depends on :exist
|
18
|
-
# }
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# some = Some.new
|
22
|
-
# some.ensure_state(:loaded) # -> calls #create and then #load
|
23
|
-
# some.revoke_state(:loaded) # -> calls #unload but not #destroy
|
24
|
-
# some.ensure_state_value(:exist, false) # same as #revoke_state(:exist)
|
25
|
-
#
|
26
|
-
module Ensure
|
27
|
-
def ensure_state(state, *args) ensure_state_value(state, true, *args) end
|
28
|
-
def revoke_state(state, *args) ensure_state_value(state, false, *args) end
|
29
|
-
def ensure_state_value(state, value, *args) EnsureMethods.ensure(self, state, value, *args) end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Helper module
|
33
|
-
module EnsureMethods
|
34
|
-
def self.klass(module_or_object)
|
35
|
-
module_or_object.is_a?(Module) ? module_or_object : module_or_object.class
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.all_included(m)
|
39
|
-
m.singleton_class.included_modules
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.all_extended(c)
|
43
|
-
c.ancestors
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.all_states(c)
|
47
|
-
h = {}
|
48
|
-
(all_extended(c) + all_included(c)).reverse.each { |klass|
|
49
|
-
h.merge!(klass.instance_variable_get("@ensure_states") || {})
|
50
|
-
}
|
51
|
-
h
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.ensure(module_or_object, state, expected, *args)
|
55
|
-
# module_or_object_text = module_or_object.is_a?(Module) ? "<module>" : "<object>"
|
56
|
-
# puts "ensure_state_impl(#{module_or_object_text.inspect}, #{state.inspect}, #{expected}, #{args.inspect})"
|
57
|
-
|
58
|
-
object = module_or_object
|
59
|
-
klass = self.klass(module_or_object)
|
60
|
-
value = call_method(object, :"#{state}?", *args)
|
61
|
-
|
62
|
-
if value != expected
|
63
|
-
entry = all_states(klass)[state] or
|
64
|
-
raise Prick::Error, "Can't find state #{state.inspect}"
|
65
|
-
|
66
|
-
# Handle ensure-pre-conditions recursively
|
67
|
-
precondition = (entry.size == 3 ? entry.shift : nil)
|
68
|
-
entry.size == 2 or raise "Malformed state entry for #{state.inspect}"
|
69
|
-
if precondition && expected # Don't tear down recursively
|
70
|
-
case precondition
|
71
|
-
when Symbol
|
72
|
-
self.ensure(object, precondition, true, *args)
|
73
|
-
when Proc
|
74
|
-
call_method(object, precondition, *args)
|
75
|
-
else
|
76
|
-
raise Prick::Fail, "Unexpected value: #{precondition.inspect}"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
method = entry[expected ? 0 : 1]
|
81
|
-
case method
|
82
|
-
when true # a noop
|
83
|
-
;
|
84
|
-
when false # an error
|
85
|
-
relation = (expected ? "to" : "from")
|
86
|
-
raise Error, "Can't change state #{relation} #{state.inspect}"
|
87
|
-
when Symbol # a method
|
88
|
-
call_method(object, method, *args)
|
89
|
-
when Proc # a lambda
|
90
|
-
call_method(object, method, *args)
|
91
|
-
else
|
92
|
-
raise Error, "Illegal @states entry: #{method.inspect}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
self # so that you can do 'some = Some.new.ensure_state(:loaded)' in one go
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.vargs(arity, args)
|
99
|
-
n_args = (arity < 0 ? -(1 + arity) : arity)
|
100
|
-
args[0...n_args]
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.call_method(object, symbol_or_lambda, *args)
|
104
|
-
# sol_text = symbol_or_lambda.is_a?(Proc) ? "<Proc>" : symbol_or_lambda
|
105
|
-
# puts "call_method(#{object.name}, #{sol_text.inspect}, #{args})"
|
106
|
-
|
107
|
-
if symbol_or_lambda.is_a?(Symbol)
|
108
|
-
executor = object.method(symbol_or_lambda)
|
109
|
-
executor.call(*vargs(executor.arity, args))
|
110
|
-
elsif symbol_or_lambda.is_a?(Proc)
|
111
|
-
executor = symbol_or_lambda
|
112
|
-
executor.call(object, *vargs(executor.arity, args))
|
113
|
-
else
|
114
|
-
raise Prick::Fail, "Illegal value: #{symbol_or_lambda.inspect}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
data/lib/prick/exceptions.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
|
2
|
-
module Prick
|
3
|
-
class Error < RuntimeError; end
|
4
|
-
class Fail < Error; end
|
5
|
-
|
6
|
-
class NotYet < NotImplementedError
|
7
|
-
def initialize() super("Internal error: Not yet implemented") end
|
8
|
-
end
|
9
|
-
|
10
|
-
class NotThis < ScriptError
|
11
|
-
def initialize() super("Internal error: Abstract method called") end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Abstract < ScriptError
|
15
|
-
def initialize() super("Internal error: Abstract method called") end
|
16
|
-
end
|
17
|
-
|
18
|
-
AbstractMethod = Abstract
|
19
|
-
|
20
|
-
class Internal < ScriptError; end
|
21
|
-
class Oops < Internal
|
22
|
-
def initialize() super("Oops, this shouldn't happen") end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
data/lib/prick/head.rb
DELETED
@@ -1,189 +0,0 @@
|
|
1
|
-
|
2
|
-
module Prick
|
3
|
-
class Head
|
4
|
-
def project_name() Prick.project.name end
|
5
|
-
|
6
|
-
# Usually equal to #version.to_s
|
7
|
-
attr_reader :name
|
8
|
-
|
9
|
-
# Version. This should be equal to schema.version
|
10
|
-
attr_reader :version
|
11
|
-
|
12
|
-
def base_version() @migration.base_version end
|
13
|
-
|
14
|
-
attr_reader :schema
|
15
|
-
|
16
|
-
attr_reader :migration
|
17
|
-
|
18
|
-
def clean?() Git::clean? end
|
19
|
-
|
20
|
-
def tag?() false end
|
21
|
-
def release_tag?() false end
|
22
|
-
def migration_tag?() false end
|
23
|
-
|
24
|
-
def branch?() false end
|
25
|
-
def release_branch?() false end
|
26
|
-
def prerelease_branch?() false end
|
27
|
-
def feature_branch?() false end
|
28
|
-
def migration_branch?() false end
|
29
|
-
|
30
|
-
def initialize(name, version, migration)
|
31
|
-
@name = name
|
32
|
-
@version = version
|
33
|
-
@schema = Schema.new
|
34
|
-
@migration = migration
|
35
|
-
end
|
36
|
-
|
37
|
-
# TODO: Handle migrations
|
38
|
-
def self.load(name)
|
39
|
-
version, tag = Version.parse(name)
|
40
|
-
if tag
|
41
|
-
ReleaseTag.load
|
42
|
-
else
|
43
|
-
if version.release?
|
44
|
-
ReleaseBranch.load
|
45
|
-
elsif version.prerelease?
|
46
|
-
PrereleaseBranch.load(version)
|
47
|
-
elsif version.feature?
|
48
|
-
FeatureBranch.load(version)
|
49
|
-
else
|
50
|
-
raise NotHere
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def create()
|
56
|
-
raise NotThis
|
57
|
-
end
|
58
|
-
|
59
|
-
def build(database)
|
60
|
-
schema.build(database)
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.database_name(version)
|
64
|
-
version.truncate(:pre).to_s
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class Tag < Head
|
69
|
-
def tag?() true end
|
70
|
-
|
71
|
-
def initialize(version, base_version, migration = nil)
|
72
|
-
migration ||= Migration.new(version, base_version)
|
73
|
-
super(version.to_s, version, migration)
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.load
|
77
|
-
state = Migration.load
|
78
|
-
self.new(state.version, state.base_version)
|
79
|
-
end
|
80
|
-
|
81
|
-
def create
|
82
|
-
initial_branch_name = "#{version}_initial"
|
83
|
-
clean? or raise Internal, "Repository is not clean"
|
84
|
-
!Git.detached? or raise Internal, "Not on a branch"
|
85
|
-
Git.create_branch(initial_branch_name)
|
86
|
-
Git.checkout_branch(initial_branch_name)
|
87
|
-
migration.update(version)
|
88
|
-
schema.version = version
|
89
|
-
Git.commit "Created release v#{version}"
|
90
|
-
Git.create_tag(version)
|
91
|
-
Git.checkout_tag(version)
|
92
|
-
self
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
class ReleaseTag < Tag
|
97
|
-
def release_tag?() true end
|
98
|
-
end
|
99
|
-
|
100
|
-
# TODO
|
101
|
-
class PrereleaseTag < Tag
|
102
|
-
end
|
103
|
-
|
104
|
-
class MigrationTag < Tag
|
105
|
-
def migration_tag?() true end
|
106
|
-
end
|
107
|
-
|
108
|
-
class Branch < Head
|
109
|
-
def branch?() true end
|
110
|
-
|
111
|
-
def initialize(name, version, migration)
|
112
|
-
super(name, version, migration)
|
113
|
-
end
|
114
|
-
|
115
|
-
def create()
|
116
|
-
Git.create_branch(version)
|
117
|
-
Git.checkout_branch(version)
|
118
|
-
migration.create
|
119
|
-
self
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
class UserBranch < Branch
|
124
|
-
def initialize(name)
|
125
|
-
super(nil, nil, nil)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
class ReleaseBranch < Branch
|
130
|
-
def release_branch?() true end
|
131
|
-
|
132
|
-
def initialize(fork = nil, base_version)
|
133
|
-
if fork
|
134
|
-
version = Version.new(base_version, fork: fork)
|
135
|
-
else
|
136
|
-
version = base_version
|
137
|
-
end
|
138
|
-
super(version.to_s, version, Migration.new(nil, base_version))
|
139
|
-
end
|
140
|
-
|
141
|
-
def self.load
|
142
|
-
state = MigrationState.load
|
143
|
-
ReleaseBranch.new(nil, state.base_version)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
class PrereleaseBranch < Branch
|
148
|
-
def prerelease_branch?() true end
|
149
|
-
|
150
|
-
def initialize(version, base_version)
|
151
|
-
target_version = version.truncate(:pre)
|
152
|
-
super(version.to_s, target_version, Migration.new(target_version, base_version))
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.load
|
156
|
-
state = MigrationState.load
|
157
|
-
PrereleaseBranch.new(state.version, state.base_version)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
class FeatureBranch < Branch
|
162
|
-
def feature_branch?() true end
|
163
|
-
|
164
|
-
def initialize(feature_name, base_version)
|
165
|
-
name = Version.new(base_version, feature: feature_name).to_s
|
166
|
-
super(name, base_version, FeatureMigration.new(feature_name, base_version))
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.load
|
170
|
-
state = MigrationState.load
|
171
|
-
FeatureBranch.new(state.version.feature)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# TODO: Versioned migrations (or maybe not)
|
176
|
-
class MigrationBranch < Branch
|
177
|
-
def migrationn_branch?() true end
|
178
|
-
|
179
|
-
def initialize(version, base_version)
|
180
|
-
if (version.fork || "") == (base_version.fork || "")
|
181
|
-
name = version.to_s + "-" + base_version.semver.to_s
|
182
|
-
else
|
183
|
-
name = version.to_s + "-" + base_version.to_s
|
184
|
-
end
|
185
|
-
super(name, version, Migration.new(version, base_version))
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
data/lib/prick/migration.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
|
2
|
-
module Prick
|
3
|
-
class Migration
|
4
|
-
attr_reader :version
|
5
|
-
attr_reader :base_version
|
6
|
-
|
7
|
-
def initialize(version, base_version)
|
8
|
-
@version = version
|
9
|
-
@base_version = base_version
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.load
|
13
|
-
state = MigrationState.load
|
14
|
-
Migration.new(state.version, state.base_version)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Remove content of the migration/ directory
|
18
|
-
def self.clear
|
19
|
-
FileUtils.empty!(MIGRATION_DIR)
|
20
|
-
end
|
21
|
-
|
22
|
-
def exist?() MigrationState.exist? end
|
23
|
-
|
24
|
-
def create()
|
25
|
-
files = Share.cp "migration/*", MIGRATION_DIR
|
26
|
-
state = MigrationState.new.write(version: version, base_version: base_version)
|
27
|
-
Git.add files, state.path
|
28
|
-
self
|
29
|
-
end
|
30
|
-
|
31
|
-
def update(version)
|
32
|
-
state = MigrationState.new.read
|
33
|
-
@version = state.version = version
|
34
|
-
state.write
|
35
|
-
Git.add state.path
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
def migrate(database)
|
40
|
-
base_version or raise Internal, "Can't migrate from nil to #{version}"
|
41
|
-
version or raise Internal, "Can't migrate from #{base_version} to nil"
|
42
|
-
MigrationBuilder.new(database, MIGRATION_DIR).build
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class FeatureMigration < Migration
|
47
|
-
attr_reader :feature
|
48
|
-
|
49
|
-
def initialize(feature, base_version)
|
50
|
-
super(base_version, base_version)
|
51
|
-
@feature = feature
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.load
|
55
|
-
migration_state = MigrationState.load
|
56
|
-
feature_state = FeatureState.load
|
57
|
-
FeatureMigration.new(feature_state.feature, migration_state.base_version)
|
58
|
-
end
|
59
|
-
|
60
|
-
def create()
|
61
|
-
super
|
62
|
-
files = Share.cp "migration", File.join(MIGRATION_DIR, feature)
|
63
|
-
state = FeatureState.write(feature: feature)
|
64
|
-
Git.add files, state.path
|
65
|
-
self
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
|