prick 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/TODO +7 -0
- data/exe/prick +95 -33
- data/lib/ext/fileutils.rb +7 -0
- data/lib/prick.rb +5 -3
- data/lib/prick/builder.rb +31 -8
- data/lib/prick/cache.rb +34 -0
- data/lib/prick/constants.rb +106 -54
- data/lib/prick/database.rb +26 -18
- data/lib/prick/diff.rb +103 -25
- data/lib/prick/git.rb +31 -9
- data/lib/prick/head.rb +183 -0
- data/lib/prick/migration.rb +41 -181
- data/lib/prick/program.rb +199 -0
- data/lib/prick/project.rb +277 -0
- data/lib/prick/rdbms.rb +2 -1
- data/lib/prick/schema.rb +5 -10
- data/lib/prick/state.rb +129 -74
- data/lib/prick/version.rb +41 -28
- data/share/diff/diff.after-tables.sql +4 -0
- data/share/diff/diff.before-tables.sql +4 -0
- data/share/diff/diff.tables.sql +8 -0
- data/share/migration/diff.tables.sql +8 -0
- data/share/{release_migration → migration}/features.yml +0 -0
- data/share/migration/migrate.sql +3 -0
- data/share/{release_migration → migration}/migrate.yml +3 -0
- data/share/migration/tables.sql +3 -0
- data/share/{schemas → schema/schema}/build.yml +0 -0
- data/share/{schemas → schema/schema}/prick/build.yml +0 -0
- data/share/schema/schema/prick/data.sql +7 -0
- data/share/{schemas → schema/schema}/prick/schema.sql +0 -0
- data/share/{schemas → schema/schema}/prick/tables.sql +2 -2
- data/share/{schemas → schema/schema}/public/.keep +0 -0
- data/share/{schemas → schema/schema}/public/build.yml +0 -0
- data/share/{schemas → schema/schema}/public/schema.sql +0 -0
- data/test_refactor +34 -0
- metadata +22 -20
- data/file +0 -0
- data/lib/prick/build.rb +0 -376
- data/lib/prick/migra.rb +0 -22
- data/share/feature_migration/diff.sql +0 -2
- data/share/feature_migration/migrate.sql +0 -2
- data/share/release_migration/diff.sql +0 -3
- data/share/release_migration/migrate.sql +0 -5
- data/share/schemas/prick/data.sql +0 -7
data/lib/prick/version.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# Required by gem
|
6
6
|
module Prick
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.5.0"
|
8
8
|
end
|
9
9
|
|
10
10
|
# Project related code starts here
|
@@ -21,9 +21,12 @@ module Prick
|
|
21
21
|
def zero?() self == Version.zero end
|
22
22
|
|
23
23
|
# Return true if `string` is a version
|
24
|
-
def self.version?(string)
|
24
|
+
def self.version?(string)
|
25
|
+
string.is_a?(String) or raise Internal, "String expected"
|
26
|
+
!(string =~ VERSION_RE).nil?
|
27
|
+
end
|
25
28
|
|
26
|
-
attr_accessor :
|
29
|
+
attr_accessor :fork
|
27
30
|
attr_accessor :semver
|
28
31
|
attr_accessor :feature
|
29
32
|
|
@@ -36,8 +39,8 @@ module Prick
|
|
36
39
|
def patch() @semver.patch end
|
37
40
|
def patch=(patch) @semver.patch = patch end
|
38
41
|
|
39
|
-
# Return true if this is a
|
40
|
-
def
|
42
|
+
# Return true if this is a fork release
|
43
|
+
def fork?() !@fork.nil? end
|
41
44
|
|
42
45
|
# Return true if this is a feature release
|
43
46
|
def feature?() !@feature.nil? end
|
@@ -47,13 +50,16 @@ module Prick
|
|
47
50
|
|
48
51
|
# Return true if this is a pre-release
|
49
52
|
def pre?() !@semver.pre.nil? end
|
53
|
+
def prerelease?() pre? end
|
50
54
|
|
51
55
|
# The releases is stored as a String (eg. 'pre.1') in the semantic version
|
52
56
|
# but #pre returns only the Integer number
|
53
57
|
def pre() @semver.pre =~ PRE_RE ? $1.to_i : nil end
|
58
|
+
def prerelease() pre end
|
54
59
|
|
55
60
|
# #pre= expects an integer or nil argument
|
56
61
|
def pre=(pre) @semver.pre = (pre ? "#{PRE_LABEL}.#{pre}" : nil) end
|
62
|
+
def prerelease=(pre) self.pre = pre end
|
57
63
|
|
58
64
|
def dup() Version.new(self) end
|
59
65
|
def clone() Version.new(self) end
|
@@ -61,19 +67,19 @@ module Prick
|
|
61
67
|
def eql?(other) self == other end
|
62
68
|
def hash() @semver.hash end
|
63
69
|
|
64
|
-
def initialize(version,
|
70
|
+
def initialize(version, fork: nil, feature: nil)
|
65
71
|
case version
|
66
72
|
when String
|
67
73
|
version =~ VERSION_RE or raise Version::FormatError, "Expected a version, got #{version.inspect}"
|
68
|
-
@
|
69
|
-
@semver = Semantic::Version.new($
|
70
|
-
@feature = feature || $
|
74
|
+
@fork = fork || $1
|
75
|
+
@semver = Semantic::Version.new($3)
|
76
|
+
@feature = feature || $4
|
71
77
|
when Semantic::Version
|
72
|
-
@
|
78
|
+
@fork = fork
|
73
79
|
@semver = version.dup
|
74
80
|
@feature = feature
|
75
81
|
when Version
|
76
|
-
@
|
82
|
+
@fork = fork || version.fork
|
77
83
|
@semver = version.semver.dup
|
78
84
|
@feature = feature || version.feature
|
79
85
|
else
|
@@ -83,9 +89,17 @@ module Prick
|
|
83
89
|
|
84
90
|
# Try converting the string `version` into a Version object. Return nil if unsuccessful
|
85
91
|
def self.try(version)
|
86
|
-
version?(version) ? new(version) : nil
|
92
|
+
version.is_a?(Version) ? version : (version?(version) ? new(version) : nil)
|
87
93
|
end
|
88
94
|
|
95
|
+
# Parse a branch or tag name into a Version object. Return a [version, tag]
|
96
|
+
# tuple where tag is true if name was a tag
|
97
|
+
def self.parse(name)
|
98
|
+
name =~ VERSION_RE or raise Version::FormatError, "Expected a version, got #{version.inspect}"
|
99
|
+
fork, tag, semver, feature = $1, $2, $3, $4
|
100
|
+
version = Version.new(semver, fork: fork, feature: feature)
|
101
|
+
[version, tag]
|
102
|
+
end
|
89
103
|
# `part` can be one of :major, :minor, :patch, or :pre. If pre is undefined, it
|
90
104
|
# is set to `pre_initial_value`
|
91
105
|
def increment(part, pre_initial_value = 1)
|
@@ -117,20 +131,18 @@ module Prick
|
|
117
131
|
end
|
118
132
|
end
|
119
133
|
|
120
|
-
|
134
|
+
# def path
|
135
|
+
# parts = [FEATURE_DIR, truncate(:pre), feature].compact
|
136
|
+
# File.join(*parts)
|
137
|
+
# end
|
121
138
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
def link
|
128
|
-
!feature? or raise Internal, "Version #{to_s} is a feature, not a release"
|
129
|
-
File.join(RELEASE_DIR, to_s)
|
130
|
-
end
|
139
|
+
# def link
|
140
|
+
# !feature? or raise Internal, "Version #{to_s} is a feature, not a release"
|
141
|
+
# File.join(RELEASE_DIR, to_s)
|
142
|
+
# end
|
131
143
|
|
132
144
|
def <=>(other)
|
133
|
-
r = (
|
145
|
+
r = (fork || "") <=> (other.fork || "")
|
134
146
|
return r if r != 0
|
135
147
|
r = semver <=> other.semver
|
136
148
|
return r if r != 0
|
@@ -138,16 +150,17 @@ module Prick
|
|
138
150
|
return r
|
139
151
|
end
|
140
152
|
|
141
|
-
# Render as
|
142
|
-
def to_s
|
143
|
-
(
|
153
|
+
# Render as branch
|
154
|
+
def to_s(tag: false)
|
155
|
+
(fork ? "#{fork}-" : "") + (tag ? "v" : "") + semver.to_s + (feature ? "_#{feature}" : "")
|
144
156
|
end
|
145
157
|
|
158
|
+
# Render as a tag
|
159
|
+
def to_tag() to_s(tag: true) end
|
160
|
+
|
146
161
|
# Render as string
|
147
162
|
def inspect() to_s end
|
148
163
|
end
|
149
|
-
|
150
|
-
# ZERO = Version.new("0.0.0")
|
151
164
|
end
|
152
165
|
|
153
166
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
-- Generated by prick(1) via migra(1). Please don't touch.
|
2
|
+
--
|
3
|
+
-- This file contains changes that can touch existing data in the database that
|
4
|
+
-- needs speciel treatment in the migrate.sql
|
5
|
+
--
|
6
|
+
-- Note that this file is not executed by prick by default and that it is not
|
7
|
+
-- added to the Git repo when it changes. You have to do that manually
|
8
|
+
--
|
@@ -0,0 +1,8 @@
|
|
1
|
+
-- Generated by prick(1) via migra(1). Please don't touch.
|
2
|
+
--
|
3
|
+
-- This file contains changes that can touch existing data in the database that
|
4
|
+
-- needs speciel treatment in the migrate.sql
|
5
|
+
--
|
6
|
+
-- Note that this file is not executed by prick by default and that it is not
|
7
|
+
-- added to the Git repo when it changes. You have to do that manually
|
8
|
+
--
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -6,11 +6,11 @@ set search_path to prick;
|
|
6
6
|
|
7
7
|
create table versions (
|
8
8
|
id integer generated by default as identity primary key,
|
9
|
-
|
9
|
+
fork varchar,
|
10
10
|
major integer not null,
|
11
11
|
minor integer not null,
|
12
12
|
patch integer not null,
|
13
|
-
pre
|
13
|
+
pre integer,
|
14
14
|
feature varchar,
|
15
15
|
version varchar not null
|
16
16
|
);
|
File without changes
|
File without changes
|
File without changes
|
data/test_refactor
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/bash
|
2
|
+
|
3
|
+
function add_table() {
|
4
|
+
local name=$1
|
5
|
+
echo "Creating table $name"
|
6
|
+
echo "create table $name (id integer);" >>schema/public/tables.sql
|
7
|
+
git add schema/public/tables.sql
|
8
|
+
git commit -m "Added table $name" >/dev/null
|
9
|
+
}
|
10
|
+
|
11
|
+
function add_migration() {
|
12
|
+
echo "Creating migration"
|
13
|
+
cp schema/public/tables.sql migration/diff.sql
|
14
|
+
echo '\i diff.sql' >migration/migrate.sql
|
15
|
+
git commit -am "Added migration"
|
16
|
+
}
|
17
|
+
|
18
|
+
set -e
|
19
|
+
clear
|
20
|
+
|
21
|
+
if [ -d dir ]; then
|
22
|
+
find dir -type f -delete
|
23
|
+
else
|
24
|
+
mkdir dir
|
25
|
+
fi
|
26
|
+
|
27
|
+
cd dir
|
28
|
+
prick --name prj init "."
|
29
|
+
|
30
|
+
prick prepare release
|
31
|
+
add_table a
|
32
|
+
add_migration
|
33
|
+
prick create release 0.1.0
|
34
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shellopts
|
@@ -78,7 +78,6 @@ files:
|
|
78
78
|
- doc/prick.txt
|
79
79
|
- doc/sh.prick
|
80
80
|
- exe/prick
|
81
|
-
- file
|
82
81
|
- lib/ext/algorithm.rb
|
83
82
|
- lib/ext/fileutils.rb
|
84
83
|
- lib/ext/forward_method.rb
|
@@ -87,8 +86,8 @@ files:
|
|
87
86
|
- lib/prick.rb
|
88
87
|
- lib/prick/archive.rb
|
89
88
|
- lib/prick/branch.rb
|
90
|
-
- lib/prick/build.rb
|
91
89
|
- lib/prick/builder.rb
|
90
|
+
- lib/prick/cache.rb
|
92
91
|
- lib/prick/command.rb
|
93
92
|
- lib/prick/constants.rb
|
94
93
|
- lib/prick/database.rb
|
@@ -97,7 +96,7 @@ files:
|
|
97
96
|
- lib/prick/ensure.rb
|
98
97
|
- lib/prick/exceptions.rb
|
99
98
|
- lib/prick/git.rb
|
100
|
-
- lib/prick/
|
99
|
+
- lib/prick/head.rb
|
101
100
|
- lib/prick/migration.rb
|
102
101
|
- lib/prick/program.rb
|
103
102
|
- lib/prick/project.rb
|
@@ -110,8 +109,9 @@ files:
|
|
110
109
|
- make_releases
|
111
110
|
- make_schema
|
112
111
|
- prick.gemspec
|
113
|
-
- share/
|
114
|
-
- share/
|
112
|
+
- share/diff/diff.after-tables.sql
|
113
|
+
- share/diff/diff.before-tables.sql
|
114
|
+
- share/diff/diff.tables.sql
|
115
115
|
- share/features/diff.sql
|
116
116
|
- share/features/feature/diff.sql
|
117
117
|
- share/features/feature/migrate.sql
|
@@ -119,22 +119,24 @@ files:
|
|
119
119
|
- share/features/features.yml
|
120
120
|
- share/features/migrations.sql
|
121
121
|
- share/gitignore
|
122
|
-
- share/
|
123
|
-
- share/
|
124
|
-
- share/
|
125
|
-
- share/
|
122
|
+
- share/migration/diff.tables.sql
|
123
|
+
- share/migration/features.yml
|
124
|
+
- share/migration/migrate.sql
|
125
|
+
- share/migration/migrate.yml
|
126
|
+
- share/migration/tables.sql
|
126
127
|
- share/schema/build.yml
|
127
128
|
- share/schema/schema.sql
|
128
|
-
- share/
|
129
|
-
- share/
|
130
|
-
- share/
|
131
|
-
- share/
|
132
|
-
- share/
|
133
|
-
- share/
|
134
|
-
- share/
|
135
|
-
- share/
|
129
|
+
- share/schema/schema/build.yml
|
130
|
+
- share/schema/schema/prick/build.yml
|
131
|
+
- share/schema/schema/prick/data.sql
|
132
|
+
- share/schema/schema/prick/schema.sql
|
133
|
+
- share/schema/schema/prick/tables.sql
|
134
|
+
- share/schema/schema/public/.keep
|
135
|
+
- share/schema/schema/public/build.yml
|
136
|
+
- share/schema/schema/public/schema.sql
|
136
137
|
- test_assorted
|
137
138
|
- test_feature
|
139
|
+
- test_refactor
|
138
140
|
- test_single_dev
|
139
141
|
homepage: http://www.nowhere.com/
|
140
142
|
licenses: []
|
@@ -154,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
156
|
- !ruby/object:Gem::Version
|
155
157
|
version: '0'
|
156
158
|
requirements: []
|
157
|
-
rubygems_version: 3.1.
|
159
|
+
rubygems_version: 3.1.2
|
158
160
|
signing_key:
|
159
161
|
specification_version: 4
|
160
162
|
summary: A release control and management system for postgresql
|
data/file
DELETED
File without changes
|
data/lib/prick/build.rb
DELETED
@@ -1,376 +0,0 @@
|
|
1
|
-
|
2
|
-
require "prick/ensure.rb"
|
3
|
-
require "prick/dsort.rb"
|
4
|
-
require "ext/fileutils.rb" # for ::touch_p
|
5
|
-
|
6
|
-
module Prick
|
7
|
-
class Build
|
8
|
-
include Ensure
|
9
|
-
|
10
|
-
# The associated project object
|
11
|
-
attr_reader :project
|
12
|
-
|
13
|
-
# Version
|
14
|
-
attr_reader :version
|
15
|
-
|
16
|
-
# Build name. Same as `version.to_s`
|
17
|
-
def name() version.to_s end
|
18
|
-
|
19
|
-
# Associated database object
|
20
|
-
attr_reader :database
|
21
|
-
|
22
|
-
# Schema object. Only defined when the build has been checked out
|
23
|
-
attr_reader :schema
|
24
|
-
|
25
|
-
# Migration object. Running the migration on a base release database will
|
26
|
-
# mutate it into the current release
|
27
|
-
attr_reader :migration
|
28
|
-
|
29
|
-
# Path to a filesystem node that represents the build on disk. Used to
|
30
|
-
# detect if a build is present in the current release's tree. It is
|
31
|
-
# possible to infer the base release from the node - either by a naming
|
32
|
-
# convention or by reading the file. Build::deref_node_file does that
|
33
|
-
def node() raise AbstractMethod end
|
34
|
-
|
35
|
-
# Base release. Returns nil if version is 0.0.0. Raises an exception if
|
36
|
-
# branch is not represented on disk and it can't be inferred from the
|
37
|
-
# version (only features)
|
38
|
-
def base_release()
|
39
|
-
return nil if version.zero?
|
40
|
-
@base_release.present? or raise Internal, "Release #{name} is not present"
|
41
|
-
@base_release
|
42
|
-
end
|
43
|
-
|
44
|
-
# List of features in this build. This requires the build to be present on disk
|
45
|
-
def features()
|
46
|
-
present? or raise "Build #{name} is not present"
|
47
|
-
version.zero? ? [] : migration.feature_versions.map { |version| project[version] }
|
48
|
-
end
|
49
|
-
|
50
|
-
# Return the build's history as a hash from release to list of features
|
51
|
-
def history()
|
52
|
-
h = {}
|
53
|
-
Algorithm.follow(self, :base_release).each { |release|
|
54
|
-
h[release] = []
|
55
|
-
indent {
|
56
|
-
release.features.each { |feature| h[release] << feature }
|
57
|
-
}
|
58
|
-
}
|
59
|
-
h
|
60
|
-
end
|
61
|
-
|
62
|
-
def initialize(project, base_release, version, migration, database: nil, schema: nil)
|
63
|
-
base_release.nil? || base_release.is_a?(Release) or
|
64
|
-
raise Internal, "Expected a Release object, got #{base_release.class}"
|
65
|
-
version.is_a?(Version) or raise Internal, "Expected a Version object, got #{version.class}"
|
66
|
-
@project = project
|
67
|
-
@base_release = base_release
|
68
|
-
@version = version
|
69
|
-
@migration = migration
|
70
|
-
@schema = Schema.new(project)
|
71
|
-
@database = database || Database.new("#{project.name}-#{name}", project.user)
|
72
|
-
project[name] = self
|
73
|
-
end
|
74
|
-
|
75
|
-
# Return true if the build exists as a branch in git
|
76
|
-
def exist?() Git.branch?(name) end
|
77
|
-
|
78
|
-
# Create and checkout the branch
|
79
|
-
def create()
|
80
|
-
!present? or raise Fail, "Build #{name} is already present on disk"
|
81
|
-
!exist? or raise Fail, "Build #{name} is already present in git"
|
82
|
-
Git.create_branch(name)
|
83
|
-
Git.checkout_branch(name)
|
84
|
-
end
|
85
|
-
|
86
|
-
# FIXME: Kills the current branch under the feets of the application. Also doesn't update
|
87
|
-
# internal structures in Project
|
88
|
-
def destroy()
|
89
|
-
project.release != self or raise Error, "Can't destroy current branch - #{self.version}"
|
90
|
-
Git.delete_branch(name)
|
91
|
-
end
|
92
|
-
|
93
|
-
# True if the release is present in this git branch
|
94
|
-
def present?() File.exist?(node) end
|
95
|
-
|
96
|
-
# True if the release is the active branch
|
97
|
-
def active?() Git.current_branch == name end
|
98
|
-
|
99
|
-
def checkout()
|
100
|
-
Git.checkout(name)
|
101
|
-
end
|
102
|
-
|
103
|
-
def checkback() # Doubtfull - creates strange results on Release and Prerelease branches
|
104
|
-
base_release.checkout
|
105
|
-
end
|
106
|
-
|
107
|
-
def built?()
|
108
|
-
active? && @schema.built?(@database)
|
109
|
-
end
|
110
|
-
|
111
|
-
def build()
|
112
|
-
active? or raise Error, "Can't build: Not active"
|
113
|
-
@schema.build(@database)
|
114
|
-
end
|
115
|
-
|
116
|
-
def rebuild()
|
117
|
-
active? or raise Error, "Can't rebuild: Not active"
|
118
|
-
@database.recreate
|
119
|
-
build
|
120
|
-
end
|
121
|
-
|
122
|
-
def include_feature(feature)
|
123
|
-
migration.include_feature(feature.migration)
|
124
|
-
end
|
125
|
-
|
126
|
-
def remove_feature(feature)
|
127
|
-
raise NotYet
|
128
|
-
end
|
129
|
-
|
130
|
-
# Create a copy of the project in tmp/ and checkout the branch. Used to build
|
131
|
-
# releases. Returns the path to the copy
|
132
|
-
def snapshot() end
|
133
|
-
|
134
|
-
# Sorting
|
135
|
-
def <=>(other) version <=> other.version end
|
136
|
-
|
137
|
-
# Use #name for String conversion
|
138
|
-
def to_s() name end
|
139
|
-
|
140
|
-
# Reads the name of the base release from a node (see Build#node)
|
141
|
-
def self.deref_node_file(node)
|
142
|
-
if File.basename(node) == "0.0.0"
|
143
|
-
nil
|
144
|
-
elsif File.symlink?(node) # Releases and prereleases
|
145
|
-
symlink = Command.command("readlink -v #{node}").first
|
146
|
-
value = File.basename(symlink.sub(/\/$/, ""))
|
147
|
-
value == "/dev/null" ? nil : value
|
148
|
-
elsif File.directory?(node) # Migrations
|
149
|
-
name = File.basename(node)
|
150
|
-
name =~ MIGRATION_RE or raise "Illegal migration name: #{name}"
|
151
|
-
$1
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
@states = {
|
157
|
-
exist: [:create, :destroy],
|
158
|
-
initialized: [:exist, :initialize, false], # ???
|
159
|
-
active: [:exist, :checkout, :checkback],
|
160
|
-
# built: [:active, :build, lambda { |this| this.database.recreate } ],
|
161
|
-
}
|
162
|
-
end
|
163
|
-
|
164
|
-
class AbstractRelease < Build
|
165
|
-
# Tag
|
166
|
-
def tag() [version.custom, "v#{version.semver}"].compact.join("-") end
|
167
|
-
|
168
|
-
# Cache object
|
169
|
-
attr_reader :archive
|
170
|
-
|
171
|
-
# Redefine Build#node
|
172
|
-
attr_reader :node
|
173
|
-
|
174
|
-
# The directory representing this release. It is initially empty. It is the
|
175
|
-
# same as the next release's migration directory and contains features that
|
176
|
-
# require this release
|
177
|
-
def release_dir() raise AbstractMethod end
|
178
|
-
|
179
|
-
def initialize(project, base_release, version, migration, **opts)
|
180
|
-
super
|
181
|
-
@node = File.join(RELEASE_DIR, name)
|
182
|
-
@archive = DumpFile.new(project, version.to_s)
|
183
|
-
end
|
184
|
-
|
185
|
-
def cached?() archive.exist? end
|
186
|
-
def cache() database.save(archive.path) end
|
187
|
-
def uncache() FileUtils.rm_f(archive.path) end
|
188
|
-
|
189
|
-
def loaded?() schema.loaded?(database) end
|
190
|
-
def load() database.ensure(:loaded, archive.file) end
|
191
|
-
def unload() database.ensure(:loaded, expect: false) end
|
192
|
-
|
193
|
-
def prepare(commit: true)
|
194
|
-
migration.prepare
|
195
|
-
Git.commit("Prepared next release") if commit
|
196
|
-
end
|
197
|
-
|
198
|
-
def <=>(other) version <=> other.version end
|
199
|
-
|
200
|
-
# Create the release in Git and on the disk
|
201
|
-
def create(create_release_link_file: true)
|
202
|
-
super()
|
203
|
-
|
204
|
-
# Create release link file (eg. releases/0.1.0)
|
205
|
-
if create_release_link_file
|
206
|
-
base_release_dir = (version.zero? ? "/dev/null" : "../#{migration.path}")
|
207
|
-
Dir.chdir(RELEASE_DIR) {
|
208
|
-
FileUtils.ln_s(base_release_dir, File.basename(node))
|
209
|
-
}
|
210
|
-
Git.add(node)
|
211
|
-
end
|
212
|
-
|
213
|
-
# Set schema version
|
214
|
-
project.schema.version = version
|
215
|
-
Git.add(project.schema.path)
|
216
|
-
end
|
217
|
-
|
218
|
-
def dump
|
219
|
-
return self
|
220
|
-
$stderr.puts "#{self.class} #{version}"
|
221
|
-
$stderr.indent { |f|
|
222
|
-
f.puts "node : #{node.inspect}"
|
223
|
-
f.puts "base_release: #{base_release&.version.inspect}"
|
224
|
-
f.puts "migration : #{migration&.path.inspect}"
|
225
|
-
f.puts "release_dir : #{release_dir.inspect}"
|
226
|
-
}
|
227
|
-
self
|
228
|
-
end
|
229
|
-
|
230
|
-
private
|
231
|
-
@ensure_states = {
|
232
|
-
# cached: [:built, :cache, :uncache],
|
233
|
-
loaded: [:cached, :load, :unload]
|
234
|
-
}
|
235
|
-
end
|
236
|
-
|
237
|
-
class Release < AbstractRelease
|
238
|
-
def release_dir() File.join(FEATURE_DIR, name) end
|
239
|
-
|
240
|
-
def initialize(project, base_release, version)
|
241
|
-
migration = base_release && ReleaseMigration.new(base_release.release_dir)
|
242
|
-
super(project, base_release, version, migration)
|
243
|
-
end
|
244
|
-
|
245
|
-
# Create the release in Git and on the disk. We assume that the migration exists
|
246
|
-
def create
|
247
|
-
super
|
248
|
-
|
249
|
-
# Create migration link file
|
250
|
-
if !version.zero?
|
251
|
-
migration_version = "#{base_release.version}_#{version}"
|
252
|
-
features = "../#{migration.path}"
|
253
|
-
Dir.chdir(MIGRATION_DIR) {
|
254
|
-
FileUtils.ln_s(features, migration_version)
|
255
|
-
Git.add(migration_version)
|
256
|
-
}
|
257
|
-
end
|
258
|
-
|
259
|
-
# Create new empty feature directory
|
260
|
-
ReleaseMigration.new(release_dir).create
|
261
|
-
|
262
|
-
Git.commit("Release #{version}")
|
263
|
-
Git.create_tag(version)
|
264
|
-
dump
|
265
|
-
migration.dump if migration
|
266
|
-
self
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
# TODO: Rename to PreRelease
|
271
|
-
class Prerelease < AbstractRelease
|
272
|
-
attr_reader :target_release
|
273
|
-
|
274
|
-
def release_dir() base_release.release_dir end
|
275
|
-
|
276
|
-
def initialize(project, base_release, version, target_version = version.truncate(:pre))
|
277
|
-
@target_release = Release.new(project, base_release, target_version)
|
278
|
-
migration = ReleaseMigration.new(target_release.migration.path)
|
279
|
-
super(project, base_release, version, migration)
|
280
|
-
end
|
281
|
-
|
282
|
-
# Create the pre-release in Git and on disk
|
283
|
-
def create
|
284
|
-
super
|
285
|
-
migration.prepare
|
286
|
-
Git.commit("Pre-release #{version}")
|
287
|
-
dump
|
288
|
-
self
|
289
|
-
end
|
290
|
-
|
291
|
-
# Create a migration for this release
|
292
|
-
def prepare_migration
|
293
|
-
base_release.built? or raise "Base release #{base_release} is not built"
|
294
|
-
puts "Prerelease#generate_migration"
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
class MigrationPrerelease < Prerelease
|
299
|
-
def initialize(project, base_release, version, target_version = version.truncate(:pre))
|
300
|
-
release_dir = "/migrations/..."
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
class MigrationRelease < AbstractRelease
|
305
|
-
def create
|
306
|
-
# does not call super because migrations belong to the release they migrate to
|
307
|
-
#
|
308
|
-
# code, code, code
|
309
|
-
end
|
310
|
-
|
311
|
-
def include_feature
|
312
|
-
raise NotYet
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
class Feature < Build
|
317
|
-
# Name of feature
|
318
|
-
def feature() version.feature end
|
319
|
-
|
320
|
-
# A feature's node is the feature directory
|
321
|
-
def node() release_dir end
|
322
|
-
|
323
|
-
def release_dir() migration.path end
|
324
|
-
|
325
|
-
def initialize(project, base_release, name)
|
326
|
-
base_release.is_a?(Release) || base_release.is_a?(Prerelease) or
|
327
|
-
raise Internal, "Expected a Release object, got #{base_release.class}"
|
328
|
-
version = Version.new(base_release.version, feature: name)
|
329
|
-
migration = FeatureMigration.new(Migration.path(version))
|
330
|
-
super(project, base_release, version, migration)
|
331
|
-
end
|
332
|
-
|
333
|
-
def checkout()
|
334
|
-
super
|
335
|
-
# FileUtils.ln_sf(feature, "feature")
|
336
|
-
end
|
337
|
-
|
338
|
-
def create
|
339
|
-
super
|
340
|
-
migration.create
|
341
|
-
migration.prepare
|
342
|
-
Git.commit("Created feature #{feature}")
|
343
|
-
migration.dump
|
344
|
-
self
|
345
|
-
end
|
346
|
-
|
347
|
-
# features/
|
348
|
-
# 0.0.0/
|
349
|
-
# feature_a
|
350
|
-
# feature_b/
|
351
|
-
# base_release.prick
|
352
|
-
# name.yml <- 0.2.0/feature_b
|
353
|
-
# rebased.yml <- reads base_release here
|
354
|
-
#
|
355
|
-
# 0.2.0/
|
356
|
-
# feature_a -> 0.0.0/feature_a <- not rebased
|
357
|
-
# feature_b -> 0.0.0/feature_b <- rebased
|
358
|
-
|
359
|
-
|
360
|
-
def rebase(new_base_release)
|
361
|
-
# Checkout new_base_release
|
362
|
-
# Merge feature
|
363
|
-
# Establish symlinks
|
364
|
-
# Create as branch
|
365
|
-
|
366
|
-
# new_base > base_release or
|
367
|
-
# raise Error, "Can't rebase from #{base_release.version} to #{new_base.version}"
|
368
|
-
# new_feature = Feature.new(project, base_release, base.version, base: base)
|
369
|
-
# new_feature.ensure(:active)
|
370
|
-
# schema.version = version
|
371
|
-
# FileUtils.ln_sf("../#{feature.release_dir}", new_feature.release_dir)
|
372
|
-
# Git.add(new_feature.release_dir)
|
373
|
-
# new_feature
|
374
|
-
end
|
375
|
-
end
|
376
|
-
end
|