v1's sha256(host_id || mac) used the lex-first non-virtual interface's MAC — usually en0 on Wi-Fi Macs, whose MAC Apple's privacy feature re-randomizes across reboots. After a restart the recomputed hash no longer matched the stored one and the daemon entered a launchd respawn loop until manual `claudemesh daemon accept-host`. v2 reads IOPlatformUUID via ioreg on macOS (burned into EFI, stable), rejects locally-administered MACs in the picker, extends the ignored- interface list with anpi/bridge/ap[N], and prepends "v2\0" to the hash so v1 and v2 hashes can never collide on the same inputs. Migration is silent: a stored v1 fingerprint that still matches under the v1 algorithm is transparently rewritten as v2 with no error; v1 stores that fail v1 are reported as genuine mismatches as before; unknown future schema_versions return `unavailable` without overwriting. Drive-by fixes for two pre-existing test-infra papercuts found while validating: turbo's `test` task now depends on `build`, and a new vitest globalSetup rebuilds the CLI on demand with ~/.bun/bin and Homebrew layered into PATH — golden tests (whoami, --version) no longer fail opaquely after a clean checkout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
// vitest globalSetup — guarantees `dist/entrypoints/cli.js` exists
|
|
// before any golden test spawns the built CLI. Without this, running
|
|
// `npx vitest run` in a clean checkout (or after `pnpm run clean`)
|
|
// surfaces as opaque `MODULE_NOT_FOUND` failures inside golden tests.
|
|
|
|
import { existsSync, statSync } from "node:fs";
|
|
import { spawnSync } from "node:child_process";
|
|
import { join, dirname, delimiter } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { homedir } from "node:os";
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const CLI_PKG_DIR = join(HERE, "..", "..");
|
|
const CLI_ENTRY = join(CLI_PKG_DIR, "dist", "entrypoints", "cli.js");
|
|
const BUILD_SCRIPT = join(CLI_PKG_DIR, "build.ts");
|
|
const PKG_JSON = join(CLI_PKG_DIR, "package.json");
|
|
|
|
// Vitest's worker doesn't always inherit the user's shell PATH (no
|
|
// `.zshrc`/`config.fish` is sourced), so a bun install at `~/.bun/bin`
|
|
// is invisible to spawnSync. Layer the well-known install locations
|
|
// in so the build command can find them.
|
|
const EXTRA_PATHS = [
|
|
join(homedir(), ".bun", "bin"),
|
|
"/opt/homebrew/bin",
|
|
"/usr/local/bin",
|
|
];
|
|
|
|
function augmentedEnv(): NodeJS.ProcessEnv {
|
|
const current = process.env.PATH ?? "";
|
|
const augmented = [...EXTRA_PATHS, current].filter(Boolean).join(delimiter);
|
|
return { ...process.env, PATH: augmented };
|
|
}
|
|
|
|
function isDistFresh(): boolean {
|
|
if (!existsSync(CLI_ENTRY)) return false;
|
|
// If the build script or package.json (which contributes the
|
|
// injected version constant) is newer than dist, rebuild.
|
|
try {
|
|
const distMtime = statSync(CLI_ENTRY).mtimeMs;
|
|
if (statSync(BUILD_SCRIPT).mtimeMs > distMtime) return false;
|
|
if (statSync(PKG_JSON).mtimeMs > distMtime) return false;
|
|
} catch {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export default async function setup(): Promise<void> {
|
|
if (isDistFresh()) return;
|
|
|
|
// Try `bun build.ts` first (the canonical path). If bun is missing,
|
|
// fall back to `pnpm run build` which delegates to the same script.
|
|
const tries: Array<{ cmd: string; args: string[] }> = [
|
|
{ cmd: "bun", args: ["build.ts"] },
|
|
{ cmd: "pnpm", args: ["run", "build"] },
|
|
];
|
|
|
|
const env = augmentedEnv();
|
|
for (const { cmd, args } of tries) {
|
|
const r = spawnSync(cmd, args, { cwd: CLI_PKG_DIR, stdio: "inherit", env });
|
|
if (r.status === 0 && existsSync(CLI_ENTRY)) return;
|
|
if (r.error && (r.error as NodeJS.ErrnoException).code === "ENOENT")
|
|
continue;
|
|
}
|
|
|
|
throw new Error(
|
|
`vitest globalSetup: failed to build the CLI. ` +
|
|
`Tried \`bun build.ts\` and \`pnpm run build\`. ` +
|
|
`Install bun (https://bun.sh) or run \`pnpm run build\` manually before testing.`,
|
|
);
|
|
}
|