blob: 1d09304991dd589420cd28bc113b620eb6ccd94f [file] [log] [blame]
import { spawn } from 'node:child_process';
/** @import {SpawnOptions} from 'node:child_process' */
/**
* Execute a command
* @param {string} command The command to execute
* @param {readonly string[]} args The arguments to pass
* @param {Omit<SpawnOptions, 'shell'>} [opts] The options to pass to spawnSync
* @returns {Promise<string>} The output from the command
*/
export default async (command, args, opts) =>
new Promise((resolve, reject) => {
const child = spawn(command, args, { ...opts, shell: false });
let stdout = '';
let stderr = '';
if (child.stdout) {
child.stdout.setEncoding('utf8');
child.stdout.on('data', (chunk) => {
stdout += chunk;
});
}
if (child.stderr) {
child.stderr.setEncoding('utf8');
child.stderr.on('data', (chunk) => {
stderr += chunk;
});
}
child.on('error', (err) => reject(err));
child.on('close', (code) =>
code == 0
? resolve(stdout.trim())
: reject(
new Error(
`The command '${command}' exited with code ${code}: ${stderr.trim()}`,
),
),
);
});