18d307f52SEvan Baconimport spawnAsync from '@expo/spawn-async'; 28d307f52SEvan Baconimport chalk from 'chalk'; 38d307f52SEvan Bacon 4814b6fafSEvan Baconimport { env } from './env'; 529128565SEvan Baconimport { isInteractive } from './interactive'; 68d307f52SEvan Baconimport { confirmAsync } from './prompts'; 7*8a424bebSJames Ideimport * as Log from '../log'; 88d307f52SEvan Bacon 98d307f52SEvan Baconexport async function maybeBailOnGitStatusAsync(): Promise<boolean> { 10814b6fafSEvan Bacon if (env.EXPO_NO_GIT_STATUS) { 118d307f52SEvan Bacon Log.warn( 128d307f52SEvan Bacon 'Git status is dirty but the command will continue because EXPO_NO_GIT_STATUS is enabled...' 138d307f52SEvan Bacon ); 148d307f52SEvan Bacon return false; 158d307f52SEvan Bacon } 168d307f52SEvan Bacon const isGitStatusClean = await validateGitStatusAsync(); 178d307f52SEvan Bacon 188d307f52SEvan Bacon // Give people a chance to bail out if git working tree is dirty 198d307f52SEvan Bacon if (!isGitStatusClean) { 2029128565SEvan Bacon if (!isInteractive()) { 218d307f52SEvan Bacon Log.warn( 228d307f52SEvan Bacon `Git status is dirty but the command will continue because the terminal is not interactive.` 238d307f52SEvan Bacon ); 248d307f52SEvan Bacon return false; 258d307f52SEvan Bacon } 268d307f52SEvan Bacon 278d307f52SEvan Bacon Log.log(); 288d307f52SEvan Bacon const answer = await confirmAsync({ 298d307f52SEvan Bacon message: `Would you like to proceed?`, 308d307f52SEvan Bacon }); 318d307f52SEvan Bacon 328d307f52SEvan Bacon if (!answer) { 338d307f52SEvan Bacon return true; 348d307f52SEvan Bacon } 358d307f52SEvan Bacon 368d307f52SEvan Bacon Log.log(); 378d307f52SEvan Bacon } 388d307f52SEvan Bacon return false; 398d307f52SEvan Bacon} 408d307f52SEvan Bacon 418d307f52SEvan Baconexport async function validateGitStatusAsync(): Promise<boolean> { 428d307f52SEvan Bacon let workingTreeStatus = 'unknown'; 438d307f52SEvan Bacon try { 448d307f52SEvan Bacon const result = await spawnAsync('git', ['status', '--porcelain']); 458d307f52SEvan Bacon workingTreeStatus = result.stdout === '' ? 'clean' : 'dirty'; 4698ecfc87SJames Ide } catch { 478d307f52SEvan Bacon // Maybe git is not installed? 488d307f52SEvan Bacon // Maybe this project is not using git? 498d307f52SEvan Bacon } 508d307f52SEvan Bacon 518d307f52SEvan Bacon if (workingTreeStatus === 'clean') { 528d307f52SEvan Bacon Log.log(`Your git working tree is ${chalk.green('clean')}`); 538d307f52SEvan Bacon Log.log('To revert the changes after this command completes, you can run the following:'); 548d307f52SEvan Bacon Log.log(' git clean --force && git reset --hard'); 558d307f52SEvan Bacon return true; 568d307f52SEvan Bacon } else if (workingTreeStatus === 'dirty') { 578d307f52SEvan Bacon Log.log(`${chalk.bold('Warning!')} Your git working tree is ${chalk.red('dirty')}.`); 588d307f52SEvan Bacon Log.log( 598d307f52SEvan Bacon `It's recommended to ${chalk.bold( 608d307f52SEvan Bacon 'commit all your changes before proceeding' 618d307f52SEvan Bacon )}, so you can revert the changes made by this command if necessary.` 628d307f52SEvan Bacon ); 638d307f52SEvan Bacon } else { 648d307f52SEvan Bacon Log.log("We couldn't find a git repository in your project directory."); 658d307f52SEvan Bacon Log.log("It's recommended to back up your project before proceeding."); 668d307f52SEvan Bacon } 678d307f52SEvan Bacon 688d307f52SEvan Bacon return false; 698d307f52SEvan Bacon} 70