diff --git a/.nx/version-plans/fix-devicectl-launch-args.md b/.nx/version-plans/fix-devicectl-launch-args.md new file mode 100644 index 0000000..78985de --- /dev/null +++ b/.nx/version-plans/fix-devicectl-launch-args.md @@ -0,0 +1,5 @@ +--- +__default__: patch +--- + +Physical iOS app launches now pass Harness launch arguments to `xcrun devicectl` without breaking JSON output collection. This prevents app launch arguments from being misinterpreted as `devicectl` flags and keeps device launches working when custom arguments are provided. diff --git a/packages/platform-ios/src/__tests__/launch-options.test.ts b/packages/platform-ios/src/__tests__/launch-options.test.ts index 955ab29..0800bdd 100644 --- a/packages/platform-ios/src/__tests__/launch-options.test.ts +++ b/packages/platform-ios/src/__tests__/launch-options.test.ts @@ -35,6 +35,7 @@ describe('Apple app launch options', () => { '--environment-variables', '{"FEATURE_X":"1"}', 'com.example.app', + '--', '--mode=test', '--retry=1', ]); diff --git a/packages/platform-ios/src/xcrun/devicectl.ts b/packages/platform-ios/src/xcrun/devicectl.ts index bc3ddff..2bbd0b0 100644 --- a/packages/platform-ios/src/xcrun/devicectl.ts +++ b/packages/platform-ios/src/xcrun/devicectl.ts @@ -10,15 +10,27 @@ export const devicectl = async ( args: string[] ): Promise => { const tempFile = join(tmpdir(), `devicectl-${randomUUID()}.json`); + const separatorIndex = args.indexOf('--'); + const argsWithJsonOutput = + separatorIndex === -1 + ? [...args, '--json-output', tempFile] + : [ + ...args.slice(0, separatorIndex), + '--json-output', + tempFile, + ...args.slice(separatorIndex), + ]; await spawn('xcrun', [ 'devicectl', command, - ...args, - '--json-output', - tempFile, + ...argsWithJsonOutput, ]); + if (!fs.existsSync(tempFile)) { + throw new Error(`devicectl did not produce JSON output at ${tempFile}`); + } + const output = fs.readFileSync(tempFile, 'utf8'); fs.unlinkSync(tempFile); @@ -106,7 +118,11 @@ export const getDeviceCtlLaunchArgs = ( args.push('--environment-variables', JSON.stringify(environment)); } - args.push(bundleId, ...(options?.arguments ?? [])); + args.push(bundleId); + + if (options?.arguments?.length) { + args.push('--', ...options.arguments); + } return args; };