feat(doctor): admit the Windows x64 Ghidra boundary
This commit is contained in:
parent
0b3551076d
commit
32dda0c19e
|
|
@ -64,6 +64,7 @@ export interface DoctorProviderInspection {
|
||||||
/** Read-only host capabilities required by diagnostics. */
|
/** Read-only host capabilities required by diagnostics. */
|
||||||
export interface DoctorHost {
|
export interface DoctorHost {
|
||||||
readonly platform: NodeJS.Platform;
|
readonly platform: NodeJS.Platform;
|
||||||
|
readonly architecture: NodeJS.Architecture;
|
||||||
readonly nodeVersion: string;
|
readonly nodeVersion: string;
|
||||||
readonly configuredHopperPath?: string;
|
readonly configuredHopperPath?: string;
|
||||||
readonly configuredIlspyCmdPath?: string;
|
readonly configuredIlspyCmdPath?: string;
|
||||||
|
|
@ -141,18 +142,19 @@ export const runDoctor = async (
|
||||||
host.platform === "linux" ? await host.linuxDistribution() : undefined;
|
host.platform === "linux" ? await host.linuxDistribution() : undefined;
|
||||||
const supportedHost =
|
const supportedHost =
|
||||||
(host.platform === "darwin" && macosMajor >= 12) ||
|
(host.platform === "darwin" && macosMajor >= 12) ||
|
||||||
(host.platform === "linux" && linuxDistribution?.supported === true);
|
(host.platform === "linux" && linuxDistribution?.supported === true) ||
|
||||||
|
(host.platform === "win32" && host.architecture === "x64");
|
||||||
checks.push(
|
checks.push(
|
||||||
check(
|
check(
|
||||||
"host",
|
"host",
|
||||||
supportedHost,
|
supportedHost,
|
||||||
macosVersion ??
|
macosVersion ??
|
||||||
(linuxDistribution === undefined
|
(linuxDistribution === undefined
|
||||||
? host.platform
|
? `${host.platform} ${host.architecture}`
|
||||||
: `${linuxDistribution.id} ${linuxDistribution.versionId ?? "unknown"}`),
|
: `${linuxDistribution.id} ${linuxDistribution.versionId ?? "unknown"}`),
|
||||||
{
|
{
|
||||||
remediation:
|
remediation:
|
||||||
"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, and 64-bit Arch Linux.",
|
"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and the experimental Windows x64 Ghidra P0 boundary.",
|
||||||
classification: "unsupported_host",
|
classification: "unsupported_host",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -357,6 +359,7 @@ export const systemDoctorHost = (
|
||||||
options: SystemDoctorHostOptions = {},
|
options: SystemDoctorHostOptions = {},
|
||||||
): DoctorHost => ({
|
): DoctorHost => ({
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
|
architecture: process.arch,
|
||||||
nodeVersion: process.versions.node,
|
nodeVersion: process.versions.node,
|
||||||
...(process.env.HOPPER_LAUNCHER_PATH === undefined
|
...(process.env.HOPPER_LAUNCHER_PATH === undefined
|
||||||
? {}
|
? {}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { PRODUCT_IDENTITY } from "../src/identity.js";
|
||||||
|
|
||||||
const host = (overrides: Partial<DoctorHost> = {}): DoctorHost => ({
|
const host = (overrides: Partial<DoctorHost> = {}): DoctorHost => ({
|
||||||
platform: "darwin",
|
platform: "darwin",
|
||||||
|
architecture: "x64",
|
||||||
nodeVersion: "24.18.0",
|
nodeVersion: "24.18.0",
|
||||||
macosVersion: () => Promise.resolve("12.0"),
|
macosVersion: () => Promise.resolve("12.0"),
|
||||||
linuxDistribution: () => Promise.resolve(undefined),
|
linuxDistribution: () => Promise.resolve(undefined),
|
||||||
|
|
@ -40,7 +41,7 @@ describe("doctor", () => {
|
||||||
),
|
),
|
||||||
).toEqual({
|
).toEqual({
|
||||||
node: "Install Node.js 22.19+ or 24.11+.",
|
node: "Install Node.js 22.19+ or 24.11+.",
|
||||||
host: "REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, and 64-bit Arch Linux.",
|
host: "REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and the experimental Windows x64 Ghidra P0 boundary.",
|
||||||
hopper: "Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH.",
|
hopper: "Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH.",
|
||||||
target: "Supply a readable local app or program path.",
|
target: "Supply a readable local app or program path.",
|
||||||
});
|
});
|
||||||
|
|
@ -56,6 +57,36 @@ describe("doctor", () => {
|
||||||
expect(result.checks.find(({ name }) => name === "host")?.ok).toBe(false);
|
expect(result.checks.find(({ name }) => name === "host")?.ok).toBe(false);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it("admits only the experimental Windows x64 host boundary", async () => {
|
||||||
|
const windows = await runDoctor(
|
||||||
|
undefined,
|
||||||
|
host({
|
||||||
|
platform: "win32",
|
||||||
|
architecture: "x64",
|
||||||
|
macosVersion: () => Promise.resolve(undefined),
|
||||||
|
executable: () => Promise.resolve(false),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const arm = await runDoctor(
|
||||||
|
undefined,
|
||||||
|
host({
|
||||||
|
platform: "win32",
|
||||||
|
architecture: "arm64",
|
||||||
|
macosVersion: () => Promise.resolve(undefined),
|
||||||
|
executable: () => Promise.resolve(false),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(windows.checks.find(({ name }) => name === "host")).toMatchObject({
|
||||||
|
ok: true,
|
||||||
|
detail: "win32 x64",
|
||||||
|
});
|
||||||
|
expect(arm.checks.find(({ name }) => name === "host")).toMatchObject({
|
||||||
|
ok: false,
|
||||||
|
detail: "win32 arm64",
|
||||||
|
});
|
||||||
|
});
|
||||||
it("detects a manual configured Hopper before Homebrew", async () => {
|
it("detects a manual configured Hopper before Homebrew", async () => {
|
||||||
const result = await runDoctor(
|
const result = await runDoctor(
|
||||||
undefined,
|
undefined,
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,13 @@ const inspection = (
|
||||||
options: {
|
options: {
|
||||||
readonly installDir?: string;
|
readonly installDir?: string;
|
||||||
readonly architecture?: NodeJS.Architecture;
|
readonly architecture?: NodeJS.Architecture;
|
||||||
|
readonly platform?: NodeJS.Platform;
|
||||||
} = { installDir: INSTALL },
|
} = { installDir: INSTALL },
|
||||||
overrides: Partial<GhidraInstallationHost> = {},
|
overrides: Partial<GhidraInstallationHost> = {},
|
||||||
): GhidraInstallationInspection =>
|
): GhidraInstallationInspection =>
|
||||||
inspectGhidraInstallation(
|
inspectGhidraInstallation(
|
||||||
{
|
{
|
||||||
platform: "linux",
|
platform: options.platform ?? "linux",
|
||||||
architecture: options.architecture ?? "x64",
|
architecture: options.architecture ?? "x64",
|
||||||
...(options.installDir === undefined
|
...(options.installDir === undefined
|
||||||
? {}
|
? {}
|
||||||
|
|
@ -49,6 +50,7 @@ const doctorHost = (
|
||||||
hopperAvailable = false,
|
hopperAvailable = false,
|
||||||
): DoctorHost => ({
|
): DoctorHost => ({
|
||||||
platform: "linux",
|
platform: "linux",
|
||||||
|
architecture: "x64",
|
||||||
nodeVersion: "24.18.0",
|
nodeVersion: "24.18.0",
|
||||||
macosVersion: () => Promise.resolve(undefined),
|
macosVersion: () => Promise.resolve(undefined),
|
||||||
linuxDistribution: () =>
|
linuxDistribution: () =>
|
||||||
|
|
@ -98,6 +100,28 @@ describe("Ghidra doctor integration", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts the experimental Windows x64 Ghidra provider boundary", async () => {
|
||||||
|
const ghidra = inspection({
|
||||||
|
installDir: "C:\\tools\\ghidra_12.1.2_PUBLIC",
|
||||||
|
platform: "win32",
|
||||||
|
});
|
||||||
|
const result = await runDoctor(undefined, {
|
||||||
|
...doctorHost(ghidra),
|
||||||
|
platform: "win32",
|
||||||
|
architecture: "x64",
|
||||||
|
linuxDistribution: () => Promise.resolve(undefined),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.healthy).toBe(true);
|
||||||
|
expect(result.checks.find(({ name }) => name === "host")).toMatchObject({
|
||||||
|
ok: true,
|
||||||
|
detail: "win32 x64",
|
||||||
|
});
|
||||||
|
expect(result.checks.find(({ name }) => name === "ghidra")).toMatchObject({
|
||||||
|
ok: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
"bad installation",
|
"bad installation",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue