When GSD is installed with `bun add -g`, running `gsd update` or `/gsd update` previously shelled out to `npm install -g`, which fails with EACCES on systems where npm has no write access to the global node_modules directory. Adds `resolveInstallCommand(pkg)` to `update-check.ts` that returns `bun add -g <pkg>` when `process.versions.bun` is defined (i.e. the current runtime is Bun), and `npm install -g <pkg>` otherwise. All three update paths — `update-cmd.ts`, `commands-handlers.ts`, and the interactive startup prompt in `update-check.ts` — now use this helper, including the fallback error message shown to the user. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
84 lines
3.7 KiB
TypeScript
84 lines
3.7 KiB
TypeScript
/**
|
|
* Regression test for #3445: gsd update must print both current and latest
|
|
* versions for diagnostics, and bypass npm cache.
|
|
* Regression test for #4145: gsd update must use bun when installed via Bun.
|
|
*/
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
test("update-cmd prints latest version before comparison (#3445)", () => {
|
|
const src = readFileSync(join(__dirname, "..", "update-cmd.ts"), "utf-8");
|
|
const latestPrintIdx = src.indexOf("Latest version:");
|
|
const comparisonIdx = src.indexOf("compareSemver(latest, current)");
|
|
assert.ok(latestPrintIdx !== -1, "Must print latest version");
|
|
assert.ok(latestPrintIdx < comparisonIdx, "Must print latest BEFORE comparison");
|
|
});
|
|
|
|
test("update commands use the registry fetch helper instead of npm view (#3806)", () => {
|
|
const src = readFileSync(join(__dirname, "..", "update-cmd.ts"), "utf-8");
|
|
const handlerSrc = readFileSync(join(__dirname, "..", "resources", "extensions", "gsd", "commands-handlers.ts"), "utf-8");
|
|
assert.ok(
|
|
src.includes("fetchLatestVersionFromRegistry"),
|
|
"update-cmd should use the shared registry fetch helper",
|
|
);
|
|
assert.ok(!src.includes("npm view "), "update-cmd should no longer shell out to npm view");
|
|
assert.ok(
|
|
handlerSrc.includes("fetchLatestVersionForCommand"),
|
|
"/gsd update should fetch the latest version through a registry helper too",
|
|
);
|
|
assert.ok(!handlerSrc.includes("npm view "), "/gsd update should no longer shell out to npm view");
|
|
});
|
|
|
|
test("update-check exports resolveInstallCommand (#4145)", async () => {
|
|
const { resolveInstallCommand } = await import("../update-check.js");
|
|
assert.equal(typeof resolveInstallCommand, "function", "resolveInstallCommand must be exported from update-check");
|
|
});
|
|
|
|
test("resolveInstallCommand returns bun command when running under Bun (#4145)", async () => {
|
|
const { resolveInstallCommand } = await import("../update-check.js");
|
|
const orig = (process.versions as Record<string, string | undefined>).bun;
|
|
try {
|
|
(process.versions as Record<string, string | undefined>).bun = "1.0.0";
|
|
assert.equal(resolveInstallCommand("gsd-pi@latest"), "bun add -g gsd-pi@latest");
|
|
} finally {
|
|
if (orig === undefined) {
|
|
delete (process.versions as Record<string, string | undefined>).bun;
|
|
} else {
|
|
(process.versions as Record<string, string | undefined>).bun = orig;
|
|
}
|
|
}
|
|
});
|
|
|
|
test("resolveInstallCommand returns npm command when not running under Bun (#4145)", async () => {
|
|
const { resolveInstallCommand } = await import("../update-check.js");
|
|
const orig = (process.versions as Record<string, string | undefined>).bun;
|
|
try {
|
|
delete (process.versions as Record<string, string | undefined>).bun;
|
|
assert.equal(resolveInstallCommand("gsd-pi@latest"), "npm install -g gsd-pi@latest");
|
|
} finally {
|
|
if (orig !== undefined) {
|
|
(process.versions as Record<string, string | undefined>).bun = orig;
|
|
}
|
|
}
|
|
});
|
|
|
|
test("update-cmd uses resolveInstallCommand instead of hardcoded npm (#4145)", () => {
|
|
const src = readFileSync(join(__dirname, "..", "update-cmd.ts"), "utf-8");
|
|
assert.ok(
|
|
src.includes("resolveInstallCommand"),
|
|
"update-cmd should use resolveInstallCommand for package manager detection",
|
|
);
|
|
});
|
|
|
|
test("commands-handlers uses resolveInstallCommand instead of hardcoded npm (#4145)", () => {
|
|
const handlerSrc = readFileSync(join(__dirname, "..", "resources", "extensions", "gsd", "commands-handlers.ts"), "utf-8");
|
|
assert.ok(
|
|
handlerSrc.includes("resolveInstallCommand"),
|
|
"/gsd update handler should use resolveInstallCommand for package manager detection",
|
|
);
|
|
});
|