Skip to content

use pod installed by bundler if possible #2669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/cli-config-apple/src/tools/installPods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
runSudo,
} from '@react-native-community/cli-tools';
import runBundleInstall from './runBundleInstall';
import {execaPod} from './pods';

interface PodInstallOptions {
skipBundleInstall?: boolean;
Expand All @@ -31,7 +32,7 @@ async function runPodInstall(loader: Ora, options: RunPodInstallOptions) {
)} ${chalk.dim('(this may take a few minutes)')}`,
);

await execa('bundle', ['exec', 'pod', 'install'], {
await execaPod(['install'], {
env: {
RCT_NEW_ARCH_ENABLED: options?.newArchEnabled ? '1' : '0',
RCT_IGNORE_PODS_DEPRECATION: '1', // From React Native 0.79 onwards, users shouldn't install CocoaPods manually.
Expand Down Expand Up @@ -77,7 +78,7 @@ async function runPodUpdate(loader: Ora) {
'(this may take a few minutes)',
)}`,
);
await execa('pod', ['repo', 'update']);
await execaPod(['repo', 'update']);
} catch (error) {
// "pod" command outputs errors to stdout (at least some of them)
logger.log((error as any).stderr || (error as any).stdout);
Expand Down Expand Up @@ -151,7 +152,7 @@ async function installPods(loader?: Ora, options?: PodInstallOptions) {
// Check if "pod" is available and usable. It happens that there are
// multiple versions of "pod" command and even though it's there, it exits
// with a failure
await execa('pod', ['--version']);
await execaPod(['--version']);
} catch (e) {
loader.info();
await installCocoaPods(loader);
Expand Down
21 changes: 21 additions & 0 deletions packages/cli-config-apple/src/tools/pods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@react-native-community/cli-types';
import {ApplePlatform} from '../types';
import runCodegen from './runCodegen';
import execa from 'execa';

interface ResolvePodsOptions {
forceInstall?: boolean;
Expand Down Expand Up @@ -214,3 +215,23 @@ export default async function resolvePods(
}
}
}

export async function execaPod(args: string[], options?: execa.Options) {
let podType: 'system' | 'bundle' = 'system';
try {
await execa('bundle', ['exec', 'pod', '--version'], options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be quicker to run bundle show cocoapods. That way it doesn't need to initialise cocoapods, it just asks bundler if it can resolve it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether it remains as an bundle exec pod --version or becomes a bundle show cocoapods;

Does this need to be more robust?

I'm asking because currently, it'd fail if bundle install hasn't been run and would then fall back to the system pod even if it's meant to be using bundler.

If the first command fails you could potentially check the output of bundle check to see if cocoapods is listed as a missing gem?

But, this may be more complex than it needs to be? I'll defer to a project maintainer on that one. 😄

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm asking because currently, it'd fail if bundle install hasn't been run and would then fall back to the system pod even if it's meant to be using bundler.

Nice catch. This would move more users to installing cocoapods globally, but it seems this is not the intended way since the template that is used by the cli is installing cocoapods with bundler anyway (https://github.com/react-native-community/template/blob/main/template/Gemfile#L7).

It would be a breaking change in but I would love to have only the bundler way.

podType = 'bundle';
} catch (bundledPodError) {
try {
await execa('pod', ['--version'], options);
podType = 'system';
} catch (systemPodError) {
throw new Error('cocoapods not installed');
}
}

if (podType === 'bundle') {
return execa('bundle', ['exec', 'pod', ...args], options);
}
return execa('pod', args, options);
}