@znode/execa
Version:
Node.js Exec Sub Shell
165 lines (164 loc) • 5.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.runShell = exports.spawn = exports.kill = exports.unsafe = exports.cd = exports.exec = void 0;
const fs = require("fs");
const cp = require("child_process");
const psTree = require("ps-tree");
const exit_codes_1 = require("@znode/exit-codes");
const event_1 = require("@zodash/event");
const execa_1 = require("./execa");
const utils_1 = require("./utils");
async function exec(cmd, options) {
return new Promise((resolve, reject) => {
var _a, _b;
let it = null;
// @TIMEOUT register
if (options.timeout) {
it = setTimeout(() => {
if (it) {
clearTimeout(it);
it = null;
}
return reject(new Error(`Execute timeout (command: ${cmd}, code: 1)`));
}, options.timeout);
}
const child = cp.exec(execa_1.$.prefix + cmd, options);
let stdout = '', stderr = '', combined = '';
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
if (options.verbose)
process.stdout.write(data);
stdout += data;
combined += data;
});
(_b = child.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
if (options.verbose)
process.stderr.write(data);
stderr += data;
combined += data;
});
child.on('exit', (code) => {
const output = new utils_1.ProcessOutput({
code,
stdout,
stderr,
combined,
__from: options.__from,
});
let response = output.toString();
// remove last \n
if (response[response.length - 1] === '\n') {
response = response.slice(0, response.length - 1);
}
// @TIMEOUT clear
if (it) {
clearTimeout(it);
it = null;
}
if (code === 0) {
return resolve(response);
}
const message = `${response}(command: ${cmd}, code: ${code})` ||
exit_codes_1.default(code);
return reject(new Error(message));
});
});
}
exports.exec = exec;
function cd(path) {
var _a;
if (execa_1.$.verbose)
console.info('$', utils_1.colorize(`cd ${path}`));
if (!fs.existsSync(path)) {
const __from = (_a = new Error().stack) === null || _a === void 0 ? void 0 : _a.split(/^\s*at\s/m)[2].trim();
// console.error(`cd: ${path}: No such directory`);
// console.error(` at ${__from}`);
// process.exit(1);
const message = [
`cd: ${path}: No such directory`,
` at ${__from}`,
].join('\n');
throw new Error(message);
}
execa_1.$.cwd = path;
}
exports.cd = cd;
async function unsafe(pieces, ...args) {
const origin = execa_1.$.strict;
execa_1.$.strict = false;
const response = await execa_1.$(pieces, ...args);
execa_1.$.strict = origin;
return response;
}
exports.unsafe = unsafe;
async function kill(pid) {
const signal = 'SIGTERM';
const children = await new Promise((resolve, reject) => {
psTree(pid, (error, children) => {
if (error)
return reject(error);
return resolve(children);
});
});
for (const p of children) {
try {
process.kill(p.PID, signal);
}
catch (e) {
//
}
}
}
exports.kill = kill;
function spawn(cmd) {
var _a, _b;
const emitter = new event_1.Event();
let error = '';
const child = cp.spawn(execa_1.$.prefix + cmd, {
windowsHide: true,
stdio: ['inherit', 'pipe', 'pipe'],
shell: typeof execa_1.$.shell === 'string' ? execa_1.$.shell : true,
cwd: execa_1.$.cwd,
});
emitter.pid = child.pid;
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
emitter.emit('data', data);
});
(_b = child.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
error += data;
// git clone writes to sderr, fine but why can't I redirect to stdout
// https://stackoverflow.com/questions/32685568/git-clone-writes-to-sderr-fine-but-why-cant-i-redirect-to-stdout
emitter.emit('data', data);
});
child.on('exit', (code) => {
if (code !== 0) {
emitter.emit('error', new Error(`${error.slice(0, error.length - 1)}(cmd: ${cmd}, code: ${code})`));
}
emitter.emit('exit', code);
});
return emitter;
}
exports.spawn = spawn;
async function runShell(command, options) {
if (options === null || options === void 0 ? void 0 : options.env) {
for (const key in options.env) {
process.env[key] = '' + options.env[key];
}
}
return new Promise((resolve, reject) => {
const child = cp.spawn(command, {
shell: true,
stdio: 'inherit',
cwd: (options === null || options === void 0 ? void 0 : options.cwd) || execa_1.$.cwd,
});
// child.on('data', e => console.log('daa:', e));
child.on('exit', (code) => {
if (code !== 0)
return reject(`run command error (command: ${command}, code: ${code})`);
resolve();
});
child.on('error', (error) => {
return reject(`run command error (command: ${command}, error: ${error === null || error === void 0 ? void 0 : error.message})`);
});
});
}
exports.runShell = runShell;