repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
scripts/lib/common.ts
Rawimport { type SpawnSyncReturns, spawnSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
import { dirname, relative, resolve } from "node:path";
import { fileURLToPath } from "node:url";
export const ROOT: string = resolve(
dirname(fileURLToPath(import.meta.url)),
"../..",
);
export function readJson(path: string): unknown {
return JSON.parse(readFileSync(path, "utf8"));
}
export function writeJson(path: string, data: unknown): void {
writeFileSync(path, `${JSON.stringify(data, null, "\t")}\n`, "utf8");
}
export interface RunOptions {
cwd?: string;
capture?: boolean;
env?: NodeJS.ProcessEnv;
timeout?: number;
check?: boolean;
}
export type RunResult = SpawnSyncReturns<string>;
interface RunError extends Error {
code?: string;
result?: RunResult;
}
export function run(
cmd: string,
args: string[] = [],
options: RunOptions = {},
): RunResult {
const result = spawnSync(cmd, args, {
cwd: options.cwd ?? ROOT,
encoding: "utf8",
stdio: options.capture ? ["ignore", "pipe", "pipe"] : "inherit",
env: options.env ?? process.env,
timeout: options.timeout,
});
if (result.error && (result.error as RunError).code !== "ENOENT")
throw result.error;
if (options.check !== false && result.status !== 0) {
const err = new Error(
`${cmd} ${args.join(" ")} exited ${result.status ?? result.signal ?? (result.error as RunError | undefined)?.code}`,
) as RunError;
err.result = result;
throw err;
}
return result;
}
export function git(args: string[], options: RunOptions = {}): RunResult {
return run("git", args, { ...options, cwd: ROOT });
}
export function rel(path: string, root: string = ROOT): string {
return relative(root, path).replaceAll("\\", "/");
}
export function stripAnsi(text: string): string {
return text
.replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, "")
.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "")
.trim();
}