Skip to content

Commit 5b89deb

Browse files
committed
Add script to init a MacOS test app
1 parent bdc172e commit 5b89deb

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ node_modules/
44
dist/
55

66
*.tsbuildinfo
7+
8+
# Treading the MacOS app as ephemeral
9+
apps/macos-test-app

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"test": "npm test --workspace react-native-node-api --workspace cmake-rn --workspace gyp-to-cmake --workspace node-addon-examples",
2727
"bootstrap": "node --run build && npm run bootstrap --workspaces --if-present",
2828
"prerelease": "node --run build && npm run prerelease --workspaces --if-present",
29-
"release": "changeset publish"
29+
"release": "changeset publish",
30+
"init-macos-test-app": "node scripts/init-macos-test-app.ts"
3031
},
3132
"author": {
3233
"name": "Callstack",
@@ -64,6 +65,7 @@
6465
"globals": "^16.0.0",
6566
"prettier": "^3.6.2",
6667
"react-native": "0.81.4",
68+
"read-pkg": "^9.0.1",
6769
"tsx": "^4.20.5",
6870
"typescript": "^5.8.0",
6971
"typescript-eslint": "^8.38.0"

scripts/init-macos-test-app.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import assert from "node:assert/strict";
2+
import cp from "node:child_process";
3+
import fs from "node:fs";
4+
import path from "node:path";
5+
6+
const REACT_NATIVE_VERSION = "0.79.6";
7+
const ROOT_PATH = path.join(import.meta.dirname, "..");
8+
const APP_PATH = path.join(ROOT_PATH, "apps", "macos-test-app");
9+
const HOST_PACKAGE_PATH = path.join(ROOT_PATH, "packages", "host");
10+
11+
function exec(command: string, args: string[], options: cp.SpawnOptions = {}) {
12+
const { status } = cp.spawnSync(command, args, {
13+
stdio: "inherit",
14+
...options,
15+
});
16+
assert.equal(status, 0, `Failed to execute '${command}'`);
17+
}
18+
19+
async function deletePreviousApp() {
20+
if (fs.existsSync(APP_PATH)) {
21+
console.log("Deleting existing app directory");
22+
await fs.promises.rm(APP_PATH, { recursive: true, force: true });
23+
}
24+
}
25+
26+
async function initializeReactNativeTemplate() {
27+
console.log("Initializing community template");
28+
exec("npx", [
29+
"@react-native-community/cli",
30+
"init",
31+
"MacOSTestApp",
32+
"--skip-install",
33+
"--skip-git-init",
34+
// "--platform-name",
35+
// "react-native-macos",
36+
"--version",
37+
REACT_NATIVE_VERSION,
38+
"--directory",
39+
APP_PATH,
40+
]);
41+
42+
// Clean up
43+
const CLEANUP_PATHS = ["ios", "android", "__tests__"];
44+
45+
for (const cleanupPath of CLEANUP_PATHS) {
46+
await fs.promises.rm(path.join(APP_PATH, cleanupPath), {
47+
recursive: true,
48+
force: true,
49+
});
50+
}
51+
}
52+
53+
function installDependencies() {
54+
console.log("Installing dependencies");
55+
exec(
56+
"npm",
57+
[
58+
"install",
59+
"--save-dev",
60+
"--prefer-offline",
61+
"--install-links",
62+
"react-native-macos-init",
63+
path.relative(APP_PATH, HOST_PACKAGE_PATH),
64+
],
65+
{
66+
cwd: APP_PATH,
67+
},
68+
);
69+
}
70+
71+
function initializeReactNativeMacOSTemplate() {
72+
console.log("Initializing react-native-macos template");
73+
exec("npx", ["react-native-macos-init"], {
74+
cwd: APP_PATH,
75+
});
76+
}
77+
78+
async function patchPodfile() {
79+
console.log("Patching Podfile");
80+
// Patch Podfile as per https://github.com/microsoft/react-native-macos/issues/2723#issuecomment-3392930688
81+
const podfilePath = path.join(APP_PATH, "macos", "Podfile");
82+
const podfileContents = await fs.promises.readFile(podfilePath, "utf8");
83+
const unwantedLines = [
84+
"require_relative '../node_modules/react-native-macos/scripts/react_native_pods'",
85+
"require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'",
86+
"require_relative '../node_modules/react-native-macos/scripts/cocoapods/autolinking'",
87+
];
88+
const podfilePatched = [
89+
"require_relative '../node_modules/react-native-macos/scripts/cocoapods/autolinking'",
90+
...podfileContents
91+
.split("\n")
92+
.filter((line) => !unwantedLines.includes(line)),
93+
];
94+
95+
await fs.promises.writeFile(podfilePath, podfilePatched.join("\n"), "utf8");
96+
}
97+
98+
function installCocoapods() {
99+
console.log("Installing cocoapods");
100+
exec("pod", ["install", "--project-directory=macos"], {
101+
cwd: APP_PATH,
102+
});
103+
}
104+
105+
await deletePreviousApp();
106+
await initializeReactNativeTemplate();
107+
installDependencies();
108+
initializeReactNativeMacOSTemplate();
109+
await patchPodfile();
110+
installCocoapods();

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
},
77
"files": ["prettier.config.js", "eslint.config.js"],
88
"references": [
9+
{ "path": "./tsconfig.scripts.json" },
910
{ "path": "./packages/cli-utils/tsconfig.json" },
1011
{ "path": "./packages/cmake-file-api/tsconfig.json" },
1112
{ "path": "./packages/cmake-file-api/tsconfig.tests.json" },

tsconfig.scripts.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "./configs/tsconfig.node.json",
3+
"compilerOptions": {
4+
"composite": true,
5+
"emitDeclarationOnly": true,
6+
"declarationMap": false,
7+
"rootDir": "scripts"
8+
},
9+
"include": ["scripts"]
10+
}

0 commit comments

Comments
 (0)