Files
clawdbot/src/infra/brew.ts
2026-01-07 00:18:07 +01:00

75 lines
2.0 KiB
TypeScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
function isExecutable(filePath: string): boolean {
try {
fs.accessSync(filePath, fs.constants.X_OK);
return true;
} catch {
return false;
}
}
function normalizePathValue(value: unknown): string | undefined {
if (typeof value !== "string") return undefined;
const trimmed = value.trim();
return trimmed ? trimmed : undefined;
}
export function resolveBrewPathDirs(opts?: {
homeDir?: string;
env?: NodeJS.ProcessEnv;
}): string[] {
const homeDir = opts?.homeDir ?? os.homedir();
const env = opts?.env ?? process.env;
const dirs: string[] = [];
const prefix = normalizePathValue(env.HOMEBREW_PREFIX);
if (prefix) {
dirs.push(path.join(prefix, "bin"), path.join(prefix, "sbin"));
}
// Linuxbrew defaults.
dirs.push(path.join(homeDir, ".linuxbrew", "bin"));
dirs.push(path.join(homeDir, ".linuxbrew", "sbin"));
dirs.push(
"/home/linuxbrew/.linuxbrew/bin",
"/home/linuxbrew/.linuxbrew/sbin",
);
// macOS defaults (also used by some Linux setups).
dirs.push("/opt/homebrew/bin", "/usr/local/bin");
return dirs;
}
export function resolveBrewExecutable(opts?: {
homeDir?: string;
env?: NodeJS.ProcessEnv;
}): string | undefined {
const homeDir = opts?.homeDir ?? os.homedir();
const env = opts?.env ?? process.env;
const candidates: string[] = [];
const brewFile = normalizePathValue(env.HOMEBREW_BREW_FILE);
if (brewFile) candidates.push(brewFile);
const prefix = normalizePathValue(env.HOMEBREW_PREFIX);
if (prefix) candidates.push(path.join(prefix, "bin", "brew"));
// Linuxbrew defaults.
candidates.push(path.join(homeDir, ".linuxbrew", "bin", "brew"));
candidates.push("/home/linuxbrew/.linuxbrew/bin/brew");
// macOS defaults.
candidates.push("/opt/homebrew/bin/brew", "/usr/local/bin/brew");
for (const candidate of candidates) {
if (isExecutable(candidate)) return candidate;
}
return undefined;
}