@@ -315,6 +315,43 @@ const MIGRATIONS = [
315315 } ,
316316] ;
317317
318+ // ---------------------------------------------------------------------------
319+ // Migration markers
320+ // ---------------------------------------------------------------------------
321+
322+ const MARKER_DIR = '.dialtone-migrations' ;
323+
324+ function getRepoRoot ( cwd ) {
325+ try {
326+ return execFileSync ( 'git' , [ 'rev-parse' , '--show-toplevel' ] , {
327+ cwd,
328+ encoding : 'utf8' ,
329+ stdio : [ 'ignore' , 'pipe' , 'ignore' ] ,
330+ } ) . trim ( ) ;
331+ } catch {
332+ return cwd ;
333+ }
334+ }
335+
336+ function markerPath ( cwd , id ) {
337+ return path . join ( getRepoRoot ( cwd ) , MARKER_DIR , id ) ;
338+ }
339+
340+ async function checkMigrationMarker ( cwd , id ) {
341+ try {
342+ await fs . access ( markerPath ( cwd , id ) ) ;
343+ return true ;
344+ } catch {
345+ return false ;
346+ }
347+ }
348+
349+ async function writeMigrationMarker ( cwd , id ) {
350+ const p = markerPath ( cwd , id ) ;
351+ await fs . mkdir ( path . dirname ( p ) , { recursive : true } ) ;
352+ await fs . writeFile ( p , '' , 'utf8' ) ;
353+ }
354+
318355// ---------------------------------------------------------------------------
319356// CLI parsing
320357// ---------------------------------------------------------------------------
@@ -749,17 +786,33 @@ async function runStandaloneMigration (migration, opts) {
749786 } ) ;
750787
751788 child . on ( 'close' , code => {
752- // Exit code 0 means success (or nothing to do)
753- resolve ( { exitCode : code } ) ;
789+ if ( code !== 0 ) {
790+ reject ( new Error ( `child process exited with code ${ code } ` ) ) ;
791+ } else {
792+ resolve ( { exitCode : code } ) ;
793+ }
754794 } ) ;
755795
756796 child . on ( 'error' , reject ) ;
757797 } ) ;
758798}
759799
760800async function runMigration ( migration , opts ) {
801+ if ( migration . id === 'color-stops' && ! opts . dryRun ) {
802+ if ( await checkMigrationMarker ( opts . cwd , migration . id ) ) {
803+ console . log ( ` ✓ Already applied on this branch (${ path . join ( getRepoRoot ( opts . cwd ) , MARKER_DIR , migration . id ) } exists). Skipping.\n` ) ;
804+ console . log ( ` Remove that file to re-run.\n` ) ;
805+ return { skipped : true } ;
806+ }
807+ }
808+
761809 if ( migration . type === 'config' ) {
762- return runConfigMigration ( migration , opts ) ;
810+ const result = await runConfigMigration ( migration , opts ) ;
811+ if ( migration . id === 'color-stops' && result . applied ) {
812+ await writeMigrationMarker ( opts . cwd , migration . id ) ;
813+ console . log ( ` Marker written to ${ path . join ( getRepoRoot ( opts . cwd ) , MARKER_DIR , migration . id ) } — commit this file with your changes.\n` ) ;
814+ }
815+ return result ;
763816 }
764817
765818 if ( migration . type === 'standalone' ) {
0 commit comments