UNPKG

process-rerun

Version:

The purpose of this library is - build simple and flexible interface for parallel command execution with rerun (on fail) possibility

80 lines 3.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.execute = execute; exports.getCache = getCache; const node_child_process_1 = require("node:child_process"); const sat_utils_1 = require("sat-utils"); const error_1 = require("../error"); /** * Extracts every shared cache payload emitted by the child process on its stdout. * * A process can publish data back to the runner by printing one or more lines shaped like: * shared-cache: "<json payload here>" * * Each json payload lives inside the double quotes with its own quotes escaped. * Returns an array with one parsed payload per matched line (empty when none are present), * preserving the order in which the process printed them. */ function getCache(output) { if (!(0, sat_utils_1.isString)(output)) return []; const entries = []; for (const match of output.matchAll(/shared-cache:\s*"((?:\\.|[^"\\])*)"/g)) { const raw = match[1]; try { // `raw` is the body of a JSON string literal (inner quotes escaped), // so decode it first, then parse the decoded json payload. const decoded = JSON.parse(`"${raw}"`); try { entries.push(JSON.parse(decoded)); } catch { entries.push(decoded); } } catch { entries.push(raw); } } return entries; } function execute({ cmd, logProcessResult, executionHolder, execOpts = {}, }) { if (!(0, sat_utils_1.isString)(cmd)) { throw new error_1.ProcessRerunError('Type', `cmd (first argument should be a string), current type is ${(0, sat_utils_1.getType)(cmd)}`); } if (!(0, sat_utils_1.isObject)(executionHolder)) { throw new error_1.ProcessRerunError('Type', `executionHolder (third argument should be an object), current type is ${(0, sat_utils_1.getType)(executionHolder)}`); } if (!(0, sat_utils_1.isFunction)(logProcessResult)) { throw new error_1.ProcessRerunError('Type', `executionHolder (second argument should be a function), current type is ${(0, sat_utils_1.getType)(logProcessResult)}`); } const startTime = +Date.now(); let stdout = ''; let stderr = ''; let settled = false; const execProc = (0, node_child_process_1.spawn)(cmd, { ...execOpts, shell: true, detached: process.platform !== 'win32' }); execProc.stdout?.on('data', chunk => { stdout += chunk.toString(); }); execProc.stderr?.on('data', chunk => { stderr += chunk.toString(); }); const finalize = (error) => { if (settled) return; settled = true; logProcessResult(cmd, startTime, execProc, error, stdout, stderr); executionHolder.stackTrace += `${stdout}${stderr}`; // collect every shared-cache line the process printed over its whole lifetime executionHolder.cache = getCache(stdout); }; execProc.on('error', finalize); execProc.on('close', (code, signal) => { const error = code !== 0 && code !== null ? Object.assign(new Error(`Command failed: ${cmd}`), { code, signal }) : null; finalize(error); }); return execProc; } //# sourceMappingURL=index.js.map