UNPKG

@ofzza/adventofcode

Version:
174 lines 6.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskResult = exports.Task = void 0; const tslib_1 = require("tslib"); // Dependencies const child_process_1 = require("child_process"); const config_1 = require("../config"); /** * Implements task management and running functinoality */ class Task { constructor(task, custom = {}) { // Set properties this.name = task.name; this.type = task.type; this.command = task.command; this.args = task.args; this.value = task.value; this.runs = task.runs; this.custom = custom; } /** * Gets list of all runnable tasks * @param tasks Array of tasks to run * @param name Start of name of task(s) to run * @param type Type of tasks to run * @returns List of all runnable tasks */ static get({ tasks = [], name = '', type = '' } = {}) { return (tasks.length ? tasks : Object.keys(config_1.Configuration.config.tasks).map(i => parseInt(i) + 1)) .map(i => (config_1.Configuration.config.tasks || []).map(task => (task ? new Task(task) : undefined))[i - 1]) .filter(task => !!task) .filter(task => !name || task.name.startsWith(name)) .filter(task => !type || task.type === type); } /** * Runs requested tasks * @param argv Startup arguments * @param name Start of name of task(s) to run * @param type Type of tasks to run * @param stdoutCallback: (text: string) => void */ static run(argv, stdoutCallback) { return (0, tslib_1.__asyncGenerator)(this, arguments, function* run_1() { // Get filters const tasks = argv.task instanceof Array ? argv.task.map(task => parseInt(task)) : argv.task ? [parseInt(argv.task)] : []; const type = argv.type; const name = argv.name; // Filter tasks to execute for (const task of Task.get({ tasks, type, name })) { // Compose and run multiple runs of the task let taskRuns = !task.runs ? [task] : task.runs.map(run => new Task(Object.assign(Object.assign({}, task), run), run)); for (const taskRun of taskRuns) { // Process dynamic task arguments taskRun.args = taskRun.args.map(arg => { return arg.replace(/\{\{(.*?)\}\}/g, match => { // Parse dynamic argument const expr = match.substr(2, match.length - 4); const parsed = expr.split('??'); const condition = parsed.length > 1 ? parsed[0] : undefined; const syntax = parsed.length > 1 ? parsed[1] : parsed[0]; // Check if argument enabled if (!condition || argv[condition] !== undefined || taskRun.custom[condition] !== undefined || taskRun[condition] !== undefined) { // Replace argument with processed version return syntax .split(' ') .map(s => (!s.startsWith(':') ? s : argv[s.substr(1)] || taskRun.custom[s.substr(1)] || taskRun[s.substr(1)])) .join(' '); } }); }); // Yield task yield yield (0, tslib_1.__await)(yield (0, tslib_1.__await)(taskRun)); // Execute task and yield result yield yield (0, tslib_1.__await)(yield (0, tslib_1.__await)(taskRun.run(stdoutCallback))); } } }); } /** * Gets high resolution time in [ms] * @returns High resolution time in [ms] */ getHRTime() { const time = process.hrtime(); return time[0] * 1000 + time[1] / 1e6; } /** * Execute task * @returns Task execution result * @param stdoutCallback Callback function called on every stdout event */ async run(stdoutCallback) { // Run task and time task execution const time = this.getHRTime(); let timeSpawned = time; let timeStd = time; try { // Run command async and stream stdout and stderr const out = await new Promise(resolve => { try { let out = ''; let err = ''; const proc = (0, child_process_1.spawn)( // Command this.command, // Command arguments this.args, // Process options { cwd: config_1.Configuration.cwd }); proc.on('spawn', () => { timeSpawned = this.getHRTime(); }); proc.stdout.on('data', (data) => { out += data.toString(); stdoutCallback(data.toString()); timeStd = this.getHRTime(); }); proc.stderr.on('data', (data) => { err += data.toString(); stdoutCallback(data.toString()); timeStd = this.getHRTime(); }); proc.on('exit', () => { resolve(out || new Error(err)); }); } catch (err) { resolve(err); } }); // Return execution result const result = out instanceof Error ? out : out .replace(/\[.*?m/g, '') .trim() .split('\n') .slice(-1)[0]; return new TaskResult(this, timeStd - timeSpawned, result, out instanceof Error ? out.message : out); } catch (err) { // Return execution result return new TaskResult(this, timeStd - timeSpawned, err); } } } exports.Task = Task; // TODO: expose isError and isValid getters /** * Contains results from an executed task */ class TaskResult { constructor(task, time, value, output) { this.task = task; this.time = time; this.value = value; this.output = output; } /** * If error was thrown while executing the task command */ get isError() { return this.value instanceof Error; } /** * If returned value matches expected value */ get isValid() { return !(this.value instanceof Error) ? (this.task.value !== undefined ? this.task.value.trim() === this.value.trim() : undefined) : false; } } exports.TaskResult = TaskResult; //# sourceMappingURL=index.js.map