fix: v2.5.1 — plugin npm runs no longer depend on PATH (Windows update failure)
A Windows self-update failed at "bootstrap": 'npm.cmd' is not recognized. The update chain runs with the dashboard server's environment, whose PATH need not reach npm.cmd, and the bootstrap looked npm up through cmd.exe (shell: true, which also printed DEP0190). - npmCommand() in scripts/plugin-bootstrap.js runs the npm bundled with the running node (npm-cli.js beside process.execPath, Windows and Unix layouts) with no shell, and puts that node's directory first on PATH (kept under the env's own Path/PATH key) so npm scripts find the same node; npm on PATH only when that node ships none - Used by the runtime install, the UI build (plugin-open.js) and the doctor's npm row (plugin-doctor.js)
This commit is contained in:
@@ -651,3 +651,45 @@ describe("pruneRetiredPluginRoots", () => {
|
||||
assert.ok(fs.existsSync(sibling));
|
||||
});
|
||||
});
|
||||
|
||||
describe("npmCommand", () => {
|
||||
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "agenthub-npmcmd-"));
|
||||
after(() => fs.rmSync(tmp, { recursive: true, force: true }));
|
||||
const cliAt = (...parts) => {
|
||||
const p = path.join(tmp, ...parts);
|
||||
fs.mkdirSync(path.dirname(p), { recursive: true });
|
||||
fs.writeFileSync(p, "");
|
||||
return p;
|
||||
};
|
||||
|
||||
it("runs the node's own bundled npm (Windows layout), no shell, no PATH lookup", () => {
|
||||
// The "'npm.cmd' is not recognized" failure: the update chain's PATH had no npm.
|
||||
const cli = cliAt("win", "node_modules", "npm", "bin", "npm-cli.js");
|
||||
const execPath = path.join(tmp, "win", "node.exe");
|
||||
const npm = boot.npmCommand(["install"], { execPath, env: { Path: "C:\\other" } });
|
||||
assert.equal(npm.file, execPath);
|
||||
assert.deepEqual(npm.args, [cli, "install"]);
|
||||
assert.equal(npm.shell, false);
|
||||
// Windows env keys keep their own case — a second "PATH" key would be ambiguous.
|
||||
assert.equal(npm.env.Path, [path.dirname(execPath), "C:\\other"].join(path.delimiter));
|
||||
assert.equal(npm.env.PATH, undefined);
|
||||
});
|
||||
|
||||
it("finds the Unix layout (bin/node + lib/node_modules/npm)", () => {
|
||||
const cli = cliAt("unix", "lib", "node_modules", "npm", "bin", "npm-cli.js");
|
||||
const execPath = path.join(tmp, "unix", "bin", "node");
|
||||
const npm = boot.npmCommand(["-v"], { execPath, env: { PATH: "/usr/bin" } });
|
||||
assert.deepEqual(npm.args, [
|
||||
path.join(tmp, "unix", "bin", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
||||
"-v",
|
||||
]);
|
||||
assert.ok(fs.existsSync(npm.args[0]) && path.resolve(npm.args[0]) === cli);
|
||||
assert.equal(npm.env.PATH.split(path.delimiter)[0], path.dirname(execPath));
|
||||
});
|
||||
|
||||
it("falls back to npm on PATH when the node has no bundled npm", () => {
|
||||
const npm = boot.npmCommand(["-v"], { execPath: path.join(tmp, "bare", "node"), env: {} });
|
||||
assert.equal(npm.file, process.platform === "win32" ? "npm.cmd" : "npm");
|
||||
assert.deepEqual(npm.args, ["-v"]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user