prick 0.17.0 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -4
  3. data/README.md +7 -7
  4. data/Rakefile +3 -1
  5. data/TODO +13 -11
  6. data/bin/console +2 -1
  7. data/doc/build-yml.txt +14 -0
  8. data/exe/prick +264 -28
  9. data/lib/builder/batch.rb +147 -0
  10. data/lib/builder/builder.rb +122 -0
  11. data/lib/builder/node.rb +189 -0
  12. data/lib/builder/node_pool.rb +105 -0
  13. data/lib/builder/parser.rb +120 -0
  14. data/lib/local/command.rb +193 -0
  15. data/lib/{prick → local}/git.rb +148 -22
  16. data/lib/local/timer.rb +98 -0
  17. data/lib/prick/constants.rb +54 -66
  18. data/lib/prick/diff.rb +28 -18
  19. data/lib/prick/prick_version.rb +161 -0
  20. data/lib/prick/state.rb +80 -165
  21. data/lib/prick/version.rb +2 -163
  22. data/lib/prick.rb +43 -27
  23. data/lib/share/init/.gitignore +10 -0
  24. data/lib/share/init/.prick-context +2 -0
  25. data/lib/share/init/.rspec +3 -0
  26. data/{share/schema/schema/public → lib/share/init/migration}/.keep +0 -0
  27. data/lib/share/init/prick.yml +6 -0
  28. data/lib/share/init/schema/.keep +0 -0
  29. data/lib/share/init/schema/build.yml +2 -0
  30. data/lib/share/init/schema/prick/.keep +0 -0
  31. data/lib/share/init/schema/prick/build.yml +5 -0
  32. data/lib/share/init/schema/prick/data.sql +6 -0
  33. data/{share/schema → lib/share/init}/schema/prick/tables.sql +2 -3
  34. data/lib/share/init/schema/public/.keep +0 -0
  35. data/lib/share/init/spec/prick_helper.rb +1 -0
  36. data/lib/share/init/spec/prick_spec.rb +6 -0
  37. data/lib/share/init/spec/spec_helper.rb +50 -0
  38. data/lib/share/migrate/migration/build.yml +4 -0
  39. data/lib/share/migrate/migration/diff.after-tables.sql +0 -0
  40. data/lib/share/migrate/migration/diff.before-tables.sql +0 -0
  41. data/lib/share/migrate/migration/diff.tables.sql +0 -0
  42. data/lib/subcommand/prick-build.rb +55 -0
  43. data/lib/subcommand/prick-create.rb +78 -0
  44. data/lib/subcommand/prick-drop.rb +25 -0
  45. data/lib/subcommand/prick-fox.rb +62 -0
  46. data/lib/subcommand/prick-init.rb +46 -0
  47. data/lib/subcommand/prick-make.rb +202 -0
  48. data/lib/subcommand/prick-migrate.rb +37 -0
  49. data/lib/subcommand/prick-release.rb +23 -0
  50. data/lib/subcommand/prick-setup.rb +20 -0
  51. data/lib/subcommand/prick-teardown.rb +18 -0
  52. data/prick.gemspec +43 -16
  53. metadata +161 -72
  54. data/.gitignore +0 -29
  55. data/.travis.yml +0 -7
  56. data/doc/create_release.txt +0 -17
  57. data/doc/flow.txt +0 -98
  58. data/doc/migra +0 -1
  59. data/doc/migrations.txt +0 -172
  60. data/doc/notes.txt +0 -116
  61. data/doc/prick.txt +0 -114
  62. data/doc/sh.prick +0 -316
  63. data/lib/ext/algorithm.rb +0 -14
  64. data/lib/ext/fileutils.rb +0 -26
  65. data/lib/ext/forward_method.rb +0 -18
  66. data/lib/ext/pg.rb +0 -18
  67. data/lib/ext/shortest_path.rb +0 -44
  68. data/lib/prick/archive.rb +0 -124
  69. data/lib/prick/branch.rb +0 -254
  70. data/lib/prick/builder.rb +0 -202
  71. data/lib/prick/cache.rb +0 -34
  72. data/lib/prick/command.rb +0 -93
  73. data/lib/prick/database.rb +0 -82
  74. data/lib/prick/dsort.rb +0 -151
  75. data/lib/prick/ensure.rb +0 -119
  76. data/lib/prick/exceptions.rb +0 -25
  77. data/lib/prick/head.rb +0 -183
  78. data/lib/prick/migration.rb +0 -70
  79. data/lib/prick/program.rb +0 -506
  80. data/lib/prick/project.rb +0 -626
  81. data/lib/prick/rdbms.rb +0 -137
  82. data/lib/prick/schema.rb +0 -27
  83. data/lib/prick/share.rb +0 -64
  84. data/libexec/strip-comments +0 -33
  85. data/make_releases +0 -72
  86. data/make_schema +0 -10
  87. data/share/diff/diff.after-tables.sql +0 -4
  88. data/share/diff/diff.before-tables.sql +0 -4
  89. data/share/diff/diff.tables.sql +0 -8
  90. data/share/features/diff.sql +0 -2
  91. data/share/features/feature/diff.sql +0 -2
  92. data/share/features/feature/migrate.sql +0 -2
  93. data/share/features/features.sql +0 -2
  94. data/share/features/features.yml +0 -2
  95. data/share/features/migrations.sql +0 -4
  96. data/share/gitignore +0 -2
  97. data/share/migration/diff.tables.sql +0 -8
  98. data/share/migration/features.yml +0 -6
  99. data/share/migration/migrate.sql +0 -3
  100. data/share/migration/migrate.yml +0 -8
  101. data/share/migration/tables.sql +0 -3
  102. data/share/schema/build.yml +0 -14
  103. data/share/schema/schema/build.yml +0 -3
  104. data/share/schema/schema/prick/build.yml +0 -14
  105. data/share/schema/schema/prick/data.sql +0 -7
  106. data/share/schema/schema/prick/schema.sql +0 -3
  107. data/share/schema/schema/public/build.yml +0 -13
  108. data/share/schema/schema.sql +0 -3
  109. data/test_assorted +0 -192
  110. data/test_feature +0 -112
  111. data/test_refactor +0 -34
  112. data/test_single_dev +0 -83
data/lib/prick/project.rb DELETED
@@ -1,626 +0,0 @@
1
- require "prick/state.rb"
2
-
3
- require "tmpdir"
4
-
5
- module Prick
6
- class Project
7
- attr_reader :name
8
- attr_reader :user # Database user
9
- attr_reader :head # Current branch/tag
10
- attr_reader :schema
11
-
12
- # Return the versioned database or the project database if `version` is nil
13
- def database(version = nil)
14
- version ? Database.new("#{name}-#{version}", user) : @database
15
- end
16
-
17
- attr_reader :cache
18
-
19
- def initialize(name, user, head)
20
- @name = name
21
- @user = user || ENV['USER']
22
- @head = head
23
- @schema = Schema.new
24
- @database = Database.new(name, user)
25
- @cache = Cache.new
26
- end
27
-
28
- forward_methods :version, :base_version, :@head
29
- forward_methods :clean?, :@head
30
- forward_methods :tag?, :release_tag?, :migration_tag?, :@head
31
- forward_methods :branch?, :release_branch?, :prerelease_branch?, :feature_branch?, :migration_branch?, :@head
32
-
33
- def self.exist?(directory)
34
- File.directory?(directory) && Dir.chdir(directory) { ProjectState.new.exist? }
35
- end
36
-
37
- def self.create(name, user, directory)
38
- user ||= ENV['USER']
39
-
40
- FileUtils.mkdir(directory) if directory != "."
41
-
42
- Dir.chdir(directory) {
43
- # Initialize git instance
44
- Git.init
45
-
46
- # Create prick version file
47
- PrickVersion.new.write(VERSION)
48
-
49
- # Create project state file
50
- ProjectState.new(name: name, user: user).write
51
-
52
- # Directories
53
- FileUtils.mkdir_p(DIRS)
54
- DIRS.each { |dir| FileUtils.touch("#{dir}/.keep") }
55
-
56
- # Copy default gitignore and schema files
57
- Share.cp("gitignore", ".gitignore")
58
- Share.cp("schema/schema", ".")
59
-
60
- # Add .prick-migration file
61
- MigrationState.new(version: Version.zero).create
62
-
63
- # Add everything so far
64
- Git.add(".")
65
- Git.commit("Initial import")
66
-
67
- # Rename branch "master"/"main" to "0.0.0_initial"
68
- from_branch = Git.branch?("master") ? "master" : "main"
69
- Git.rename_branch(from_branch, "0.0.0_initial")
70
-
71
- # Create schema
72
- schema = Schema.new
73
- schema.version = Version.zero
74
- Git.add schema.version_file
75
-
76
- # Create release
77
- Git.commit "Created release v0.0.0"
78
- Git.create_tag(Version.zero)
79
- Git.checkout_tag(Version.zero)
80
- }
81
- end
82
-
83
- # Initialize from disk
84
- #
85
- # TODO Handle migrations
86
- def self.load
87
- if Git.detached?
88
- name = "v#{Git.current_tag}"
89
- else
90
- name = Git.current_branch
91
- end
92
- begin
93
- branch = Head.load(name)
94
- rescue Version::FormatError
95
- raise Fail, "Illegal branch name: #{name}"
96
- end
97
- state = ProjectState.new.read
98
- Project.new(state.name, state.user, branch)
99
- end
100
-
101
- def build(database = self.database, version: nil)
102
- database.clean
103
- if version
104
- FileUtils.mkdir_p(TMP_DIR)
105
- Dir.mktmpdir("clone-", TMP_DIR) { |dir|
106
- Command.command "git clone . #{dir}"
107
- Dir.chdir(dir) {
108
- Git.checkout_tag(version)
109
- project = Project.load
110
- project.head.build(database)
111
- }
112
- }
113
- else
114
- head.build(database)
115
- end
116
- self
117
- end
118
-
119
- def load(database = self.database, version: nil, file: nil)
120
- version.nil? ^ file.nil? or raise Internal, "Need exactly one of :file and :version to be defined"
121
- database.clean
122
- if version
123
- cache.exist?(version) or raise Internal, "Can't find cache file for database #{database}"
124
- cache.load(database, version)
125
- else
126
- database.load(file)
127
- end
128
- self
129
- end
130
-
131
- def save(database = nil, file: nil)
132
- !database.nil? || file or raise Internal, "Need a database when saving to file"
133
- database ||= self.database
134
- if file
135
- database.save(file)
136
- else
137
- cache.save(database)
138
- end
139
- self
140
- end
141
-
142
- # Create a schema diff between two database versions. to_version defaults to the
143
- # current version. Returns the Diff object
144
- def diff(from_version, to_version)
145
- begin
146
- from_db = Database.new("#{name}-base", user)
147
- to_db = Database.new("#{name}-next", user)
148
- from_version ||= version
149
- build(from_db, version: from_version)
150
- build(to_db, version: to_version)
151
- Diff.new(from_db, to_db)
152
- ensure
153
- from_db&.drop
154
- to_db&.drop
155
- end
156
- end
157
-
158
- def prepare_release(fork = nil)
159
- check_clean(:release_tag)
160
- @head = ReleaseBranch.new(fork, version).create
161
- submit "Prepared new release based on v#{version}", true
162
- self
163
- end
164
-
165
- def prepare_schema(name, commit: true)
166
- path = File.join(SCHEMA_DIR, name)
167
- FileUtils.mkdir_p(path)
168
- Git.add Share.cp("schema/schema.sql", path, clobber: false, templates: { 'SCHEMA' => name })
169
- Git.add Share.cp("schema/build.yml", path, clobber: false)
170
- File.open(Schema.yml_file, "a") { |f| f.write("- #{name}\n") }
171
- Git.add(Schema.yml_file)
172
- submit "Added schema #{name}", commit
173
- end
174
-
175
- def prepare_diff(from_version = version)
176
- begin
177
- from_name = "#{name}-base"
178
- from_db = Database.new(from_name, user)
179
- build(from_db, version: from_version)
180
-
181
- to_name = "#{name}-next"
182
- to_db = Database.new(to_name, user)
183
- build(to_db)
184
-
185
- if prerelease_branch?
186
- head.migrate_features(from_db)
187
- end
188
-
189
- diff = Diff.new(from_db, to_db)
190
- for path, lines, tables in [
191
- [BEFORE_TABLES_DIFF_PATH, diff.before_table_changes, false],
192
- [TABLES_DIFF_PATH, diff.table_changes, true],
193
- [AFTER_TABLES_DIFF_PATH, diff.after_table_changes, false]]
194
- if lines.empty?
195
- if File.exist?(path)
196
- if tables
197
- Share.cp(File.join("diff", File.basename(path)), path)
198
- Git.add(path)
199
- else
200
- Git.rm(path)
201
- end
202
- end
203
- else
204
- Share.cp(File.join("diff", File.basename(path)), path)
205
- File.open(path, "a") { |f| f.puts lines }
206
- Git.add(path) if !tables
207
- end
208
- end
209
- self
210
- ensure
211
- from_db&.drop
212
- to_db&.drop
213
- end
214
- end
215
-
216
- def create_release(new_version)
217
- check_clean(:release_branch)
218
- head = ReleaseTag.new(new_version, version)
219
- check_migration(head.migration)
220
- (@head = head).create
221
- self
222
- end
223
-
224
- def generate_schema
225
- build = SchemaBuilder.new(database, SCHEMA_DIR).build(execute: false)
226
- puts build.lines
227
- end
228
-
229
- def generate_migration
230
- build = MigrationBuilder.new(database, MIGRATION_DIR).build(execute: false)
231
- puts build.lines
232
- end
233
-
234
- private
235
- def check(kind) self.send(:"#{kind}?") end
236
- def check_clean(kind = nil)
237
- clean? or raise Internal, "Dirty repository"
238
- kind.nil? || check(kind) or raise Internal, "Not on a #{kind} tag/branh"
239
- end
240
-
241
- def check_branch() branch? or raise Internal, "Not on a branch" end
242
- def check_tag() tag? or raise Internal, "Not on a tag" end
243
-
244
- # FIXME: Use Cache::file
245
- def cache_file(version) File.join(CACHE_DIR, "#{database(version)}.sql.gz") end
246
-
247
- def submit(msg, commit = true)
248
- Git.commit msg if commit
249
- @message = msg
250
- end
251
-
252
- def clean(database) # FIXME: Use Database#clean
253
- if database.exist?
254
- database.recreate if database.loaded?
255
- else
256
- database.create
257
- end
258
- end
259
-
260
- def check_migration(migration)
261
- begin
262
- from_version = migration.base_version
263
- from_db = Database.new("#{name}-base", user)
264
- to_db = Database.new("#{name}-next", user)
265
- build(from_db, version: from_version)
266
- build(to_db)
267
- migration.migrate(from_db)
268
- Diff.new(from_db, to_db).same? or raise Error, "Schema/migration mismatch"
269
- ensure
270
- from_db&.drop
271
- to_db&.drop
272
- end
273
- end
274
- end
275
- end
276
-
277
- __END__
278
-
279
- module Prick
280
- class Project
281
- # Name of project. Persisted in the project state file
282
- attr_reader :name
283
-
284
- # Name of Postgresql user that owns the databases. Defaults to #name.
285
- # Persisted in the project state file. TODO: Make writable
286
- attr_reader :user
287
-
288
- # Current branch
289
- attr :branch
290
-
291
- # Version of the current branch. If is defined as #branch.version
292
- def version() branch.version end
293
-
294
- # Project (default) database
295
- def database(version = nil)
296
- version ? Database.new("#{name}-#{version.truncate(:pre)}", user) : @database
297
- end
298
-
299
- # Last commit message. TODO: Move to git.rb
300
- attr_reader :message
301
-
302
- # True if we're on a tag
303
- def tag?() Git.detached? end
304
- def self.tag?() Git.detached? end
305
-
306
- # Classifiers
307
- forward_methods :release?, :prerelease?, :feature?, :migration?, :@branch
308
-
309
- def initialize(name, user, branch)
310
- @name = name
311
- @user = user
312
- @branch = branch
313
- @database = Database.new(name, user)
314
- end
315
-
316
- def self.load
317
- name = Git.current_branch || Git.current_tag
318
- if name =~ MIGRATION_RE
319
- branch = MigrationRelease.load(name)
320
- else
321
- begin
322
- version = Version.new(name)
323
- rescue Version::FormatError
324
- raise Fail, "Illegal branch name: #{name}"
325
- end
326
- if version.release?
327
- branch = Release.load(name)
328
- elsif version.pre?
329
- branch = PreRelease.load(name, version)
330
- elsif version.feature?
331
- branch = Feature.load(name)
332
- else
333
- raise Oops
334
- end
335
- end
336
- state = ProjectState.new.read
337
- Project.new(state.name, state.user, branch)
338
- end
339
-
340
- def self.initialized?(directory)
341
- File.directory?(directory) && Dir.chdir(directory) { ProjectState.new.exist? }
342
- end
343
-
344
- def self.initialize_directory(name, user, directory)
345
- FileUtils.mkdir_p(directory)
346
- Dir.chdir(directory) {
347
- # Initialize git instance
348
- Git.init
349
-
350
- # Create prick version file
351
- PrickVersion.new.write(VERSION)
352
-
353
- # Create project state file
354
- ProjectState.new(name: name, user: user).write
355
-
356
- # Directories
357
- DIRS.each { |dir|
358
- !File.exist?(dir) or raise Fail, "Already initialized: Directory '#{dir}' exists"
359
- }
360
- FileUtils.mkdir_p(DIRS)
361
- DIRS.each { |dir| FileUtils.touch("#{dir}/.keep") }
362
-
363
- # Copy default gitignore and schema files
364
- Share.cp("gitignore", ".gitignore")
365
- Share.cp("schemas", ".")
366
-
367
- # Add everything so far
368
- Git.add(".")
369
- Git.commit("Initial import")
370
-
371
- # Create initial release
372
- release = Release.new(Version.zero, nil)
373
- release.create
374
-
375
- schema = Schema.new(SCHEMAS_DIR)
376
- schema.version = release.version
377
- Git.add schema.version_file
378
-
379
- Git.commit "Release 0.0.0"
380
- release.tag!
381
-
382
- # Kill master branch
383
- Git.delete_branch("master")
384
- }
385
- end
386
-
387
- def build(database: self.database, version: nil)
388
- clean(database)
389
- if version
390
- FileUtils.mkdir_p(TMP_DIR)
391
- Dir.mktmpdir("clone-", TMP_DIR) { |dir|
392
- Command.command "git clone . #{dir}"
393
- Dir.chdir(dir) {
394
- Git.checkout_tag(version)
395
- project = Project.load
396
- project.branch.build(database)
397
- }
398
- }
399
- else
400
- branch.build(database)
401
- end
402
- self
403
- end
404
-
405
- def load(file, database: self.database)
406
- clean(database)
407
- database.load(file)
408
- self
409
- end
410
-
411
- def save(file, database: self.database)
412
- database.save(file)
413
- self
414
- end
415
-
416
- def cache_file(version) File.join(CACHE_DIR, "#{database(version)}.sql.gz") end
417
-
418
- def make(database, subject)
419
- Schema.built? or raise Error, "Schema is not built into project database"
420
- Schema.make(database, subject)
421
- end
422
-
423
- def backup(path = nil)
424
- save path || File.join(SPOOL_DIR, "#{name}-#{Time.now.utc.strftime("%Y%m%d-%H%M%S")}.sql.gz")
425
- end
426
-
427
- def restore(path = nil)
428
- load path || Dir.glob(File.join(SPOOL_DIR, "#{name}-*.sql.gz")).sort.last
429
- end
430
-
431
- def prepare_release(commit: true)
432
- release = ReleaseMigration.new(nil, branch.version).create
433
- submit "Prepared new release based on #{version}", commit
434
- release
435
- end
436
-
437
- def prepare_schema(name, commit: true)
438
- path = File.join(SCHEMAS_DIR, name)
439
- FileUtils.mkdir_p(path)
440
- Git.add Share.cp("schema/*", path, clobber: false, templates: { 'SCHEMA' => name })
441
- File.open(branch.schema.yml_file, "a") { |f| f.write("- #{name}\n") }
442
- Git.add(branch.schema.yml_file)
443
- submit "Added schema #{name}", commit
444
- end
445
-
446
- def prepare_diff(from_version)
447
- to_database = nil
448
- begin
449
- from_name = "#{name}-base"
450
- from_database = Database.new(from_name, user)
451
- build(database: from_database, version: from_version)
452
-
453
- to_name = "#{name}-next"
454
- to_database = Database.new(to_name, user)
455
- build(database: to_database)
456
-
457
- # Helpful double-check
458
- Diff.same?(to_database.name, database.name) or
459
- raise Error, "Schema and project database are not synchronized"
460
-
461
- if release?
462
- dir = branch.migration.migration_dir
463
- else
464
- dir = branch.migration.features_dir
465
- end
466
-
467
- # dir = branch.migration.features_dir || branch.migration.migration_dir
468
- to_file = File.join(dir, DIFF_FILE)
469
-
470
- if prerelease?
471
- branch.migrate_features(from_database)
472
- end
473
-
474
- Diff.new(from_name, to_name).write(to_file)
475
- ensure
476
- from_database&.drop
477
- to_database&.drop
478
- end
479
- end
480
-
481
- def prepare_migration(from, commit: true)
482
- to = branch.version
483
- migration_release = MigrationRelease.new(to, from)
484
- migration_release.create
485
- submit "Prepared migration from #{from} to #{to}", commit
486
- migration_release
487
- end
488
-
489
- def create_release(version, commit: true)
490
- check_migration(branch.version) or raise Error, "Schema/migration mismatch"
491
- release = Release.new(version, branch.version)
492
- release.create
493
- submit "Created release #{version}", commit
494
- release.tag!
495
- build
496
- release
497
- end
498
-
499
- def cancel_release(version, commit: true)
500
- Git.cancel_tag(version)
501
- end
502
-
503
- def create_release_from_prerelease(commit: true)
504
- check_migration(branch.base_version) or raise Error, "Schema/migration mismatch"
505
- release = Release.new(branch.version.truncate(:pre), branch.base_version)
506
- release.create
507
- submit "Released #{release.version}", commit
508
- release.tag!
509
- build
510
- release
511
- end
512
-
513
- def create_prerelease(version, commit: true)
514
- prerelease = PreRelease.new(version.increment(:pre), branch.version)
515
- prerelease.create
516
- submit "Created pre-release #{prerelease.version}", commit
517
- build
518
- prerelease
519
- end
520
-
521
- def increment_prerelease(commit: true)
522
- prerelease = branch.increment
523
- prerelease.create
524
- submit "Created pre-release #{prerelease.version}", commit
525
- build
526
- prerelease
527
- end
528
-
529
- # # Turned out to be a bad idea
530
- # def retarget_migration(version, commit: true)
531
- # branch.retarget(version)
532
- # commit "Retargeted to #{version}" if commit
533
- # branch
534
- # end
535
-
536
- def create_feature(name, commit: true)
537
- feature = Feature.new(name, version)
538
- feature.create
539
- submit "Created feature #{name}", commit
540
- end
541
-
542
- def include_feature(feature_version, commit: false)
543
- Git.merge_branch(feature_version, exclude_files: [branch.schema.version_file], fail: true)
544
- branch.include(feature_version)
545
- end
546
-
547
- # Checks that the migration of the current branch takes the database from
548
- # the base version to the content of the schema
549
- def check_migration(from_version)
550
- begin
551
- from_db = Database.new("#{name}-base", user)
552
- to_db = Database.new("#{name}-next", user)
553
- build(database: from_db, version: from_version)
554
- build(database: to_db)
555
- migration = # FIXME: This may be a repeated pattern
556
- if migration?
557
- branch.migration
558
- elsif prerelease?
559
- branch.migration
560
- else
561
- Migration.new(nil, branch.directory)
562
- end
563
- migration.migrate(from_db)
564
- Diff.new(from_db, to_db).same?
565
- ensure
566
- from_db&.drop
567
- to_db&.drop
568
- end
569
- end
570
-
571
- # TODO: Make production-only and add a to-argument
572
- def upgrade
573
- branches = list_upgrades(database.version, branch.version)
574
- FileUtils.mkdir_p(TMP_DIR)
575
- Dir.mktmpdir("clone-", TMP_DIR) { |dir|
576
- Command.command "git clone . #{dir}"
577
- Dir.chdir(dir) {
578
- branches.each { |branch|
579
- branch.checkout_release
580
- project = Project.load
581
- project.branch.migrate(project.database)
582
- }
583
- }
584
- }
585
- end
586
-
587
- def list_releases(all: false)
588
- Git.list_tags(include_cancelled: all).grep(RELEASE_RE) { |tag|
589
- version = $2
590
- dir = File.join(RELEASES_DIR, version)
591
- migration_state = MigrationState.new(dir).read(tag: tag)
592
- Release.new(migration_state.version, migration_state.base_version)
593
- }
594
- end
595
-
596
- # TODO
597
- # list_migrations(all: false)
598
- def list_migrations
599
- Git.list_branches.grep(MIGRATION_RE) { |branch|
600
- from_version = Version.new($1)
601
- to_version = Version.new($4)
602
- MigrationRelease.new(to_version, from_version)
603
- }
604
- end
605
-
606
- def list_upgrades(from, to)
607
- edges = (list_releases + list_migrations).map { |branch| [branch.base_version, branch.version, branch] }
608
- (Algorithm.shortest_path(edges, from, to) || []).map(&:last)
609
- end
610
-
611
- private
612
- def submit(msg, commit = true)
613
- Git.commit msg if commit
614
- @message = msg
615
- end
616
-
617
- def clean(database)
618
- if database.exist?
619
- database.recreate if database.loaded?
620
- else
621
- database.create
622
- end
623
- end
624
- end
625
- end
626
-