1*b4759e5fSTomasz Sapetaimport { Command } from '@expo/commander'; 2*b4759e5fSTomasz Sapetaimport chalk from 'chalk'; 3*b4759e5fSTomasz Sapetaimport { hashElement } from 'folder-hash'; 4*b4759e5fSTomasz Sapetaimport path from 'path'; 5*b4759e5fSTomasz Sapetaimport process from 'process'; 6*b4759e5fSTomasz Sapeta 7*b4759e5fSTomasz Sapetaimport { podInstallAsync } from '../CocoaPods'; 8*b4759e5fSTomasz Sapetaimport { EXPO_DIR } from '../Constants'; 9*b4759e5fSTomasz Sapetaimport logger from '../Logger'; 10*b4759e5fSTomasz Sapeta 11*b4759e5fSTomasz Sapetatype ActionOptions = { 12*b4759e5fSTomasz Sapeta force: boolean; 13*b4759e5fSTomasz Sapeta verbose: boolean; 14*b4759e5fSTomasz Sapeta}; 15*b4759e5fSTomasz Sapeta 16*b4759e5fSTomasz Sapetaasync function action(options: ActionOptions) { 17*b4759e5fSTomasz Sapeta if (process.platform !== 'darwin') { 18*b4759e5fSTomasz Sapeta throw new Error('This command is not supported on this platform.'); 19*b4759e5fSTomasz Sapeta } 20*b4759e5fSTomasz Sapeta 21*b4759e5fSTomasz Sapeta for (const relativeProjectPath of ['ios', 'apps/bare-expo/ios']) { 22*b4759e5fSTomasz Sapeta const absoluteProjectPath = path.join(EXPO_DIR, relativeProjectPath); 23*b4759e5fSTomasz Sapeta const podfileLockHash = await md5(path.join(absoluteProjectPath, 'Podfile.lock')); 24*b4759e5fSTomasz Sapeta const manifestLockHash = await md5(path.join(absoluteProjectPath, 'Pods/Manifest.lock')); 25*b4759e5fSTomasz Sapeta 26*b4759e5fSTomasz Sapeta if (!manifestLockHash || podfileLockHash !== manifestLockHash || options.force) { 27*b4759e5fSTomasz Sapeta logger.info(` Installing pods in ${chalk.yellow(relativeProjectPath)} directory`); 28*b4759e5fSTomasz Sapeta 29*b4759e5fSTomasz Sapeta try { 30*b4759e5fSTomasz Sapeta await podInstallAsync(absoluteProjectPath, { 31*b4759e5fSTomasz Sapeta stdio: options.verbose ? 'inherit' : 'pipe', 32*b4759e5fSTomasz Sapeta }); 33*b4759e5fSTomasz Sapeta } catch (e) { 34*b4759e5fSTomasz Sapeta if (!options.verbose) { 35*b4759e5fSTomasz Sapeta // In this case, the output has already been printed. 36*b4759e5fSTomasz Sapeta logger.error(` Installation failed with output: ${e.output}`); 37*b4759e5fSTomasz Sapeta } 38*b4759e5fSTomasz Sapeta return; 39*b4759e5fSTomasz Sapeta } 40*b4759e5fSTomasz Sapeta } 41*b4759e5fSTomasz Sapeta } 42*b4759e5fSTomasz Sapeta logger.success(' All iOS projects have up-to-date local pods'); 43*b4759e5fSTomasz Sapeta} 44*b4759e5fSTomasz Sapeta 45*b4759e5fSTomasz Sapetaasync function md5(path: string): Promise<string | null> { 46*b4759e5fSTomasz Sapeta try { 47*b4759e5fSTomasz Sapeta const { hash } = await hashElement(path, { 48*b4759e5fSTomasz Sapeta algo: 'md5', 49*b4759e5fSTomasz Sapeta encoding: 'hex', 50*b4759e5fSTomasz Sapeta files: { 51*b4759e5fSTomasz Sapeta ignoreBasename: true, 52*b4759e5fSTomasz Sapeta ignoreRootName: true, 53*b4759e5fSTomasz Sapeta }, 54*b4759e5fSTomasz Sapeta }); 55*b4759e5fSTomasz Sapeta return hash; 56*b4759e5fSTomasz Sapeta } catch { 57*b4759e5fSTomasz Sapeta return null; 58*b4759e5fSTomasz Sapeta } 59*b4759e5fSTomasz Sapeta} 60*b4759e5fSTomasz Sapeta 61*b4759e5fSTomasz Sapetaexport default (program: Command) => { 62*b4759e5fSTomasz Sapeta program 63*b4759e5fSTomasz Sapeta .command('pod-install') 64*b4759e5fSTomasz Sapeta .alias('pods') 65*b4759e5fSTomasz Sapeta .description('Installs pods in the directories where they are not in-sync') 66*b4759e5fSTomasz Sapeta .option('-f, --force', 'Whether to force installing pods in all projects.', false) 67*b4759e5fSTomasz Sapeta .option('-v, --verbose', 'Whether to inherit logs from `pod install` command.', false) 68*b4759e5fSTomasz Sapeta .asyncAction(action); 69*b4759e5fSTomasz Sapeta}; 70