fuzzyworld

auto-print / files / src / util.ts

util.ts

Blame: the commit that last changed each line · file · history

a6d0aed2 2026-10-24 Pavel Safronov1// Small helpers shared by the other modules.
2
3import { spawnSync } from "node:child_process";
4import path from "node:path";
5
6export function fail(message: string): never {
7 throw new Error(message);
8}
9
10/** Runs a command and returns its output. Fails with the command's error output if it does not succeed. */
11export function run(command: string, args: string[], input?: string, timeoutMs = 180_000): string {
12 const result = spawnSync(command, args, { input, encoding: "utf8", timeout: timeoutMs, maxBuffer: 64 * 1024 * 1024 });
13 if (result.error) {
14 const code = (result.error as NodeJS.ErrnoException).code;
15 if (code === "ENOENT") fail(`"${command}" is not installed or not on the PATH.`);
16 fail(`${path.basename(command)} failed: ${result.error.message}`);
17 }
18 if (result.status !== 0) {
19 fail(`${path.basename(command)} exited with code ${result.status}:\n${result.stderr.trim()}`);
20 }
21 return result.stdout;
22}
23
24/** How a file is named in messages: relative to the current folder when it is inside it, otherwise in full. */
25export function displayPath(filePath: string): string {
26 const relative = path.relative(process.cwd(), filePath);
27 return relative && !relative.startsWith("..") && !path.isAbsolute(relative) ? relative : filePath;
28}
29
30export function sleep(milliseconds: number): Promise<void> {
31 return new Promise((resolve) => setTimeout(resolve, milliseconds));
32}