76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
|
|
import { createLog } from '../log';
|
|
import type { Logger } from 'winston';
|
|
import { EOL } from 'os';
|
|
|
|
export class Shell {
|
|
private child : ChildProcessWithoutNullStreams;
|
|
private log : Logger;
|
|
private bin : string;
|
|
private args : any[];
|
|
private opts : any = {};
|
|
private lines : string[] = [];
|
|
private stdio : Function = null;
|
|
private stderr : Function = null;
|
|
private after : Function = null;
|
|
private silent : boolean = false;
|
|
|
|
constructor (args : any[], env : any = null, stdio : Function = null, stderr : Function = null, after : Function = null, silent : boolean = false) {
|
|
const bin : string = args.shift();
|
|
if (env !== null) this.opts = { env };
|
|
this.bin = bin;
|
|
this.args = args;
|
|
this.stdio = stdio;
|
|
this.stderr = stderr;
|
|
this.silent = silent;
|
|
this.after = after;
|
|
if (!this.silent) this.log = createLog(bin);
|
|
}
|
|
|
|
public async execute () : Promise<number> {
|
|
return new Promise((resolve : Function, reject : Function) => {
|
|
this.child = spawn(this.bin, this.args);
|
|
|
|
if (!this.silent) this.log.info(`Shell: ${this.bin} ${this.args.join(' ')}`);
|
|
|
|
this.child.stdout.on('data', (data : string) => {
|
|
if (!this.silent) this.log.info(data.toString());
|
|
if (this.after !== null) this.lines.push(data);
|
|
if (this.stdio !== null) {
|
|
let lines : string[] = data.toString().split(EOL).filter( el => el.trim() !== '');
|
|
for (let line of lines) {
|
|
this.stdio(line);
|
|
}
|
|
}
|
|
});
|
|
|
|
this.child.stderr.on('data', (data : string) => {
|
|
if (!this.silent) this.log.warn(data.toString());
|
|
if (this.stderr !== null) {
|
|
this.stderr(data.toString());
|
|
}
|
|
});
|
|
|
|
this.child.on('close', (code : number) => {
|
|
if (this.after !== null) {
|
|
this.after(this.lines.join(EOL));
|
|
}
|
|
if (code === 0) {
|
|
if (!this.silent) this.log.info(`Complete: ${this.bin} ${this.args.join(' ')}`);
|
|
return resolve(code);
|
|
} else {
|
|
if (!this.silent) this.log.error(`Error executing: ${this.bin} ${this.args.join(' ')}`);
|
|
return reject(code);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
public kill () {
|
|
if (!this.silent) this.log.warn(`Killing: ${this.bin} ${this.args.join(' ')}`);
|
|
//this.child.stdin.pause();
|
|
this.child.kill();
|
|
}
|
|
}
|
|
|
|
module.exports = { Shell }; |