hereby
Version:
A simple task runner
52 lines • 1.96 kB
JavaScript
import { performance } from "node:perf_hooks";
import * as style from "./style.js";
import { prettyMilliseconds } from "./utils.js";
export class Runner {
constructor(_d) {
this._d = _d;
this._addedTasks = new Map();
this.failedTasks = [];
}
async runTasks(...tasks) {
// Using allSettled here so that we don't immediately exit; it could be
// the case that a task has code that needs to run before, e.g. a
// cleanup function in a "finally" or something.
const results = await Promise.allSettled(tasks.map((task) => {
let promise = this._addedTasks.get(task);
if (!promise)
this._addedTasks.set(task, promise = this._runTask(task));
return promise;
}));
const rejected = results.find((result) => result.status === "rejected");
if (rejected)
throw rejected.reason;
}
async _runTask(task) {
const { dependencies, run } = task.options;
if (dependencies) {
await this.runTasks(...dependencies);
}
if (!run)
return;
const start = performance.now();
try {
if (this.failedTasks.length === 0) {
this._d.log(`Starting ${style.blue(task.options.name)}`);
}
await run();
if (this.failedTasks.length === 0) {
const took = performance.now() - start;
this._d.log(`Finished ${style.green(task.options.name)} in ${prettyMilliseconds(took)}`);
}
}
catch (e) {
this.failedTasks.push(task.options.name);
if (this.failedTasks.length === 1) {
const took = performance.now() - start;
this._d.error(`Error in ${style.red(task.options.name)} in ${prettyMilliseconds(took)}\n${e}`);
}
throw e;
}
}
}
//# sourceMappingURL=runner.js.map