mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:20:43 +00:00
fix(update): use absolute npm script shell
This commit is contained in:
@@ -150,6 +150,47 @@ describe("update global helpers", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("uses an absolute POSIX script shell for npm lifecycle scripts during global installs", async () => {
|
||||
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("linux");
|
||||
try {
|
||||
await expect(
|
||||
createGlobalInstallEnv({
|
||||
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
|
||||
PATH: "/home/peter/.npm-global/bin",
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
|
||||
NPM_CONFIG_SCRIPT_SHELL: "/bin/sh",
|
||||
});
|
||||
} finally {
|
||||
platformSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves explicit npm script shell config for global installs", async () => {
|
||||
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("linux");
|
||||
try {
|
||||
await expect(
|
||||
createGlobalInstallEnv({
|
||||
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
|
||||
NPM_CONFIG_SCRIPT_SHELL: "/custom/sh",
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
NPM_CONFIG_SCRIPT_SHELL: "/custom/sh",
|
||||
});
|
||||
await expect(
|
||||
createGlobalInstallEnv({
|
||||
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
|
||||
npm_config_script_shell: "/custom/lower-sh",
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
npm_config_script_shell: "/custom/lower-sh",
|
||||
});
|
||||
} finally {
|
||||
platformSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves portable Git paths from process-local app data only", async () => {
|
||||
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32");
|
||||
try {
|
||||
|
||||
@@ -41,6 +41,7 @@ const NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS = [
|
||||
"--omit=optional",
|
||||
...NPM_GLOBAL_INSTALL_QUIET_FLAGS,
|
||||
] as const;
|
||||
const NPM_CONFIG_SCRIPT_SHELL_KEYS = ["NPM_CONFIG_SCRIPT_SHELL", "npm_config_script_shell"];
|
||||
const FIRST_PACKAGED_DIST_INVENTORY_VERSION = { major: 2026, minor: 4, patch: 15 };
|
||||
const OMITTED_PRIVATE_QA_BUNDLED_PLUGIN_ROOTS = new Set([
|
||||
"dist/extensions/qa-channel",
|
||||
@@ -315,6 +316,31 @@ function applyCorepackDownloadPromptEnv(env: Record<string, string>) {
|
||||
}
|
||||
}
|
||||
|
||||
function hasNpmScriptShellSetting(env: NodeJS.ProcessEnv): boolean {
|
||||
return NPM_CONFIG_SCRIPT_SHELL_KEYS.some((key) => Boolean(env[key]?.trim()));
|
||||
}
|
||||
|
||||
function resolvePosixNpmScriptShell(env: NodeJS.ProcessEnv): string | null {
|
||||
if (process.platform === "win32") {
|
||||
return null;
|
||||
}
|
||||
if (fsSync.existsSync("/bin/sh")) {
|
||||
return "/bin/sh";
|
||||
}
|
||||
const shell = env.SHELL?.trim();
|
||||
return shell && path.isAbsolute(shell) && fsSync.existsSync(shell) ? shell : null;
|
||||
}
|
||||
|
||||
function applyPosixNpmScriptShellEnv(env: Record<string, string>) {
|
||||
if (hasNpmScriptShellSetting(env)) {
|
||||
return;
|
||||
}
|
||||
const scriptShell = resolvePosixNpmScriptShell(env);
|
||||
if (scriptShell) {
|
||||
env.NPM_CONFIG_SCRIPT_SHELL = scriptShell;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveGlobalInstallSpec(params: {
|
||||
packageName: string;
|
||||
tag: string;
|
||||
@@ -344,8 +370,13 @@ export async function createGlobalInstallEnv(
|
||||
const hasCorepackDownloadPromptSetting = Boolean(
|
||||
sourceEnv.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim(),
|
||||
);
|
||||
const missingPosixScriptShell =
|
||||
Boolean(resolvePosixNpmScriptShell(sourceEnv)) && !hasNpmScriptShellSetting(sourceEnv);
|
||||
const requiresMergedEnv =
|
||||
pathPrepend.length > 0 || process.platform === "win32" || !hasCorepackDownloadPromptSetting;
|
||||
pathPrepend.length > 0 ||
|
||||
process.platform === "win32" ||
|
||||
!hasCorepackDownloadPromptSetting ||
|
||||
missingPosixScriptShell;
|
||||
if (!requiresMergedEnv) {
|
||||
return env;
|
||||
}
|
||||
@@ -357,6 +388,7 @@ export async function createGlobalInstallEnv(
|
||||
applyPathPrepend(merged, pathPrepend);
|
||||
applyWindowsPackageInstallEnv(merged);
|
||||
applyCorepackDownloadPromptEnv(merged);
|
||||
applyPosixNpmScriptShellEnv(merged);
|
||||
return merged;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user