mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-05-01 06:36:23 +08:00
refactor(plugins): share bundled runtime deps install script helpers
This commit is contained in:
66
scripts/lib/bundled-runtime-deps-install.mjs
Normal file
66
scripts/lib/bundled-runtime-deps-install.mjs
Normal file
@@ -0,0 +1,66 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
|
||||
export function createNestedNpmInstallEnv(env = process.env) {
|
||||
const nextEnv = { ...env };
|
||||
delete nextEnv.npm_config_global;
|
||||
delete nextEnv.npm_config_location;
|
||||
delete nextEnv.npm_config_prefix;
|
||||
return nextEnv;
|
||||
}
|
||||
|
||||
export function createBundledRuntimeDependencyInstallEnv(env = process.env, options = {}) {
|
||||
const nextEnv = {
|
||||
...createNestedNpmInstallEnv(env),
|
||||
npm_config_dry_run: "false",
|
||||
npm_config_fetch_retries: env.npm_config_fetch_retries ?? "5",
|
||||
npm_config_fetch_retry_maxtimeout: env.npm_config_fetch_retry_maxtimeout ?? "120000",
|
||||
npm_config_fetch_retry_mintimeout: env.npm_config_fetch_retry_mintimeout ?? "10000",
|
||||
npm_config_fetch_timeout: env.npm_config_fetch_timeout ?? "300000",
|
||||
npm_config_legacy_peer_deps: "true",
|
||||
npm_config_package_lock: "false",
|
||||
npm_config_save: "false",
|
||||
};
|
||||
if (options.ci) {
|
||||
nextEnv.CI = "1";
|
||||
}
|
||||
if (options.quiet) {
|
||||
Object.assign(nextEnv, {
|
||||
npm_config_audit: "false",
|
||||
npm_config_fund: "false",
|
||||
npm_config_loglevel: "error",
|
||||
npm_config_progress: "false",
|
||||
npm_config_yes: "true",
|
||||
});
|
||||
}
|
||||
return nextEnv;
|
||||
}
|
||||
|
||||
export function createBundledRuntimeDependencyInstallArgs(specs = [], options = {}) {
|
||||
return [
|
||||
"install",
|
||||
...(options.noAudit ? ["--no-audit"] : []),
|
||||
...(options.noFund ? ["--no-fund"] : []),
|
||||
"--ignore-scripts",
|
||||
...(options.silent ? ["--silent"] : []),
|
||||
...specs,
|
||||
];
|
||||
}
|
||||
|
||||
export function runBundledRuntimeDependencyNpmInstall(params) {
|
||||
const runSpawnSync = params.spawnSyncImpl ?? spawnSync;
|
||||
const result = runSpawnSync(params.npmRunner.command, params.npmRunner.args, {
|
||||
cwd: params.cwd,
|
||||
encoding: "utf8",
|
||||
env: params.env ?? params.npmRunner.env ?? process.env,
|
||||
shell: params.npmRunner.shell,
|
||||
stdio: params.stdio ?? "pipe",
|
||||
...(params.timeoutMs ? { timeout: params.timeoutMs } : {}),
|
||||
windowsHide: true,
|
||||
windowsVerbatimArguments: params.npmRunner.windowsVerbatimArguments,
|
||||
});
|
||||
if (result.status === 0) {
|
||||
return;
|
||||
}
|
||||
const output = [result.stderr, result.stdout].filter(Boolean).join("\n").trim();
|
||||
throw new Error(output || "npm install failed");
|
||||
}
|
||||
@@ -24,8 +24,20 @@ import {
|
||||
import { tmpdir } from "node:os";
|
||||
import { basename, dirname, isAbsolute, join, posix, relative } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import {
|
||||
createBundledRuntimeDependencyInstallArgs,
|
||||
createBundledRuntimeDependencyInstallEnv,
|
||||
createNestedNpmInstallEnv,
|
||||
runBundledRuntimeDependencyNpmInstall,
|
||||
} from "./lib/bundled-runtime-deps-install.mjs";
|
||||
import { resolveNpmRunner } from "./npm-runner.mjs";
|
||||
|
||||
export {
|
||||
createBundledRuntimeDependencyInstallArgs,
|
||||
createBundledRuntimeDependencyInstallEnv,
|
||||
createNestedNpmInstallEnv,
|
||||
};
|
||||
|
||||
export const BUNDLED_PLUGIN_INSTALL_TARGETS = [];
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
@@ -582,32 +594,6 @@ export function discoverBundledPluginRuntimeDeps(params = {}) {
|
||||
.toSorted((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
export function createNestedNpmInstallEnv(env = process.env) {
|
||||
const nextEnv = { ...env };
|
||||
delete nextEnv.npm_config_global;
|
||||
delete nextEnv.npm_config_location;
|
||||
delete nextEnv.npm_config_prefix;
|
||||
return nextEnv;
|
||||
}
|
||||
|
||||
export function createBundledRuntimeDependencyInstallEnv(env = process.env) {
|
||||
return {
|
||||
...createNestedNpmInstallEnv(env),
|
||||
npm_config_dry_run: "false",
|
||||
npm_config_fetch_retries: env.npm_config_fetch_retries ?? "5",
|
||||
npm_config_fetch_retry_maxtimeout: env.npm_config_fetch_retry_maxtimeout ?? "120000",
|
||||
npm_config_fetch_retry_mintimeout: env.npm_config_fetch_retry_mintimeout ?? "10000",
|
||||
npm_config_fetch_timeout: env.npm_config_fetch_timeout ?? "300000",
|
||||
npm_config_legacy_peer_deps: "true",
|
||||
npm_config_package_lock: "false",
|
||||
npm_config_save: "false",
|
||||
};
|
||||
}
|
||||
|
||||
export function createBundledRuntimeDependencyInstallArgs(missingSpecs) {
|
||||
return ["install", "--ignore-scripts", ...missingSpecs];
|
||||
}
|
||||
|
||||
function shouldEagerInstallBundledPluginDeps(env = process.env) {
|
||||
return env?.[EAGER_BUNDLED_PLUGIN_DEPS_ENV]?.trim() === "1";
|
||||
}
|
||||
@@ -1003,19 +989,12 @@ export function runBundledPluginPostinstall(params = {}) {
|
||||
comSpec: params.comSpec,
|
||||
npmArgs: createBundledRuntimeDependencyInstallArgs(missingSpecs),
|
||||
});
|
||||
const result = spawn(npmRunner.command, npmRunner.args, {
|
||||
runBundledRuntimeDependencyNpmInstall({
|
||||
cwd: packageRoot,
|
||||
encoding: "utf8",
|
||||
npmRunner,
|
||||
env: npmRunner.env ?? installEnv,
|
||||
stdio: "pipe",
|
||||
windowsHide: true,
|
||||
shell: npmRunner.shell,
|
||||
windowsVerbatimArguments: npmRunner.windowsVerbatimArguments,
|
||||
spawnSyncImpl: spawn,
|
||||
});
|
||||
if (result.status !== 0) {
|
||||
const output = [result.stderr, result.stdout].filter(Boolean).join("\n").trim();
|
||||
throw new Error(output || "npm install failed");
|
||||
}
|
||||
log.log(`[postinstall] installed bundled plugin deps: ${missingSpecs.join(", ")}`);
|
||||
} catch (e) {
|
||||
// Non-fatal: gateway will surface the missing dep via doctor.
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { performance } from "node:perf_hooks";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import semverSatisfies from "semver/functions/satisfies.js";
|
||||
import {
|
||||
createBundledRuntimeDependencyInstallArgs,
|
||||
createBundledRuntimeDependencyInstallEnv,
|
||||
runBundledRuntimeDependencyNpmInstall,
|
||||
} from "./lib/bundled-runtime-deps-install.mjs";
|
||||
import { resolveNpmRunner } from "./npm-runner.mjs";
|
||||
|
||||
const TRANSIENT_TEMP_REMOVE_ERROR_CODES = new Set(["EBUSY", "ENOTEMPTY", "EPERM"]);
|
||||
@@ -905,39 +909,17 @@ function createRuntimeInstallManifest(pluginId, pinnedGroups) {
|
||||
}
|
||||
|
||||
function runNpmInstall(params) {
|
||||
const npmEnv = {
|
||||
...(params.npmRunner.env ?? process.env),
|
||||
CI: "1",
|
||||
npm_config_audit: "false",
|
||||
npm_config_dry_run: "false",
|
||||
npm_config_fetch_retries: process.env.npm_config_fetch_retries ?? "5",
|
||||
npm_config_fetch_retry_maxtimeout: process.env.npm_config_fetch_retry_maxtimeout ?? "120000",
|
||||
npm_config_fetch_retry_mintimeout: process.env.npm_config_fetch_retry_mintimeout ?? "10000",
|
||||
npm_config_fetch_timeout: process.env.npm_config_fetch_timeout ?? "300000",
|
||||
npm_config_fund: "false",
|
||||
npm_config_legacy_peer_deps: "true",
|
||||
npm_config_loglevel: "error",
|
||||
npm_config_package_lock: "false",
|
||||
npm_config_progress: "false",
|
||||
npm_config_save: "false",
|
||||
npm_config_yes: "true",
|
||||
};
|
||||
const runSpawnSync = params.spawnSyncImpl ?? spawnSync;
|
||||
const result = runSpawnSync(params.npmRunner.command, params.npmRunner.args, {
|
||||
return runBundledRuntimeDependencyNpmInstall({
|
||||
cwd: params.cwd,
|
||||
encoding: "utf8",
|
||||
env: npmEnv,
|
||||
shell: params.npmRunner.shell,
|
||||
npmRunner: params.npmRunner,
|
||||
env: createBundledRuntimeDependencyInstallEnv(params.npmRunner.env ?? process.env, {
|
||||
ci: true,
|
||||
quiet: true,
|
||||
}),
|
||||
spawnSyncImpl: params.spawnSyncImpl,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
timeout: params.timeoutMs ?? 5 * 60 * 1000,
|
||||
windowsHide: true,
|
||||
windowsVerbatimArguments: params.npmRunner.windowsVerbatimArguments,
|
||||
});
|
||||
if (result.status === 0) {
|
||||
return;
|
||||
}
|
||||
const output = [result.stderr, result.stdout].filter(Boolean).join("\n").trim();
|
||||
throw new Error(output || "npm install failed");
|
||||
}
|
||||
|
||||
function resolveLegacyRuntimeDepsStampPath(pluginDir) {
|
||||
@@ -1203,7 +1185,11 @@ function installPluginRuntimeDeps(params) {
|
||||
runNpmInstall({
|
||||
cwd: tempInstallDir,
|
||||
npmRunner: resolveNpmRunner({
|
||||
npmArgs: ["install", "--no-audit", "--no-fund", "--ignore-scripts", "--silent"],
|
||||
npmArgs: createBundledRuntimeDependencyInstallArgs([], {
|
||||
noAudit: true,
|
||||
noFund: true,
|
||||
silent: true,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user