script-launcher
Version:
Enhance your package.json scripts with features like: menus, functions, arrays, concurrency and many more.
198 lines (197 loc) • 8.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Process = void 0;
const spawn = require("cross-spawn");
const logger_1 = require("./logger");
const common_1 = require("./common");
const prettyTime = require("pretty-time");
class Process {
constructor(childProcess, options) {
this.outputCount = 0;
this._stdout = '';
this._stderr = '';
const startTime = process.hrtime();
this.pid = childProcess.pid;
if (logger_1.Logger.level > 1) {
if (options.testmode) {
logger_1.Logger.log('Process pid : ' + common_1.Colors.Yellow + 11111 + common_1.Colors.Normal);
}
else {
logger_1.Logger.log('Process pid : ' + common_1.Colors.Yellow + childProcess.pid + common_1.Colors.Normal);
}
this.showOutputData(childProcess);
}
else {
if (options.testmode)
this.testOutputData(childProcess);
}
this.exitPromise = new Promise((resolve, reject) => {
try {
childProcess.on('close', (code, signal) => {
setImmediate(() => {
// Proccess all events in event queue, to flush the out streams.
if (childProcess.stdout)
childProcess.stdout.removeAllListeners('data');
if (childProcess.stderr)
childProcess.stderr.removeAllListeners('data');
if (options.suppress)
code = 0;
resolve(code);
});
});
childProcess.on('exit', (code, signal) => {
this._stdout = Process.getStdout(childProcess, options.stdio, this._stdout);
this._stderr = Process.getStderr(childProcess, options.stdio, this._stderr);
const timespan = process.hrtime(startTime);
if (this.outputCount !== 0)
logger_1.Logger.log(''.padEnd(process.stdout.columns, '-'));
const extraInfo = options.extraLogInfo ? ' ' + options.extraLogInfo(this) : '';
if (options.testmode) {
logger_1.Logger.log('Process exited : pid=' + 11111 + ' code=' + code + ' signal=' + signal, ' elapsed=4ms' + extraInfo);
}
else {
logger_1.Logger.log('Process exited : pid=' + childProcess.pid + ' code=' + code + ' signal=' + signal, ' elapsed=' + prettyTime(timespan, 'ms') + extraInfo);
}
logger_1.Logger.log();
logger_1.Logger.log();
});
childProcess.on('error', error => {
this._stdout = Process.getStdout(childProcess, options.stdio, this._stdout);
this._stderr = Process.getStderr(childProcess, options.stdio, this._stderr);
const timespan = process.hrtime(startTime);
if (this.outputCount !== 0)
logger_1.Logger.log(''.padEnd(process.stdout.columns, '-'));
const extraInfo = options.extraLogInfo ? ' ' + options.extraLogInfo(this) : '';
if (options.testmode) {
logger_1.Logger.log('Process error : pid=' + 11111 + ` code=${error}`, ' elapsed=5ms' + extraInfo);
}
else {
logger_1.Logger.log('Process error : pid=' + childProcess.pid + ` code=${error}`, ' elapsed=' + prettyTime(timespan, 'ms') + extraInfo);
}
logger_1.Logger.log();
logger_1.Logger.log();
});
}
catch (error) {
if (this.outputCount !== 0)
logger_1.Logger.log(''.padEnd(process.stdout.columns, '-'));
if (options.testmode) {
logger_1.Logger.error('Process failed : pid=' + 11111 + ` failed to attach event emitters, ${error}.`);
}
else {
logger_1.Logger.error('Process failed : pid=' + childProcess.pid + ` failed to attach event emitters, ${error}.`);
}
logger_1.Logger.log();
logger_1.Logger.log();
reject(error);
}
});
}
get stdout() {
return this._stdout;
}
get stderr() {
return this._stderr;
}
static spawn(command, args, options) {
if ((logger_1.Logger.level > 1 || options.testmode) && options) {
options = Object.assign({}, options);
options.stdio = ['inherit', 'pipe', 'pipe'];
}
if (!command) {
return {
pid: -1,
stderr: '',
stdout: '',
wait: () => __awaiter(this, void 0, void 0, function* () { return 0; })
};
}
if (options.dry) {
logger_1.Logger.info('Dry Command : ' + common_1.Colors.Yellow + "'" + command + ' ' + args.join(' ') + "'" + common_1.Colors.Normal);
return {
pid: -1,
stderr: '',
stdout: '',
wait: () => __awaiter(this, void 0, void 0, function* () { return 0; })
};
}
const childProcess = spawn(command, args, options);
if (options.cwd)
logger_1.Logger.log('Process dir : ' + common_1.Colors.Green + "'" + options.cwd + "'" + common_1.Colors.Normal);
return new Process(childProcess, options);
}
wait() {
return this.exitPromise;
}
static getStdioOption(stdio, index) {
if (typeof stdio === 'string')
return stdio;
if (stdio !== undefined && index < stdio.length)
return stdio[index].toString();
return '';
}
static getStdout(childProcess, stdio, defaultValue) {
if (Process.getStdioOption(stdio, 1) === 'pipe') {
const data = childProcess.stdout.read();
if (data)
return data.toString();
}
return defaultValue;
}
static getStderr(childProcess, stdio, defaultValue) {
if (Process.getStdioOption(stdio, 2) === 'pipe') {
const data = childProcess.stderr.read();
if (data)
return data.toString();
}
return defaultValue;
}
showOutputData(childProcess) {
childProcess.stdout.on('data', data => {
const content = data.toString().trim();
if (content) {
this._stdout += content;
if (this.outputCount === 0)
logger_1.Logger.log(''.padEnd(process.stdout.columns, '-'));
logger_1.Logger.log(common_1.Colors.Dim + content + common_1.Colors.Normal);
this.outputCount++;
}
});
childProcess.stderr.on('data', data => {
const content = data.toString().trim();
if (content) {
this._stderr += content;
if (this.outputCount === 0)
logger_1.Logger.log(''.padEnd(process.stdout.columns, '-'));
logger_1.Logger.log(common_1.Colors.Red + content + common_1.Colors.Normal);
this.outputCount++;
}
});
}
testOutputData(childProcess) {
childProcess.stdout.on('data', data => {
const content = data.toString().trim();
if (content) {
this._stdout += content;
process.stdout.write(content);
}
});
childProcess.stderr.on('data', data => {
const content = data.toString().trim();
if (content) {
this._stderr += content;
process.stderr.write(content);
}
});
}
}
exports.Process = Process;