mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 02:15:44 +00:00
* fix(doctor): check only the current platform's Hopper launcher candidates Doctor built one launcher list for every platform, so on macOS it could report a Linux-only path as a healthy Hopper ahead of a renamed bundle, and setup then registered that path. Give per-platform automatic candidates one owner that runtime configuration and doctor both read, scan renamed macOS bundles and probe the Homebrew cask only on macOS, and share runtime's renamed-bundle scan with the doctor host. Fixes #6228 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): keep the renamed Hopper bundle scan asynchronous Sharing runtime's synchronous scan made the doctor host read ~/Applications with readdirSync, which blocks the event loop on a slow or network-mounted home. Give MacHopperPaths an asynchronous scan for doctor beside runtime's lazy synchronous one, sharing the directory filter and candidate builder, and check that both return the same candidates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(doctor): model renamed launchers with runtime's POSIX joins Since #5235, runtime builds macOS launcher paths with posix.join, so on Windows the discovery table's native-join renamed launcher no longer matched runtime's candidate. Model launchers with posix.join and keep filesystem setup native, as MacHopperPaths.test.ts does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
2.7 KiB
TypeScript
73 lines
2.7 KiB
TypeScript
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join, posix, relative } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
localMacHopperRenamedLauncherCandidates,
|
|
macHopperCanonicalLauncherCandidates,
|
|
macHopperRenamedLauncherCandidates,
|
|
readMacHopperRenamedLauncherCandidates,
|
|
} from "./MacHopperPaths.js";
|
|
|
|
describe("macOS Hopper launcher paths", () => {
|
|
const home = "/fixture/home";
|
|
|
|
it("keeps canonical system and user candidates ahead of renamed bundles", () => {
|
|
expect(macHopperCanonicalLauncherCandidates(home)).toEqual([
|
|
"/Applications/Hopper Disassembler.app/Contents/MacOS/hopper",
|
|
"/fixture/home/Applications/Hopper Disassembler.app/Contents/MacOS/hopper",
|
|
]);
|
|
expect(
|
|
macHopperRenamedLauncherCandidates(
|
|
home,
|
|
new Map([
|
|
[
|
|
"/Applications",
|
|
["Hopper z.app", "Hopper a.app", "Hopper Disassembler.app"],
|
|
],
|
|
["/fixture/home/Applications", ["Hopper User.app"]],
|
|
]),
|
|
),
|
|
).toEqual([
|
|
"/Applications/Hopper a.app/Contents/MacOS/hopper",
|
|
"/Applications/Hopper z.app/Contents/MacOS/hopper",
|
|
"/fixture/home/Applications/Hopper User.app/Contents/MacOS/hopper",
|
|
]);
|
|
});
|
|
|
|
it("finds the same renamed user bundles through runtime and doctor scans", async () => {
|
|
// Keep native ownership for all I/O, including UNC temporary directories.
|
|
// On Windows, a checkout-relative home models POSIX separators without
|
|
// discarding the drive/share or normalizing a UNC prefix through posix.join.
|
|
const root =
|
|
process.platform === "win32" ? join(process.cwd(), "build") : tmpdir();
|
|
await mkdir(root, { recursive: true });
|
|
const temporary = await mkdtemp(join(root, "rea-hopper-paths-"));
|
|
const home =
|
|
process.platform === "win32"
|
|
? relative(process.cwd(), temporary).replaceAll("\\", "/")
|
|
: temporary;
|
|
const applications = join(temporary, "Applications");
|
|
try {
|
|
await mkdir(join(applications, "Hopper Preview.app"), {
|
|
recursive: true,
|
|
});
|
|
await mkdir(join(applications, "Hopper Disassembler.app"));
|
|
await writeFile(join(applications, "Hopper File.app"), "");
|
|
const runtime = [...localMacHopperRenamedLauncherCandidates(home)];
|
|
expect(runtime.filter((path) => path.startsWith(home))).toEqual([
|
|
posix.join(
|
|
home,
|
|
"Applications/Hopper Preview.app/Contents/MacOS/hopper",
|
|
),
|
|
]);
|
|
expect(await readMacHopperRenamedLauncherCandidates(home)).toEqual(
|
|
runtime,
|
|
);
|
|
} finally {
|
|
await rm(temporary, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|