Skip to content

Commit 1aa4d95

Browse files
committed
Restore Headers symlink too
1 parent 1b2b93b commit 1aa4d95

File tree

3 files changed

+59
-45
lines changed

3 files changed

+59
-45
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
readAndParsePlist,
1010
readFrameworkInfo,
1111
readXcframeworkInfo,
12-
restoreFrameworkLinks,
12+
restoreVersionedFrameworkSymlinks,
1313
} from "./apple";
1414
import { setupTempDirectory } from "../test-utils";
1515

@@ -269,7 +269,7 @@ describe("apple", { skip: process.platform !== "darwin" }, () => {
269269
});
270270
});
271271

272-
describe("restoreFrameworkLinks", () => {
272+
describe("restoreVersionedFrameworkSymlinks", () => {
273273
it("restores a versioned framework", async (context) => {
274274
const infoPlistContents = `
275275
<?xml version="1.0" encoding="UTF-8"?>
@@ -335,11 +335,11 @@ describe("apple", { skip: process.platform !== "darwin" }, () => {
335335
);
336336
}
337337

338-
await restoreFrameworkLinks(frameworkPath);
338+
await restoreVersionedFrameworkSymlinks(frameworkPath);
339339
await assertVersionedFramework();
340340

341341
// Calling again to expect a no-op
342-
await restoreFrameworkLinks(frameworkPath);
342+
await restoreVersionedFrameworkSymlinks(frameworkPath);
343343
await assertVersionedFramework();
344344
});
345345

@@ -366,8 +366,8 @@ describe("apple", { skip: process.platform !== "darwin" }, () => {
366366
const frameworkPath = path.join(tempDirectoryPath, "foo.framework");
367367

368368
await assert.rejects(
369-
() => restoreFrameworkLinks(frameworkPath),
370-
/Expected "Versions" directory inside versioned framework/,
369+
() => restoreVersionedFrameworkSymlinks(frameworkPath),
370+
/Expected 'Versions' directory inside versioned framework/,
371371
);
372372
});
373373
});

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

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -192,52 +192,62 @@ export async function linkFlatFramework({
192192
}
193193
}
194194

195-
/**
196-
* NPM packages aren't preserving internal symlinks inside versioned frameworks.
197-
* This function attempts to restore those.
198-
*/
199-
export async function restoreFrameworkLinks(frameworkPath: string) {
200-
// Reconstruct missing symbolic links if needed
201-
const versionsPath = path.join(frameworkPath, "Versions");
202-
const versionCurrentPath = path.join(versionsPath, "Current");
195+
async function restoreSymlink(target: string, linkPath: string) {
196+
if (
197+
!fs.existsSync(linkPath) &&
198+
fs.existsSync(path.resolve(path.dirname(linkPath), target))
199+
) {
200+
await fs.promises.symlink(target, linkPath);
201+
}
202+
}
203203

204+
async function guessCurrentFrameworkVersion(frameworkPath: string) {
205+
const versionsPath = path.join(frameworkPath, "Versions");
204206
assert(
205207
fs.existsSync(versionsPath),
206-
`Expected "Versions" directory inside versioned framework '${frameworkPath}'`,
208+
"Expected 'Versions' directory inside versioned framework",
207209
);
208210

209-
if (!fs.existsSync(versionCurrentPath)) {
210-
const versionDirectoryEntries = await fs.promises.readdir(versionsPath, {
211-
withFileTypes: true,
212-
});
213-
const versionDirectoryPaths = versionDirectoryEntries
214-
.filter((dirent) => dirent.isDirectory())
215-
.map((dirent) => path.join(dirent.parentPath, dirent.name));
216-
assert.equal(
217-
versionDirectoryPaths.length,
218-
1,
219-
`Expected a single directory in ${versionsPath}, found ${JSON.stringify(versionDirectoryPaths)}`,
220-
);
221-
const [versionDirectoryPath] = versionDirectoryPaths;
222-
await fs.promises.symlink(
223-
path.relative(path.dirname(versionCurrentPath), versionDirectoryPath),
224-
versionCurrentPath,
225-
);
226-
}
211+
const versionDirectoryEntries = await fs.promises.readdir(versionsPath, {
212+
withFileTypes: true,
213+
});
214+
const versions = versionDirectoryEntries
215+
.filter((dirent) => dirent.isDirectory())
216+
.map((dirent) => dirent.name);
217+
assert.equal(
218+
versions.length,
219+
1,
220+
`Expected exactly one directory in ${versionsPath}, found ${JSON.stringify(versions)}`,
221+
);
222+
const [version] = versions;
223+
return version;
224+
}
227225

228-
const { CFBundleExecutable } = await readFrameworkInfo(
229-
path.join(versionCurrentPath, "Resources", "Info.plist"),
226+
/**
227+
* NPM packages aren't preserving internal symlinks inside versioned frameworks.
228+
* This function attempts to restore those.
229+
*/
230+
export async function restoreVersionedFrameworkSymlinks(frameworkPath: string) {
231+
const currentVersionName = await guessCurrentFrameworkVersion(frameworkPath);
232+
const currentVersionPath = path.join(frameworkPath, "Versions", "Current");
233+
await restoreSymlink(currentVersionName, currentVersionPath);
234+
await restoreSymlink(
235+
"Versions/Current/Resources",
236+
path.join(frameworkPath, "Resources"),
237+
);
238+
await restoreSymlink(
239+
"Versions/Current/Headers",
240+
path.join(frameworkPath, "Headers"),
230241
);
231242

232-
const libraryRealPath = path.join(versionCurrentPath, CFBundleExecutable);
233-
const libraryLinkPath = path.join(frameworkPath, CFBundleExecutable);
234-
// Reconstruct missing symbolic links if needed
235-
if (fs.existsSync(libraryRealPath) && !fs.existsSync(libraryLinkPath)) {
236-
await fs.promises.symlink(
237-
path.relative(path.dirname(libraryLinkPath), libraryRealPath),
238-
libraryLinkPath,
239-
);
240-
}
243+
const { CFBundleExecutable: executableName } = await readFrameworkInfo(
244+
path.join(currentVersionPath, "Resources", "Info.plist"),
245+
);
246+
247+
await restoreSymlink(
248+
path.join("Versions", "Current", executableName),
249+
path.join(frameworkPath, executableName),
250+
);
241251
}
242252

243253
export async function linkVersionedFramework({
@@ -250,7 +260,7 @@ export async function linkVersionedFramework({
250260
"Linking Apple addons are only supported on macOS",
251261
);
252262

253-
await restoreFrameworkLinks(frameworkPath);
263+
await restoreVersionedFrameworkSymlinks(frameworkPath);
254264

255265
const frameworkInfoPath = path.join(
256266
frameworkPath,

packages/weak-node-api/src/restore-xcframework-symlinks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ async function restoreVersionedFrameworkSymlinks(frameworkPath: string) {
4343
"Versions/Current/Resources",
4444
path.join(frameworkPath, "Resources"),
4545
);
46+
await restoreSymlink(
47+
"Versions/Current/Headers",
48+
path.join(frameworkPath, "Headers"),
49+
);
4650
}
4751

4852
if (process.platform === "darwin") {

0 commit comments

Comments
 (0)