Skip to content

Commit 0b01fd5

Browse files
committed
Re-use existing build phase
1 parent 68e45f0 commit 0b01fd5

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

packages/host/src/node/cli/apple.ts

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as xcode from "@bacons/xcode";
77
import * as xcodeJson from "@bacons/xcode/json";
88
import * as zod from "zod";
99

10-
import { chalk, spawn } from "@react-native-node-api/cli-utils";
10+
import { chalk, prettyPath, spawn } from "@react-native-node-api/cli-utils";
1111

1212
import { getLibraryName } from "../path-utils.js";
1313
import {
@@ -42,37 +42,73 @@ export async function ensureXcodeBuildPhase(fromPath: string) {
4242
target.props.productType === "com.apple.product-type.application",
4343
);
4444

45+
let saveProject = false;
46+
4547
for (const target of applicationTargets) {
4648
console.log(`Patching '${target.getDisplayName()}' target`);
4749

4850
const existingBuildPhases = target.props.buildPhases.filter((phase) =>
4951
phase.getDisplayName().startsWith(BUILD_PHASE_PREFIX),
5052
);
5153

54+
const shellScript = [
55+
"set -e",
56+
`'${process.execPath}' '${CLI_PATH}' link --apple '${fromPath}'`,
57+
].join("\n");
58+
59+
let foundBuildPhase = false;
60+
5261
for (const existingBuildPhase of existingBuildPhases) {
53-
console.log(
54-
"Removing existing build phase:",
55-
chalk.dim(existingBuildPhase.getDisplayName()),
56-
);
57-
existingBuildPhase.removeFromProject();
62+
if (
63+
xcode.PBXShellScriptBuildPhase.is(existingBuildPhase) &&
64+
existingBuildPhase.getDisplayName() === BUILD_PHASE_NAME
65+
) {
66+
if (existingBuildPhase.props.shellScript === shellScript) {
67+
console.log("Found existing build phase with the same shell script");
68+
foundBuildPhase = true;
69+
} else {
70+
console.log(
71+
"Updating existing build phase with the new shell script",
72+
);
73+
existingBuildPhase.props.shellScript = shellScript;
74+
foundBuildPhase = true;
75+
saveProject = true;
76+
}
77+
} else {
78+
// We're expecting no other build phases with this prefix
79+
console.log(
80+
"Removing existing build phase:",
81+
chalk.dim(existingBuildPhase.getDisplayName()),
82+
);
83+
existingBuildPhase.removeFromProject();
84+
}
5885
}
5986

60-
// TODO: Declare input and output files to prevent unnecessary runs
61-
62-
target.createBuildPhase(xcode.PBXShellScriptBuildPhase, {
63-
name: BUILD_PHASE_NAME,
64-
shellScript: [
65-
"set -e",
66-
`'${process.execPath}' '${CLI_PATH}' link --apple '${fromPath}'`,
67-
].join("\n"),
68-
});
87+
if (!foundBuildPhase) {
88+
console.log("Adding new build phase");
89+
// TODO: Consider declaring input and output files to prevent unnecessary runs
90+
target.createBuildPhase(xcode.PBXShellScriptBuildPhase, {
91+
name: BUILD_PHASE_NAME,
92+
shellScript,
93+
});
94+
saveProject = true;
95+
}
6996
}
7097

71-
await fs.promises.writeFile(
72-
pbxprojPath,
73-
xcodeJson.build(xcodeProject.toJSON()),
74-
"utf8",
75-
);
98+
if (saveProject) {
99+
console.log("Saving Xcode project", prettyPath(pbxprojPath));
100+
await fs.promises.writeFile(
101+
pbxprojPath,
102+
xcodeJson.build(xcodeProject.toJSON()),
103+
"utf8",
104+
);
105+
} else {
106+
console.log(
107+
"Skipped saving Xcode project",
108+
prettyPath(pbxprojPath),
109+
chalk.dim("(no changes were made)"),
110+
);
111+
}
76112
}
77113

78114
/**

0 commit comments

Comments
 (0)