function wait<T>(
time: number,
msg?: T,
reject = false,
id?: any,
): [Promise<T>, () => void] {
function makeResolver(action: (arg: any) => void) {
//prettier-ignore
id = setTimeout(() => action(msg), time);
}
return [
new Promise((resolver, rejecter) =>
makeResolver(reject ? rejecter : resolver)
),
() => clearTimeout(id),
];
}
/**
* withTimeout returns a new promise that resolves when the promise resolves or the timeout occurs.
*
* NOTE: Deno has issues with inferring generics see https://github.com/denoland/deno/issues/3997.
* For now, just pass explicit generic parameters
* @param ms specify timeout in milliseconds
* @param promise a function that returns a promise. Be sure to call bind if it is a method.
* @param timoutMsg Specify an object to return if the timeout occurs
*/
export async function withTimeout<V, TO>(
ms: number,
promise: () => Promise<V>,
timoutMsg?: TO,
rejectOnTimeout = false,
): Promise<V | TO> {
const [waiting, cancel] = wait(ms, timoutMsg, rejectOnTimeout);
const result = await Promise.race([promise(), waiting]);
cancel();
return result as V | TO;
}
const timeoutMsg: Deno.ProcessStatus = {
success: false,
code: 0,
signal: 255,
};
function isTimeoutMessage(x: any) {
return x.success === false && x.signal === 255;
}
//////////// BEGIN MAIN CODE //////////
const p = new Deno.Command("deno", {
args: cmdArgs,
stderr: spec.quiet ? "piped" : "inherit",
stdout: "piped",
}).spawn();
const out = await withTimeout(15e3, p.output.bind(p), timeoutMsg);
if (isTimeoutMessage(out)) {
p.kill();
throw new Error("Config program timed out.");
}
const s = await p.status;
if (!s.success) {
if (spec.quiet) console.error(p.stderr);
throw new Error("Config program threw an Error");
}
const _yamlText = new TextDecoder().decode(p.stdout);