nativescript
Version:
Command-line interface for building NativeScript projects
201 lines • 8.36 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChildProcess = void 0;
const child_process = require("child_process");
const path_1 = require("path");
const events_1 = require("events");
const yok_1 = require("./yok");
class ChildProcess extends events_1.EventEmitter {
constructor($logger, $errors) {
super();
this.$logger = $logger;
this.$errors = $errors;
}
async exec(command, options, execOptions) {
return new Promise((resolve, reject) => {
const callback = (error, stdout, stderr) => {
this.$logger.trace("Exec %s \n stdout: %s \n stderr: %s", command, stdout.toString(), stderr.toString());
if (error) {
reject(error);
}
else {
const output = execOptions && execOptions.showStderr ? { stdout, stderr } : stdout;
resolve(output);
}
};
if (options) {
child_process.exec(command, options, callback);
}
else {
child_process.exec(command, callback);
}
});
}
async execFile(command, args) {
this.$logger.trace("execFile: %s %s", command, this.getArgumentsAsQuotedString(args));
return new Promise((resolve, reject) => {
child_process.execFile(command, args, (error, stdout) => {
if (error) {
reject(error);
}
else {
resolve(stdout);
}
});
});
}
spawn(command, args, options) {
var _a;
if (command.charAt(0) === ".") {
// resolve relative paths to full paths to avoid node Spawn ENOENT errors on some setups.
const cwd = (_a = options === null || options === void 0 ? void 0 : options.cwd) !== null && _a !== void 0 ? _a : process.cwd();
command = (0, path_1.resolve)(cwd, command);
}
this.$logger.trace("spawn: %s %s", command, this.getArgumentsAsQuotedString(args));
return child_process.spawn(command, args, options);
}
fork(modulePath, args, options) {
this.$logger.trace("fork: %s %s", modulePath, this.getArgumentsAsQuotedString(args));
return child_process.fork(modulePath, args, options);
}
spawnFromEvent(command, args, event, options, spawnFromEventOptions) {
// event should be exit or close
return new Promise((resolve, reject) => {
const childProcess = this.spawn(command, args, options);
let isResolved = false;
let capturedOut = "";
let capturedErr = "";
let killTimer = null;
if (spawnFromEventOptions && spawnFromEventOptions.timeout) {
this.$logger.trace(`Setting maximum time for execution of current child process to ${spawnFromEventOptions.timeout}`);
killTimer = setTimeout(() => {
this.$logger.trace(`Sending SIGTERM to current child process as maximum time for execution ${spawnFromEventOptions.timeout} had passed.`);
childProcess.kill("SIGTERM");
}, spawnFromEventOptions.timeout);
}
if (childProcess.stdout) {
childProcess.stdout.on("data", (data) => {
if (spawnFromEventOptions &&
spawnFromEventOptions.emitOptions &&
spawnFromEventOptions.emitOptions.eventName) {
this.emit(spawnFromEventOptions.emitOptions.eventName, {
data,
pipe: "stdout",
});
}
capturedOut += data;
});
}
if (childProcess.stderr) {
childProcess.stderr.on("data", (data) => {
if (spawnFromEventOptions &&
spawnFromEventOptions.emitOptions &&
spawnFromEventOptions.emitOptions.eventName) {
this.emit(spawnFromEventOptions.emitOptions.eventName, {
data,
pipe: "stderr",
});
}
capturedErr += data;
});
}
childProcess.on(event, (arg) => {
const exitCode = typeof arg === "number" ? arg : arg && arg.code;
const result = {
stdout: capturedOut,
stderr: capturedErr,
exitCode: exitCode,
};
const clearKillTimer = () => {
if (killTimer) {
clearTimeout(killTimer);
}
};
const resolveAction = () => {
isResolved = true;
resolve(result);
clearKillTimer();
};
if (spawnFromEventOptions &&
spawnFromEventOptions.throwError === false) {
if (!isResolved) {
this.$logger.trace("Result when throw error is false:");
this.$logger.trace(result);
resolveAction();
}
}
else {
if (exitCode === 0) {
resolveAction();
}
else {
let errorMessage = `Command ${command} failed with exit code ${exitCode}`;
if (capturedErr) {
errorMessage += ` Error output: \n ${capturedErr}`;
}
if (!isResolved) {
isResolved = true;
reject(new Error(errorMessage));
clearKillTimer();
}
}
}
});
childProcess.once("error", (err) => {
if (!isResolved) {
if (spawnFromEventOptions &&
spawnFromEventOptions.throwError === false) {
const result = {
stdout: capturedOut,
stderr: err.message,
exitCode: err.code,
};
isResolved = true;
resolve(result);
}
else {
isResolved = true;
reject(err);
}
}
});
});
}
async trySpawnFromCloseEvent(command, args, options, spawnFromEventOptions) {
try {
const childProcessResult = await this.spawnFromEvent(command, args, "close", options, spawnFromEventOptions);
return childProcessResult;
}
catch (err) {
this.$logger.trace(`Error from trySpawnFromCloseEvent method. More info: ${err}`);
return Promise.resolve({
stderr: err && err.message ? err.message : err,
stdout: null,
exitCode: -1,
});
}
}
async tryExecuteApplication(command, args, event, errorMessage, condition) {
const childProcess = await this.tryExecuteApplicationCore(command, args, event, errorMessage);
if (condition && condition(childProcess)) {
this.$errors.fail(errorMessage);
}
}
async tryExecuteApplicationCore(command, args, event, errorMessage) {
try {
return this.spawnFromEvent(command, args, event, undefined, {
throwError: false,
});
}
catch (e) {
const message = e.code === "ENOENT" ? errorMessage : e.message;
this.$errors.fail(message);
}
}
getArgumentsAsQuotedString(args) {
return (args && args.length && args.map((argument) => `"${argument}"`).join(" "));
}
}
exports.ChildProcess = ChildProcess;
yok_1.injector.register("childProcess", ChildProcess);
//# sourceMappingURL=child-process.js.map
;