mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-23 13:08:12 +00:00
90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
// Warns during install lifecycle when a package manager other than pnpm is used.
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const allowedLifecyclePackageManagers = new Set(["pnpm", "npm", "yarn", "bun"]);
|
|
const lifecyclePackageManagerLauncherAliases = new Map([
|
|
["yarnpkg", "yarn"],
|
|
["yarn-berry", "yarn"],
|
|
]);
|
|
|
|
function normalizeEnvValue(value) {
|
|
return typeof value === "string" ? value.trim() : "";
|
|
}
|
|
|
|
function normalizeLifecyclePackageManagerName(value) {
|
|
const normalized = normalizeEnvValue(value).toLowerCase();
|
|
if (!/^[a-z0-9][a-z0-9._-]*$/u.test(normalized)) {
|
|
return null;
|
|
}
|
|
return allowedLifecyclePackageManagers.has(normalized) ? normalized : null;
|
|
}
|
|
|
|
function detectLifecyclePackageManagerFromExecPath(value) {
|
|
const execPath = normalizeEnvValue(value).toLowerCase();
|
|
const executableName = execPath.split(/[\\/]/u).findLast((segment) => segment.length > 0) ?? "";
|
|
const launcherName = executableName.replace(/\.(?:c?js|mjs|cmd|ps1|exe)$/u, "");
|
|
const candidates = [launcherName, launcherName.replace(/-cli$/u, "")];
|
|
|
|
for (const candidate of candidates) {
|
|
if (/^yarn(?:pkg)?-\d/u.test(candidate)) {
|
|
return "yarn";
|
|
}
|
|
|
|
const aliasedPackageManager = lifecyclePackageManagerLauncherAliases.get(candidate);
|
|
if (aliasedPackageManager) {
|
|
return aliasedPackageManager;
|
|
}
|
|
|
|
const packageManager = normalizeLifecyclePackageManagerName(candidate);
|
|
if (packageManager) {
|
|
return packageManager;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Detects the package manager running the current lifecycle script.
|
|
*/
|
|
export function detectLifecyclePackageManager(env = process.env) {
|
|
const userAgent = normalizeEnvValue(env.npm_config_user_agent);
|
|
const userAgentMatch = /^([A-Za-z0-9._-]+)\//u.exec(userAgent);
|
|
if (userAgentMatch) {
|
|
return normalizeLifecyclePackageManagerName(userAgentMatch[1]);
|
|
}
|
|
|
|
return detectLifecyclePackageManagerFromExecPath(env.npm_execpath);
|
|
}
|
|
|
|
/**
|
|
* Builds the warning shown for non-pnpm lifecycle installs.
|
|
*/
|
|
export function createPackageManagerWarningMessage(packageManager) {
|
|
if (!packageManager || packageManager === "pnpm") {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
`[openclaw] warning: detected ${packageManager} for install lifecycle.`,
|
|
"[openclaw] this repo works best with pnpm; npm-compatible installs are slower and much larger here.",
|
|
"[openclaw] prefer: corepack pnpm install",
|
|
].join("\n");
|
|
}
|
|
|
|
/**
|
|
* Emits the non-pnpm lifecycle warning when needed.
|
|
*/
|
|
export function warnIfNonPnpmLifecycle(env = process.env, warn = console.warn) {
|
|
const message = createPackageManagerWarningMessage(detectLifecyclePackageManager(env));
|
|
if (!message) {
|
|
return false;
|
|
}
|
|
warn(message);
|
|
return true;
|
|
}
|
|
|
|
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
|
warnIfNonPnpmLifecycle();
|
|
}
|