prick 0.3.0 → 0.8.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/TODO +7 -0
  4. data/exe/prick +235 -163
  5. data/lib/ext/fileutils.rb +7 -0
  6. data/lib/prick.rb +7 -5
  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 -20
  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 +255 -0
  16. data/lib/prick/project.rb +264 -0
  17. data/lib/prick/rdbms.rb +3 -12
  18. data/lib/prick/schema.rb +6 -11
  19. data/lib/prick/state.rb +129 -74
  20. data/lib/prick/version.rb +41 -28
  21. data/prick.gemspec +3 -1
  22. data/share/diff/diff.after-tables.sql +4 -0
  23. data/share/diff/diff.before-tables.sql +4 -0
  24. data/share/diff/diff.tables.sql +8 -0
  25. data/share/migration/diff.tables.sql +8 -0
  26. data/share/{release_migration → migration}/features.yml +0 -0
  27. data/share/migration/migrate.sql +3 -0
  28. data/share/{release_migration → migration}/migrate.yml +3 -0
  29. data/share/migration/tables.sql +3 -0
  30. data/share/{schemas → schema/schema}/build.yml +0 -0
  31. data/share/{schemas → schema/schema}/prick/build.yml +0 -0
  32. data/share/schema/schema/prick/data.sql +7 -0
  33. data/share/{schemas → schema/schema}/prick/schema.sql +0 -0
  34. data/share/{schemas → schema/schema}/prick/tables.sql +2 -2
  35. data/share/{schemas → schema/schema}/public/.keep +0 -0
  36. data/share/{schemas → schema/schema}/public/build.yml +0 -0
  37. data/share/{schemas → schema/schema}/public/schema.sql +0 -0
  38. data/test_refactor +34 -0
  39. metadata +23 -21
  40. data/file +0 -0
  41. data/lib/prick/build.rb +0 -376
  42. data/lib/prick/migra.rb +0 -22
  43. data/share/feature_migration/diff.sql +0 -2
  44. data/share/feature_migration/migrate.sql +0 -2
  45. data/share/release_migration/diff.sql +0 -3
  46. data/share/release_migration/migrate.sql +0 -5
  47. data/share/schemas/prick/data.sql +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb7c2d20ea8aa16ba957f5139e00b02eec90d92a16316d9a468b97df7f83bc93
4
- data.tar.gz: 6c2a0acd245344a1bb302aede789bb964757462786aebdc5fec14ea33f43e42f
3
+ metadata.gz: 98dae1ae969be39dba2d394c5ef973837bddd75b57e95a50984369b9b63b68a9
4
+ data.tar.gz: 2d346ef2b8b6ea0bde7c6a0442278f9c9a3132a8268555417790f7cd5f45a936
5
5
  SHA512:
6
- metadata.gz: 4d350899a5591bc2c6b8d2b6f88948ddf39a6146a535411c1affccf3f5f32dcee4ccb8b30ea0e19060d7bc6a6d1c21064ae10dacf9f19aa3997d04fd2466c892
7
- data.tar.gz: fad2bbb8a50f18c779160bc17308072a94fd4ca98b1db76c3c16724eafe1c4128c4df4b0485051a136a19cf0315daff9b19dd4035dfe54cdbf624376c7c3c4c4
6
+ metadata.gz: fe461c8c031c7279cdd53329b92808a92367939841d30c4e7a995ae2c42e089fbdf0c8e143beef9997512bb94dc0b2c838df83d8990b545a27dec1ab94e0f3ba
7
+ data.tar.gz: 03cd1324f95be8e3672cc0e1a05e1818c287d62e786a4ac27eebf42d9f71151766d7002f1f19de0c1f44b86568797e80d96e6209103661ba1d4cb8132d959ca8
data/.gitignore CHANGED
@@ -24,3 +24,6 @@
24
24
 
25
25
  # Ignore development testing dir
26
26
  /dir
27
+
28
+ # Ignore stove-away directory
29
+ /hold
data/TODO CHANGED
@@ -1,3 +1,10 @@
1
1
 
2
+ o Check for commits to tags
3
+ o Accumulate version history in prick.versions instead of just having the newest
4
+ o Using rc's in migration syntax: fork-version-fork-version.rc1 ?
2
5
  o Make it possible to execute prick in any subdirecty instead of only in the root
6
+ o Hack migra to create separate file(s) for table changes
7
+ o Also execute subject/ directory if only a subject.sql is found. subject.yml
8
+ should still override everything
9
+ o Track included files - this will make dependency checks much easier
3
10
 
data/exe/prick CHANGED
@@ -4,180 +4,163 @@ require 'prick.rb'
4
4
  require 'prick/program.rb'
5
5
 
6
6
  require 'shellopts'
7
- require 'indented_io'
8
7
 
9
8
  require 'tempfile'
10
9
 
11
10
  include ShellOpts
12
11
  include Prick
13
12
 
14
- PROGRAM = File.basename($0)
15
-
16
13
  SPEC = %(
17
- n,name=NAME
18
- C,directory=DIR
19
- h,help
20
- v,verbose
21
- q,quiet
22
- version
14
+ -n,name=NAME
15
+ Name of project. Defauls to the environment variable `PRICK_PROJECT` if
16
+ set and else the name of the current directory
23
17
 
24
- init! u,user=USER
18
+ -C,directory=DIR
19
+ Change to directory DIR before doing anything else
25
20
 
26
- info!
27
- list! list.releases! m,migrations c,cancelled list.migrations! list.upgrades! a,all
21
+ -h,help COMMAND...
22
+ Print this page
28
23
 
29
- build! d,database=DATABASE C,nocache
30
- make!
31
- load! d,database=DATABASE
32
- save! d,database=DATABASE
33
- migrate!
24
+ +v,verbose
25
+ Be verbose. Repeated --verbose options increase the verbosity level
34
26
 
35
- prepare! prepare.release! prepare.migration! prepare.schema! prepare.diff!
36
- include! include.feature!
37
- check!
27
+ -q,quiet
28
+ Be quiet
38
29
 
39
- create! create.release! create.prerelease! create.feature!
40
- cancel! cancel.release!
30
+ --version
31
+ Print prick version
41
32
 
42
- upgrade!
43
- backup!
44
- restore!
45
- )
33
+ init! -u,user=USER [DIR]
34
+ Initialize a project in the given directory. DIR defaults to the current
35
+ directory. The USER is the postgres user, it defaults to the project name
46
36
 
47
- USAGE = "Usage: #{PROGRAM} -h -v -n NAME -C DIR COMMAND" # FIXME: Why doesn't shellopts include PROGRAM?
37
+ info!
38
+ Print project information
48
39
 
49
- HELP = %(
50
- NAME
51
- prick - Database version management
40
+ list.releases! -m,migrations -c,cancelled
41
+ List releases. Include migration releases if the --migration option is
42
+ present and also include cancelled releases if the --cancelled option is
43
+ present
52
44
 
53
- USAGE
54
- prick -v -n NAME -C DIR -h <command>
45
+ list.migrations!
46
+ List migrations
55
47
 
56
- OPTIONS
57
- -n, --name=NAME
58
- Name of project. Defauls to the environment variable `PRICK_PROJECT` if
59
- set and else the name of the current directory
48
+ list.upgrades! [FROM [TO]]
49
+ List available upgrades
60
50
 
61
- -C, --directory=DIR
62
- Change to directory DIR before anything else
51
+ list.cache!
52
+ List cache files
63
53
 
64
- -h, --help
65
- Print this page
54
+ build! -d,database=DATABASE -C,no-cache [TAG]
55
+ Build the current database from the content in the schemas/ directory.
56
+ With a tag the version is built into the associated versioned database
57
+ and the result is saved to cache unless the -C option is given. The -d
58
+ option overrides the default database
66
59
 
67
- -v, --verbose
68
- Be verbose
60
+ make! -d,database=DATABASE -C,no-cache [TAG]
61
+ Build the current database from the content in the schemas/ directory.
62
+ With a tag the associated versioned database is loaded from cache if
63
+ present. The -C option ignores the cache and the -d option overrides
64
+ the default database
69
65
 
70
- --version
71
- Print prick version
66
+ make.clean! -a,all
67
+ Drop versioned databases and remove cached and other temporary files.
68
+ Also drop the project database if the -a option is given
72
69
 
73
- COMMANDS
74
- INITIALIZATION
75
- init [DIR] --user=USER
76
- Initialize a project in the given directory. DIR defaults to the
77
- current directory. The USER is the postgres user, it defaults to
78
- the project name
70
+ load! -d,database=DATABASE VERSION|FILE
71
+ Load the cached version or the file into the associated versioned
72
+ database. It is an error if the version hasn't been cached. The --database
73
+ argument overrides the database
79
74
 
80
- INFO COMMANDS
81
- info
75
+ save! VERSION [FILE]
76
+ Save the versioned database associated with version to the cache or the
77
+ given file
82
78
 
83
- list releases --migrations --cancelled
84
- list migrations
85
- list upgrades --all
86
- List releases/migrations/upgrades
79
+ drop! -a,all [DATABASE]
80
+ Drop the given database or all versioned databases. The --all option also
81
+ drops the project database
87
82
 
88
- BUILDING
89
- build -d database -C --nocache [version]
90
- Builds the current database from the content in the schemas/ directory.
91
- With an explicit version the given version is built or loaded from cache
92
- into the associated versioned database. The -C argument force a build even
93
- if a cache file is present. The -d option overrides the database
94
-
95
- make
96
- Not yet implemented
97
-
98
- load -d database file|version
99
- Load a version or file into a database. If the argument is a version the
100
- assocated versioned database will be loaded from cache. If the argument is
101
- a file the project database is loaded. The -d option overrides what
102
- database is used. This is often used to load a specific version into the
103
- project database ('prick load -d <project-name> <version>') or to load into
104
- an unrelated database not controlled by prick
105
-
106
- save -d database [file]
107
- Save the project database to the given file. Default file name is the
108
- username suffixed with project name, custom name, and branch
83
+ diff! -m,mark -t,tables -T,notables
84
+ diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
85
+ Create a schema diff between the given databases or versions. Default
86
+ to-version is the current schema and default from-version is the base
87
+ version of this branch/tag
109
88
 
110
- migrate
111
- Not yet implemented
89
+ migrate!
90
+ Not yet implemented
112
91
 
113
- PREPARING RELEASES
114
- prepare release
115
- Populate the current migration directory with migration files
92
+ prepare!
93
+ Prepare a release. Just a shorthand for 'prick prepare release'
116
94
 
117
- prepare feature NAME
118
- Create and populate a feature as a subdirectory of the current
119
- directory. Also prepares the current release directory
95
+ prepare.release! [FORK]
96
+ Populate the current migration directory with migration files
120
97
 
121
- prepare migration FROM
122
- Create and populate a migration directory
98
+ prepare.feature! NAME
99
+ Create and populate a feature as a subdirectory of the current directory.
100
+ Also prepares the current release directory
123
101
 
124
- prepare schema NAME
125
- Create and populate a new schema directory. Existing files and
126
- directories are kept
102
+ prepare.migration! [FROM]
103
+ Create and populate a migration directory
127
104
 
128
- prepare diff [VERSION]
105
+ prepare.schema! NAME
106
+ Create and populate a new schema directory. Existing files and
107
+ directories are kept
108
+
109
+ prepare.diff! [VERSION]
110
+ Not yet implemented
129
111
 
130
- include feature FEATURE
131
- Include the given feature in the current pre-release
112
+ include.feature! FEATURE
113
+ Include the given feature in the current pre-release
132
114
 
133
- check
134
- Check that the current migration applied to the base version yields the
135
- same result as loading the current schema
115
+ check!
116
+ Check that the current migration applied to the base version yields the
117
+ same result as loading the current schema
136
118
 
137
- CREATING RELEASES
138
- create release [RELEASE]
139
- Prepare a release and create release directory and migration file
140
- before tagging and branching to a release branch. The RELEASE argument
141
- can be left out if the current branch is a prerelease branch
119
+ create.release! [RELEASE]
120
+ Prepare a release and create release directory and migration file before
121
+ tagging and branching to a release branch. The RELEASE argument can be
122
+ left out if the current branch is a prerelease branch
142
123
 
143
- create prerelease RELEASE
144
- Prepare a release and create release directory and migration file
145
- before branching to a prerelease branch
146
-
147
- create feature NAME
148
- Prepare a feature before branching to a feature branch
124
+ create.prerelease! RELEASE
125
+ Prepare a release and create release directory and migration file before
126
+ branching to a prerelease branch
149
127
 
150
- cancel release RELEASE
151
- Cancel a release. Since tags are immutable, the release is cancelled by
152
- added a special cancel-tag to the release that makes prick ignore it
128
+ create.feature! NAME
129
+ Prepare a feature before branching to a feature branch
153
130
 
154
- DEPLOYING RELEASES
155
- upgrade
156
- Migrate the database to match the current schema
131
+ cancel!
132
+ Cancel a release. Just a shorthand for 'prick cancel release'
133
+
134
+ cancel.release!
135
+ Cancel a release. Since tags are immutable, the release is cancelled by
136
+ added a special cancel-tag to the release that makes prick ignore it
157
137
 
158
- backup [FILE]
159
- Saves a backup of the database to the given file or to the var/spool
160
- directory
138
+ generate.migration!
139
+ Create a script to migrate the database
161
140
 
162
- restore [FILE]
163
- Restore the database from the given backup file or from the latest
164
- backup in the var/spool directory
141
+ generate.schema!
142
+ Create a script to create the database
143
+
144
+ upgrade!
145
+ Migrate the database to match the current schema
146
+
147
+ backup! [FILE]
148
+ Saves a backup of the database to the given file or to the var/spool
149
+ directory
150
+
151
+ restore! [FILE]
152
+ Restore the database from the given backup file or from the latest backup
153
+ in the var/spool directory
165
154
  )
166
155
 
167
156
 
168
- opts, args = ShellOpts.as_struct(SPEC, ARGV)
157
+
158
+ opts, args = ShellOpts.process(SPEC, ARGV)
169
159
 
170
160
  # Handle --help
171
- if opts.help?
172
- begin
173
- file = Tempfile.new("prick")
174
- file.puts HELP.split("\n").map { |l| l.sub(/^ /, "") }
175
- file.flush
176
- system "less #{file.path}"
177
- ensure
178
- file.close
179
- end
180
- exit
161
+ if opts.help?
162
+ ShellOpts.help
163
+ exit
181
164
  end
182
165
 
183
166
  # Handle --version
@@ -188,7 +171,7 @@ end
188
171
 
189
172
  begin
190
173
  # Honor -C option
191
- if opts.directory
174
+ if opts.directory?
192
175
  if File.exist?(opts.directory)
193
176
  begin
194
177
  Dir.chdir(opts.directory)
@@ -206,9 +189,9 @@ begin
206
189
  # Handle init command
207
190
  if opts.subcommand == :init
208
191
  directory = args.expect(0..1)
209
- name = opts.name || directory || File.basename(Dir.getwd)
210
- user = opts.init.user || name
211
- program.initialize_directory(name, user, directory || ".")
192
+ name = opts.name || (directory && File.basename(directory)) || File.basename(Dir.getwd)
193
+ user = opts.init!.user || name
194
+ program.init(name, user, directory || ".")
212
195
  exit 0
213
196
  end
214
197
 
@@ -218,51 +201,77 @@ begin
218
201
  VERSION == file.read.to_s or
219
202
  raise Prick::Fail, ".prick-version required prick-#{file.read} but you're using prick-#{VERSION}"
220
203
 
204
+ # TODO: Check for dirty detached head
205
+
221
206
  # Expect a sub-command
222
- opts.subcommand? or raise Prick::Error, "Subcomand expected"
207
+ opts.subcommand or raise Prick::Error, "Subcomand expected"
223
208
 
224
209
  case opts.subcommand
225
210
  when :info
226
211
  args.expect(0)
227
212
  program.info
228
213
 
229
- when :build
230
- version = args.expect(0..1)
231
- program.build(opts.build.database, version, opts.build.nocache)
232
-
233
- when :save
234
- file_or_version = args.expect(0..1)
235
- program.save(opts.save.database, file_or_version)
236
-
237
- when :load
238
- file_or_version = args.expect(1)
239
- program.load(opts.load.database, file_or_version)
240
-
241
- when :make
242
- raise NotYet
243
-
244
- when :migrate
245
- raise NotYet
246
-
247
214
  when :list
248
- command = opts.list
215
+ command = opts.list!
249
216
  case command.subcommand
250
217
  when :releases;
251
- obj = command.releases
218
+ obj = command.releases!
252
219
  program.list_releases(migrations: obj.migrations?, cancelled: obj.cancelled?)
253
220
  when :migrations; program.list_migrations
254
221
  when :upgrades; program.list_upgrades(*args.expect(0..2).compact)
222
+ when :cache;
223
+ args.expect(0)
224
+ program.list_cache
255
225
  when NilClass; raise Prick::Error, "list requires a releases|migrations|upgrades sub-command"
256
226
  else
257
227
  raise Prick::Internal, "Subcommand #{opts.subcommand}.#{command.subcommand} is not matched"
258
228
  end
259
229
 
230
+ when :build
231
+ version = args.expect(0..1)
232
+ program.build(opts.build!.database, version, opts.build!.no_cache?)
233
+
234
+ when :make
235
+ command = opts.make!
236
+ case command.subcommand
237
+ when :clean
238
+ args.expect(0)
239
+ program.make_clean(command.clean!.all?)
240
+ else
241
+ version = args.expect(0..1)
242
+ program.make(opts.make!.database, version, opts.make!.no_cache?)
243
+ end
244
+
245
+ when :load
246
+ version_or_file = args.expect(1)
247
+ program.load(opts.load!.database, version_or_file)
248
+
249
+ when :save
250
+ version, file = args.expect(1..2)
251
+ program.save(version, file)
252
+
253
+ when :drop
254
+ program.drop(args.expect(0..1), opts.drop!.all)
255
+
256
+ when :diff
257
+ mark = opts.diff!.mark
258
+ tables = opts.diff!.tables
259
+ no_tables = opts.diff!.notables
260
+ tables.nil? && no_tables.nil? || tables ^ no_tables or
261
+ raise Error, "--tables and --no-tables options are exclusive"
262
+ select = tables ? :tables : (no_tables ? :no_tables : :all)
263
+ from, to = args.expect(0..2)
264
+ program.diff(from, to, mark, select)
265
+
266
+ when :migrate
267
+ raise NotYet
268
+
260
269
  when :prepare
261
- cmd = opts.prepare.subcommand || :release
270
+ cmd = opts.prepare!.subcommand || :release
262
271
  case cmd
263
- when :release; args.expect(0); program.prepare_release
264
- when :feature; raise NotYet
265
- when :migration; program.prepare_migration(args.expect(1))
272
+ when :release; program.prepare_release(args.expect(0..1))
273
+ when :feature; program.prepare_feature(args.expect(1))
274
+ when :migration; program.prepare_migration(args.expect(0..1))
266
275
  when :schema; program.prepare_schema(args.expect(1))
267
276
  when :diff; program.prepare_diff(args.expect(0..1))
268
277
  else
@@ -270,7 +279,7 @@ begin
270
279
  end
271
280
 
272
281
  when :include
273
- cmd = opts.include.subcommand || :feature
282
+ cmd = opts.include!.subcommand || :feature
274
283
  case cmd
275
284
  when :feature; program.include_feature(args.expect(1))
276
285
  else
@@ -282,7 +291,7 @@ begin
282
291
  program.check
283
292
 
284
293
  when :create
285
- cmd = opts.create.subcommand || :release
294
+ cmd = opts.create!.subcommand || :release
286
295
  case cmd
287
296
  when :release; program.create_release(args.expect(0..1))
288
297
  when :prerelease; program.create_prerelease(args.expect(0..1))
@@ -292,10 +301,20 @@ begin
292
301
  end
293
302
 
294
303
  when :cancel
295
- cmd = opts.cancel.subcommand
304
+ cmd = opts.cancel!.subcommand
296
305
  case cmd
297
306
  when :release; program.cancel_release(args.expect(1))
298
- when nil; raise Prick::Error, "'cancel' subcommand require a release argument"
307
+ when nil; raise Prick::Error, "'cancel' subcommand requires a release argument"
308
+ else
309
+ raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
310
+ end
311
+
312
+ when :generate
313
+ cmd = opts.generate!.subcommand
314
+ case cmd
315
+ when :schema; program.generate_schema
316
+ when :migration; program.generate_migration
317
+ when nil; raise Prick::Error, "'generate' subcommand requires a 'schema' or 'migration' argument"
299
318
  else
300
319
  raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
301
320
  end
@@ -319,3 +338,56 @@ rescue Prick::Error => ex
319
338
  ShellOpts.error(ex.message)
320
339
  end
321
340
 
341
+ __END__
342
+
343
+ # Awaits support for sections in ShellOpts
344
+ HELP = %(
345
+ OPTIONS
346
+ -n, --name=NAME
347
+ -C, --directory=DIR
348
+ -h, --help
349
+ -v, --verbose
350
+ --version
351
+
352
+ COMMANDS
353
+ INITIALIZATION
354
+ init --user=USER [DIR]
355
+
356
+ INFO COMMANDS
357
+ info
358
+ list releases --migrations --cancelled
359
+ list migrations
360
+ list upgrades --all
361
+
362
+ BUILDING
363
+ build -d DATABASE -C --nocache [TAG]
364
+ make -d DATABASE -C --nocache [TAG]
365
+ make clean -a
366
+ load -d DATABASE VERSION|FILE
367
+ save VERSION [FILE]
368
+ drop --all [DATABASE]
369
+ diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
370
+ migrate
371
+
372
+ PREPARING RELEASES
373
+ prepare release [FORK]
374
+ prepare feature NAME
375
+ prepare migration FROM
376
+ prepare schema NAME
377
+ prepare diff [VERSION]
378
+ include feature FEATURE
379
+ check
380
+
381
+ CREATING RELEASES
382
+ create release [RELEASE]
383
+ create prerelease RELEASE
384
+ create feature NAME
385
+ cancel release RELEASE
386
+
387
+ DEPLOYING RELEASES
388
+ generate migration
389
+ generate schema
390
+ upgrade
391
+ backup [FILE]
392
+ restore [FILE]
393
+ )