Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- fix(react-native): Do not change the Podfile or run `pod install` when the iOS project uses Swift Package Manager ([#1386](https://github.com/getsentry/sentry-wizard/pull/1386))

## 9.1.0

- feat(sourcemaps): Import the Vite, webpack, Rollup and esbuild plugins from the installed SDK (`@sentry/node`, `@sentry/nestjs`, `@sentry/aws-serverless`) on v11, or install `@sentry/bundler-plugins` as a dev dependency and import from `@sentry/bundler-plugins/<bundler>` ([#1382](https://github.com/getsentry/sentry-wizard/pull/1382))
Expand Down
41 changes: 30 additions & 11 deletions src/react-native/react-native-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
findDebugFilesUploadPhase,
getValidExistingBuildPhases,
patchBundlePhase,
usesSwiftPMAutolinking,
writeXcodeProject,
} from './xcode';

Expand Down Expand Up @@ -349,20 +350,38 @@ async function patchXcodeFiles(config: RNCliSetupConfigContent) {
gitignore: false,
});

// The RNSentry pod is a Swift pod and requires `use_modular_headers!` in the
// Podfile to integrate as a static library. Patch it before `pod install` so
// the install succeeds now and any later manual `pod install` keeps working.
if (usesCocoaPod('ios')) {
traceStep('add-modular-headers', () => addModularHeaders('ios'));
}

if (platform() === 'darwin' && (await confirmPodInstall())) {
await traceStep('pod-install', () => podInstall('ios'));
}

const xcodeProjectPath = traceStep('find-xcode-project', () =>
getFirstMatchedPath(XCODE_PROJECT),
);

// `react-native spm add --deintegrate` keeps a Podfile that `pod install`
// cannot parse.
const usesSwiftPM =
!!xcodeProjectPath && usesSwiftPMAutolinking(xcodeProjectPath);
Sentry.setTag(
'ios-dependency-manager',
usesSwiftPM ? 'swiftpm' : 'cocoapods',
);

if (usesSwiftPM) {
clack.log.info(
`The iOS project uses Swift Package Manager. The wizard does not change the ${chalk.cyan(
'Podfile',
)} and does not run ${chalk.cyan('pod install')}.`,
);
} else {
// The RNSentry pod is a Swift pod and requires `use_modular_headers!` in the
// Podfile to integrate as a static library. Patch it before `pod install` so
// the install succeeds now and any later manual `pod install` keeps working.
if (usesCocoaPod('ios')) {
traceStep('add-modular-headers', () => addModularHeaders('ios'));
}

if (platform() === 'darwin' && (await confirmPodInstall())) {
await traceStep('pod-install', () => podInstall('ios'));
}
}

Sentry.setTag(
'xcode-project-status',
xcodeProjectPath ? 'found' : 'not-found',
Expand Down
11 changes: 11 additions & 0 deletions src/react-native/xcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ export function findDebugFilesUploadPhase(
});
}

// React Native SwiftPM autolinking adds a local package at this path.
export function usesSwiftPMAutolinking(xcodeProjectPath: string): boolean {
try {
return /relativePath = "?build\/generated\/autolinking"?;/.test(
fs.readFileSync(xcodeProjectPath, 'utf-8'),
);
} catch {
return false;
}
}

export function writeXcodeProject(
xcodeProjectPath: string,
xcodeProject: Project,
Expand Down
36 changes: 36 additions & 0 deletions test/react-native/xcode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
findBundlePhase,
findDebugFilesUploadPhase,
ErrorPatchSnippet,
usesSwiftPMAutolinking,
} from '../../src/react-native/xcode';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import chalk from 'chalk';
import { makeCodeSnippet } from '../../src/utils/clack';
// @ts-expect-error - clack is ESM and TS complains about that. It works though
Expand Down Expand Up @@ -435,4 +439,36 @@ sentry-cli upload-dsym path/to/dsym --include-sources
expect(findDebugFilesUploadPhase(input)).toBeUndefined();
});
});

describe('usesSwiftPMAutolinking', () => {
const writeProject = (content: string) => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-xcode-project'));
const projectPath = path.join(dir, 'project.pbxproj');
fs.writeFileSync(projectPath, content);
return projectPath;
};

it('returns true for a project with the autolinking package', () => {
const projectPath =
writeProject(`/* Begin XCLocalSwiftPackageReference section */
C2FECF1430FDAAE3BF355839 /* XCLocalSwiftPackageReference "build/generated/autolinking" */ = {isa = XCLocalSwiftPackageReference; relativePath = build/generated/autolinking;};
/* End XCLocalSwiftPackageReference section */`);

expect(usesSwiftPMAutolinking(projectPath)).toBe(true);
});

it('returns false for a CocoaPods project', () => {
const projectPath = writeProject(
`shellScript = "\"\${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";`,
);

expect(usesSwiftPMAutolinking(projectPath)).toBe(false);
});

it('returns false if the project file does not exist', () => {
expect(
usesSwiftPMAutolinking(path.join(os.tmpdir(), 'missing.pbxproj')),
).toBe(false);
});
});
});
Loading