@@ -8,12 +8,14 @@ import { createAdapterFromUrl } from './adapter'
88import { getHead } from './git'
99import { addGitHook , HookAlreadyFoundError } from './git'
1010import {
11+ CLI_LOGGER ,
1112 createConfig ,
1213 createMigrationDir ,
1314 generate ,
1415 getConfigurationForCommit ,
1516 getStatus ,
1617 isMerkelRepository ,
18+ PendingMigrationFoundError ,
1719 prepareCommitMsg ,
1820} from './index'
1921import { Migration , Task , TaskType } from './migration'
@@ -133,12 +135,12 @@ yargs.command(
133135 when : ( ) => ! ! argv . db ,
134136 } ,
135137 ] )
136- if ( await createMigrationDir ( migrationDir as string ) ) {
137- process . stdout . write ( `Created ${ chalk . cyan ( migrationDir as string ) } \n` )
138+ if ( await createMigrationDir ( migrationDir ) ) {
139+ process . stdout . write ( `Created ${ chalk . cyan ( migrationDir ) } \n` )
138140 }
139141 await createConfig ( {
140- migrationDir : migrationDir as string ,
141- migrationOutDir : ( migrationOutDir as string ) || './migrations' ,
142+ migrationDir,
143+ migrationOutDir : migrationOutDir || './migrations' ,
142144 } )
143145 process . stdout . write ( `Created ${ chalk . cyan ( path . join ( '.' , '.merkelrc.json' ) ) } \n` )
144146 if ( initMetaNow ) {
@@ -249,6 +251,8 @@ yargs.command(
249251 const adapter = createAdapterFromUrl ( argv . db ! )
250252 await adapter . init ( )
251253 const head = await getHead ( )
254+ // wait for current migration to finish
255+ await adapter . waitForPending ( CLI_LOGGER )
252256 const status = await getStatus ( adapter , head )
253257 process . stdout . write ( '\n' + status . toString ( ) )
254258 if ( status . newCommits . some ( commit => commit . tasks . length > 0 ) ) {
@@ -283,33 +287,62 @@ yargs.command(
283287 try {
284288 const adapter = createAdapterFromUrl ( argv . db ! )
285289 await adapter . init ( )
286- const head = await getHead ( )
287- const status = await getStatus ( adapter , head )
288- process . stdout . write ( status . toString ( ) )
289- if ( status . newCommits . some ( commit => commit . tasks . length > 0 ) ) {
290- if ( argv . confirm ) {
291- const answer = await inquirer . prompt < { continue : boolean } > ( {
292- type : 'confirm' ,
293- name : 'continue' ,
294- message : 'Continue?' ,
295- } )
296- if ( ! answer . continue ) {
297- process . exit ( 0 )
290+ while ( true ) {
291+ const head = await getHead ( )
292+ const status = await getStatus ( adapter , head )
293+ process . stdout . write ( status . toString ( ) )
294+ const tasks = status . newCommits . reduce < Task [ ] > ( ( prev , next ) => prev . concat ( next . tasks ) , [ ] )
295+ if ( tasks . length > 0 ) {
296+ if ( argv . confirm ) {
297+ const answer = await inquirer . prompt < { continue : boolean } > ( {
298+ type : 'confirm' ,
299+ name : 'continue' ,
300+ message : 'Continue?' ,
301+ } )
302+ if ( ! answer . continue ) {
303+ process . exit ( 0 )
304+ }
305+ process . stdout . write ( '\n' )
298306 }
299- process . stdout . write ( '\n' )
300- }
301- process . stdout . write ( 'Starting migration\n\n' )
302- for ( const commit of status . newCommits ) {
303- process . stdout . write ( `${ chalk . yellow ( commit . shortSha1 ) } ${ commit . subject } \n` )
304- for ( const task of commit . tasks ) {
305- process . stdout . write ( task . toString ( ) + ' ...' )
306- const interval = setInterval ( ( ) => process . stdout . write ( '.' ) , 100 )
307- await task . execute ( argv . migrationOutDir ! , adapter , head , commit )
308- clearInterval ( interval )
309- process . stdout . write ( ' Success\n' )
307+
308+ process . stdout . write ( 'Starting migration\n\n' )
309+
310+ const hasChanged = await adapter . waitForPending ( CLI_LOGGER )
311+
312+ if ( hasChanged ) {
313+ process . stdout . write ( 'The migrations have changed, reloading..\n\n' )
314+ continue
315+ }
316+ // create pending tasks
317+ for ( const task of tasks ) {
318+ try {
319+ task . head = head
320+ await adapter . beginMigrationTask ( task )
321+ } catch ( error ) {
322+ if ( error instanceof PendingMigrationFoundError ) {
323+ continue
324+ } else {
325+ throw error
326+ }
327+ }
310328 }
329+
330+ for ( const commit of status . newCommits ) {
331+ process . stdout . write ( `${ chalk . yellow ( commit . shortSha1 ) } ${ commit . subject } \n` )
332+ for ( const task of commit . tasks ) {
333+ process . stdout . write ( task . toString ( ) + ' ...' )
334+ const interval = setInterval ( ( ) => process . stdout . write ( '.' ) , 100 )
335+ try {
336+ await task . execute ( argv . migrationOutDir ! , adapter , head , commit )
337+ } finally {
338+ clearInterval ( interval )
339+ }
340+ process . stdout . write ( ' Success\n' )
341+ }
342+ }
343+ process . stdout . write ( chalk . green ( '\nAll migrations successful\n' ) )
311344 }
312- process . stdout . write ( chalk . green ( '\nAll migrations successful\n' ) )
345+ break
313346 }
314347 process . exit ( 0 )
315348 } catch ( err ) {
@@ -328,13 +361,29 @@ const migrationCommand = (type: TaskType) => async (argv: MigrationCommandArgv)
328361 try {
329362 const adapter = createAdapterFromUrl ( argv . db ! )
330363 await adapter . init ( )
331- const head = await getHead ( )
332- for ( const name of argv . migrations ! ) {
333- const task = new Task ( { type, migration : new Migration ( name ) } )
364+ const tasks = argv . migrations ! . map ( name => new Task ( { type, migration : new Migration ( name ) } ) )
365+ while ( true ) {
366+ await adapter . waitForPending ( CLI_LOGGER )
367+ const head = await getHead ( )
368+ for ( const task of tasks ) {
369+ try {
370+ task . head = head
371+ await adapter . beginMigrationTask ( task )
372+ } catch ( error ) {
373+ if ( error instanceof PendingMigrationFoundError ) {
374+ continue
375+ } else {
376+ throw error
377+ }
378+ }
379+ }
380+ break
381+ }
382+ for ( const task of tasks ) {
334383 process . stdout . write ( `${ task . toString ( ) } ...` )
335384 const interval = setInterval ( ( ) => process . stdout . write ( '.' ) , 100 )
336385 try {
337- await task . execute ( argv . migrationOutDir ! , adapter , head )
386+ await task . execute ( argv . migrationOutDir ! , adapter )
338387 } finally {
339388 clearInterval ( interval )
340389 }
0 commit comments