UNPKG

alwaysai

Version:

The alwaysAI command-line interface (CLI)

62 lines (53 loc) 1.75 kB
import { spawn } from 'child_process'; import signalExit = require('signal-exit'); import * as chalk from 'chalk'; import { CliTerseError } from '@alwaysai/alwayscli'; import { Cmd } from '../types'; import { logger } from '../../logger'; export const PROCESS_EXITED_WITH_NON_ZERO_STATUS_CODE = 'Process exited with non-zero status code'; export async function run(cmd: Cmd) { return new Promise<string>((resolve, reject) => { const optString = cmd.args ? cmd.args.join(' ') : ''; logger.debug(`${cmd.exe} ${optString}`); const child = spawn(cmd.exe, cmd.args ?? [], { cwd: cmd.cwd }); signalExit(() => { child.kill(); }); if (cmd.input) { cmd.input.pipe(child.stdin); } // TODO: Limit buffer size const outChunks: Buffer[] = []; const allChunks: Buffer[] = []; // stderr and stdout child.stdout.on('data', (chunk) => { outChunks.push(chunk); allChunks.push(chunk); }); child.stderr.on('data', (chunk) => { allChunks.push(chunk); }); child.on('error', (err) => { reject(err); }); child.on('close', (code) => { if (code === 0) { const str = Buffer.concat(outChunks).toString('utf8'); if (str.endsWith('\n')) { resolve(str.slice(0, -1)); } else { resolve(str); } } else if (code !== null) { let message = `${PROCESS_EXITED_WITH_NON_ZERO_STATUS_CODE} ${chalk.bold( code.toString() )}`; message += '\n\n'; message += `$ ${cmd.exe} ${cmd.args ? cmd.args.join(' ') : ''}`; message += '\n\n'; message += Buffer.concat(allChunks).toString('utf8'); reject(new CliTerseError(message)); } }); }); }