diff --git a/packages/cli/src/commands/init/init.ts b/packages/cli/src/commands/init/init.ts index 7d5df4c6e..65b03f570 100644 --- a/packages/cli/src/commands/init/init.ts +++ b/packages/cli/src/commands/init/init.ts @@ -159,7 +159,7 @@ async function installDependencies({ }); if (process.platform === 'darwin') { - await installPods({projectName, loader, shouldUpdatePods: false}); + await installPods({projectName, loader}); } loader.succeed(); diff --git a/packages/cli/src/commands/upgrade/upgrade.ts b/packages/cli/src/commands/upgrade/upgrade.ts index 28faad31f..ea951bf0a 100644 --- a/packages/cli/src/commands/upgrade/upgrade.ts +++ b/packages/cli/src/commands/upgrade/upgrade.ts @@ -194,10 +194,7 @@ const installDeps = async (root: string, newVersion: string) => { } }; -const installCocoaPodsDeps = async ( - projectDir: string, - thirdPartyIOSDeps: Array, -) => { +const installCocoaPodsDeps = async (projectDir: string) => { if (process.platform === 'darwin') { try { logger.info( @@ -207,7 +204,6 @@ const installCocoaPodsDeps = async ( ); await installPods({ projectName: projectDir.split('/').pop() || '', - shouldUpdatePods: thirdPartyIOSDeps.length > 0, }); } catch (error) { if (error.stderr) { @@ -323,9 +319,6 @@ async function upgrade(argv: Array, ctx: Config) { projectDir, 'node_modules/react-native/package.json', )); - const thirdPartyIOSDeps = Object.values(ctx.dependencies).filter( - dependency => dependency.platforms.ios, - ); const newVersion = await getVersionToUpgradeTo( argv, @@ -346,7 +339,7 @@ async function upgrade(argv: Array, ctx: Config) { if (patch === '') { logger.info('Diff has no changes to apply, proceeding further'); await installDeps(projectDir, newVersion); - await installCocoaPodsDeps(projectDir, thirdPartyIOSDeps); + await installCocoaPodsDeps(projectDir); logger.success( `Upgraded React Native to v${newVersion} 🎉. Now you can review and commit the changes`, @@ -382,7 +375,7 @@ async function upgrade(argv: Array, ctx: Config) { } } else { await installDeps(projectDir, newVersion); - await installCocoaPodsDeps(projectDir, thirdPartyIOSDeps); + await installCocoaPodsDeps(projectDir); logger.info('Running "git status" to check what changed...'); await execa('git', ['status'], {stdio: 'inherit'}); } diff --git a/packages/cli/src/tools/installPods.ts b/packages/cli/src/tools/installPods.ts index 0b991b9ec..2fa8abfa5 100644 --- a/packages/cli/src/tools/installPods.ts +++ b/packages/cli/src/tools/installPods.ts @@ -15,7 +15,44 @@ type PromptCocoaPodsInstallation = { promptQuestion: string; }; -async function updatePods(loader: ora.Ora) { +async function runPodInstall( + loader: ora.Ora, + projectName: string, + shouldHandleRepoUpdate: boolean = true, +) { + try { + loader.start( + `Installing CocoaPods dependencies ${chalk.dim( + '(this may take a few minutes)', + )}`, + ); + await execa('pod', ['install']); + } catch (error) { + // "pod" command outputs errors to stdout (at least some of them) + const stderr = error.stderr || error.stdout; + + /** + * If CocoaPods failed due to repo being out of date, it will + * include the update command in the error message. + * + * `shouldHandleRepoUpdate` will be set to `false` to + * prevent infinite loop (unlikely scenario) + */ + if (stderr.includes('pod repo update') && shouldHandleRepoUpdate) { + await runPodUpdate(loader); + await runPodInstall(loader, projectName, false); + } else { + loader.fail(); + throw new Error( + `Failed to install CocoaPods dependencies for iOS project, which is required by this template.\nPlease try again manually: "cd ./${projectName}/ios && pod install".\nCocoaPods documentation: ${chalk.dim.underline( + 'https://cocoapods.org/', + )}`, + ); + } + } +} + +async function runPodUpdate(loader: ora.Ora) { try { loader.start( `Updating CocoaPods repositories ${chalk.dim( @@ -127,11 +164,9 @@ async function installCocoaPods(loader: ora.Ora) { async function installPods({ projectName, loader, - shouldUpdatePods, }: { projectName: string; loader?: ora.Ora; - shouldUpdatePods?: boolean; }) { loader = loader || new NoopLoader(); try { @@ -157,27 +192,7 @@ async function installPods({ await installCocoaPods(loader); } - if (shouldUpdatePods) { - await updatePods(loader); - } - - try { - loader.start( - `Installing CocoaPods dependencies ${chalk.dim( - '(this may take a few minutes)', - )}`, - ); - await execa('pod', ['install']); - } catch (error) { - // "pod" command outputs errors to stdout (at least some of them) - logger.log(error.stderr || error.stdout); - - throw new Error( - `Failed to install CocoaPods dependencies for iOS project, which is required by this template.\nPlease try again manually: "cd ./${projectName}/ios && pod install".\nCocoaPods documentation: ${chalk.dim.underline( - 'https://cocoapods.org/', - )}`, - ); - } + await runPodInstall(loader, projectName); } catch (error) { throw error; } finally {