@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
78 lines • 3.53 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.stdioCaptureProcessor = stdioCaptureProcessor;
exports.waitOnScript = waitOnScript;
const child_process_1 = __importDefault(require("child_process"));
const readline_1 = __importDefault(require("readline"));
const assert_1 = require("../../util/assert");
const log_1 = require("../../util/log");
/**
* Simply captures the output of the script executed by {@link waitOnScript}.
*
* @param stdio - The standard io tuple provided by {@link waitOnScript}
* @param onStdOutLine - The callback is executed each time we receive a new line from the standard output channel.
* @param onStdErrLine - The callback is executed each time we receive a new line from the standard error channel.
*/
function stdioCaptureProcessor(stdio, onStdOutLine, onStdErrLine) {
(0, assert_1.guard)(stdio[1] !== null, 'no stdout given in stdio!');
const outRl = readline_1.default.createInterface({
input: stdio[1],
terminal: false
});
(0, assert_1.guard)(stdio[2] !== null, 'no stderr given in stdio!');
const errRl = readline_1.default.createInterface({
input: stdio[2],
terminal: false
});
outRl.on('line', onStdOutLine);
errRl.on('line', onStdErrLine);
}
/**
* Run the given module with the presented arguments, and wait for it to exit.
*
* @param module - The (flowR) module that you want to use for the fork.
* It is probably best to use {@link __dirname} so you can specify the module relative to your
* current one.
* @param args - The arguments you want to start your process with.
* @param io - If you omit this argument, the in-, out- and error-channels of the script execution
* will be automatically forwarded to the respective in-, out- and error-channels of your process.
* However, by defining `io` you essentially gain full control on what should happen
* with these streams. For a simple capturing processor, for example if you want to collect
* the output of the script, see {@link stdioCaptureProcessor}.
* @param exitOnError - If set to `true`, the process will exit with the exit code of the script.
*/
async function waitOnScript(module, args, io, exitOnError = false) {
log_1.log.info(`starting script ${module} with args ${JSON.stringify(args)}`);
const child = child_process_1.default.fork(module, args, {
silent: io !== undefined
});
if (io !== undefined) {
io(child.stdio);
}
child.on('exit', (code, signal) => {
if (code) {
console.error(`Script ${module} exited with code ${String(code)} and signal ${JSON.stringify(signal)}`);
if (exitOnError) {
process.exit(code);
}
}
});
child.on('error', err => {
console.error(`Script ${module} signaled error ${JSON.stringify(err)}`);
if (exitOnError) {
process.exit(1);
}
});
await new Promise((resolve, reject) => child.on('exit', code => {
if (exitOnError && code) {
reject(new Error(`Script ${module} exited with code ${String(code)}`));
}
else {
resolve();
}
}));
}
//# sourceMappingURL=execute.js.map