prick 0.3.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ )