mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-17 04:50:51 +00:00
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { expandHomePrefix } from "./home-dir.js";
|
|
|
|
function resolveWindowsExecutableExtensions(
|
|
executable: string,
|
|
env: NodeJS.ProcessEnv | undefined,
|
|
): string[] {
|
|
if (process.platform !== "win32") {
|
|
return [""];
|
|
}
|
|
if (path.extname(executable).length > 0) {
|
|
return [""];
|
|
}
|
|
return (
|
|
env?.PATHEXT ??
|
|
env?.Pathext ??
|
|
process.env.PATHEXT ??
|
|
process.env.Pathext ??
|
|
".EXE;.CMD;.BAT;.COM"
|
|
)
|
|
.split(";")
|
|
.map((ext) => ext.toLowerCase());
|
|
}
|
|
|
|
export function isExecutableFile(filePath: string): boolean {
|
|
try {
|
|
const stat = fs.statSync(filePath);
|
|
if (!stat.isFile()) {
|
|
return false;
|
|
}
|
|
if (process.platform !== "win32") {
|
|
fs.accessSync(filePath, fs.constants.X_OK);
|
|
}
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function resolveExecutableFromPathEnv(
|
|
executable: string,
|
|
pathEnv: string,
|
|
env?: NodeJS.ProcessEnv,
|
|
): string | undefined {
|
|
const entries = pathEnv.split(path.delimiter).filter(Boolean);
|
|
const extensions = resolveWindowsExecutableExtensions(executable, env);
|
|
for (const entry of entries) {
|
|
for (const ext of extensions) {
|
|
const candidate = path.join(entry, executable + ext);
|
|
if (isExecutableFile(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function resolveExecutablePath(
|
|
rawExecutable: string,
|
|
options?: { cwd?: string; env?: NodeJS.ProcessEnv },
|
|
): string | undefined {
|
|
const expanded = rawExecutable.startsWith("~") ? expandHomePrefix(rawExecutable) : rawExecutable;
|
|
if (expanded.includes("/") || expanded.includes("\\")) {
|
|
if (path.isAbsolute(expanded)) {
|
|
return isExecutableFile(expanded) ? expanded : undefined;
|
|
}
|
|
const base = options?.cwd && options.cwd.trim() ? options.cwd.trim() : process.cwd();
|
|
const candidate = path.resolve(base, expanded);
|
|
return isExecutableFile(candidate) ? candidate : undefined;
|
|
}
|
|
const envPath =
|
|
options?.env?.PATH ?? options?.env?.Path ?? process.env.PATH ?? process.env.Path ?? "";
|
|
return resolveExecutableFromPathEnv(expanded, envPath, options?.env);
|
|
}
|