prick 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/TODO +7 -0
  4. data/exe/prick +95 -33
  5. data/lib/ext/fileutils.rb +7 -0
  6. data/lib/prick.rb +5 -3
  7. data/lib/prick/builder.rb +31 -8
  8. data/lib/prick/cache.rb +34 -0
  9. data/lib/prick/constants.rb +106 -54
  10. data/lib/prick/database.rb +26 -18
  11. data/lib/prick/diff.rb +103 -25
  12. data/lib/prick/git.rb +31 -9
  13. data/lib/prick/head.rb +183 -0
  14. data/lib/prick/migration.rb +41 -181
  15. data/lib/prick/program.rb +199 -0
  16. data/lib/prick/project.rb +277 -0
  17. data/lib/prick/rdbms.rb +2 -1
  18. data/lib/prick/schema.rb +5 -10
  19. data/lib/prick/state.rb +129 -74
  20. data/lib/prick/version.rb +41 -28
  21. data/share/diff/diff.after-tables.sql +4 -0
  22. data/share/diff/diff.before-tables.sql +4 -0
  23. data/share/diff/diff.tables.sql +8 -0
  24. data/share/migration/diff.tables.sql +8 -0
  25. data/share/{release_migration → migration}/features.yml +0 -0
  26. data/share/migration/migrate.sql +3 -0
  27. data/share/{release_migration → migration}/migrate.yml +3 -0
  28. data/share/migration/tables.sql +3 -0
  29. data/share/{schemas → schema/schema}/build.yml +0 -0
  30. data/share/{schemas → schema/schema}/prick/build.yml +0 -0
  31. data/share/schema/schema/prick/data.sql +7 -0
  32. data/share/{schemas → schema/schema}/prick/schema.sql +0 -0
  33. data/share/{schemas → schema/schema}/prick/tables.sql +2 -2
  34. data/share/{schemas → schema/schema}/public/.keep +0 -0
  35. data/share/{schemas → schema/schema}/public/build.yml +0 -0
  36. data/share/{schemas → schema/schema}/public/schema.sql +0 -0
  37. data/test_refactor +34 -0
  38. metadata +22 -20
  39. data/file +0 -0
  40. data/lib/prick/build.rb +0 -376
  41. data/lib/prick/migra.rb +0 -22
  42. data/share/feature_migration/diff.sql +0 -2
  43. data/share/feature_migration/migrate.sql +0 -2
  44. data/share/release_migration/diff.sql +0 -3
  45. data/share/release_migration/migrate.sql +0 -5
  46. data/share/schemas/prick/data.sql +0 -7
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Required by gem
6
6
  module Prick
7
- VERSION = "0.4.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) !(string =~ VERSION_RE).nil? end
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 :custom
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 custom release
40
- def custom?() !@custom.nil? end
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, custom: nil, feature: nil)
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
- @custom = custom || $1
69
- @semver = Semantic::Version.new($2)
70
- @feature = feature || $3
74
+ @fork = fork || $1
75
+ @semver = Semantic::Version.new($3)
76
+ @feature = feature || $4
71
77
  when Semantic::Version
72
- @custom = custom
78
+ @fork = fork
73
79
  @semver = version.dup
74
80
  @feature = feature
75
81
  when Version
76
- @custom = custom || version.custom
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
- def tag() "v#{to_s}" end
134
+ # def path
135
+ # parts = [FEATURE_DIR, truncate(:pre), feature].compact
136
+ # File.join(*parts)
137
+ # end
121
138
 
122
- def path
123
- parts = [FEATURE_DIR, truncate(:pre), feature].compact
124
- File.join(*parts)
125
- end
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 = (custom || "") <=> (other.custom || "")
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 String
142
- def to_s
143
- (custom ? "#{custom}-" : "") + semver.to_s + (feature ? "_#{feature}" : "")
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,4 @@
1
+ -- Generated by prick(1) via migra(1). Please don't touch.
2
+ --
3
+ -- It should not be necessary to change this file as it doesn't contain data changes
4
+ --
@@ -0,0 +1,4 @@
1
+ -- Generated by prick(1) via migra(1). Please don't touch.
2
+ --
3
+ -- It should not be necessary to change this file as it doesn't contain data changes
4
+ --
@@ -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
+ --
@@ -0,0 +1,3 @@
1
+ -- Customize your migrations here but
2
+ --
3
+
@@ -2,4 +2,7 @@
2
2
  #
3
3
  ---
4
4
  - features
5
+ - diff.before-tables.sql
6
+ - tables
5
7
  - migrate.sql
8
+ - diff.after-tables.sql
@@ -0,0 +1,3 @@
1
+ -- Placeholder for table changes. After you prepared a diff, you should inspect
2
+ -- diff.table.sql and incorporate the changes here
3
+ --
@@ -0,0 +1,7 @@
1
+ -- Auto-generated file. Don't touch
2
+ --
3
+
4
+ COPY prick.versions (id, fork, major, minor, patch, pre, feature, version) FROM stdin;
5
+ 1 \N 0 0 0 \N \N 0.0.0
6
+ \.
7
+
@@ -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
- custom varchar,
9
+ fork varchar,
10
10
  major integer not null,
11
11
  minor integer not null,
12
12
  patch integer not null,
13
- pre varchar,
13
+ pre integer,
14
14
  feature varchar,
15
15
  version varchar not null
16
16
  );
@@ -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.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-05 00:00:00.000000000 Z
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/migra.rb
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/feature_migration/diff.sql
114
- - share/feature_migration/migrate.sql
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/release_migration/diff.sql
123
- - share/release_migration/features.yml
124
- - share/release_migration/migrate.sql
125
- - share/release_migration/migrate.yml
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/schemas/build.yml
129
- - share/schemas/prick/build.yml
130
- - share/schemas/prick/data.sql
131
- - share/schemas/prick/schema.sql
132
- - share/schemas/prick/tables.sql
133
- - share/schemas/public/.keep
134
- - share/schemas/public/build.yml
135
- - share/schemas/public/schema.sql
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.4
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
@@ -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