55 lines
1.3 KiB
TypeScript
55 lines
1.3 KiB
TypeScript
import { execSync } from "child_process";
|
|
import fs from "fs";
|
|
import os from "os";
|
|
import path from "path";
|
|
|
|
export type BinaryName = "sling" | "atlas";
|
|
|
|
export interface BinaryInfo {
|
|
path: string;
|
|
version: string;
|
|
}
|
|
|
|
export function resolveBinary(name: BinaryName): string | null {
|
|
try {
|
|
const out = execSync(`which ${name}`, {
|
|
encoding: "utf8",
|
|
stdio: ["pipe", "pipe", "pipe"],
|
|
})
|
|
.trim()
|
|
.split("\n")[0];
|
|
if (out) return out;
|
|
} catch {
|
|
// not on PATH
|
|
}
|
|
if (name === "sling") {
|
|
const fallback = path.join(os.homedir(), ".sling", "bin", "sling");
|
|
if (fs.existsSync(fallback)) return fallback;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function probe(name: BinaryName): BinaryInfo | null {
|
|
const binPath = resolveBinary(name);
|
|
if (!binPath) return null;
|
|
let version = "";
|
|
try {
|
|
version = execSync(
|
|
name === "atlas" ? `"${binPath}" version` : `"${binPath}" --version`,
|
|
{ encoding: "utf8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }
|
|
)
|
|
.trim()
|
|
.split("\n")[0];
|
|
} catch {
|
|
// version probe failed; still report the path
|
|
}
|
|
return { path: binPath, version };
|
|
}
|
|
|
|
export function checkBinaries(): {
|
|
sling: BinaryInfo | null;
|
|
atlas: BinaryInfo | null;
|
|
} {
|
|
return { sling: probe("sling"), atlas: probe("atlas") };
|
|
}
|