11/** @fileoverview Utility for running shell commands with proper error handling. */
22
3- import { spawn , spawnSync } from 'node:child_process '
3+ import { spawn , spawnSync } from '@socketsecurity/lib/spawn '
44
55import { getDefaultLogger } from '@socketsecurity/lib/logger'
66
@@ -13,22 +13,22 @@ const logger = getDefaultLogger()
1313 * @param {object } options - Spawn options
1414 * @returns {Promise<number> } Exit code
1515 */
16- export function runCommand ( command , args = [ ] , options = { } ) {
17- return new Promise ( ( resolve , reject ) => {
18- const child = spawn ( command , args , {
16+ export async function runCommand ( command , args = [ ] , options = { } ) {
17+ try {
18+ const result = await spawn ( command , args , {
1919 stdio : 'inherit' ,
2020 ...( process . platform === 'win32' && { shell : true } ) ,
2121 ...options ,
2222 } )
23-
24- child . on ( 'exit' , code => {
25- resolve ( code || 0 )
26- } )
27-
28- child . on ( 'error' , error => {
29- reject ( error )
30- } )
31- } )
23+ return result . code
24+ } catch ( error ) {
25+ // spawn() from @socketsecurity/lib throws on non-zero exit
26+ // Return the exit code from the error
27+ if ( error && typeof error === 'object' && 'code' in error ) {
28+ return error . code
29+ }
30+ throw error
31+ }
3232}
3333
3434/**
@@ -93,37 +93,38 @@ export async function runParallel(commands) {
9393 * @param {object } options - Spawn options
9494 * @returns {Promise<{exitCode: number, stdout: string, stderr: string}> }
9595 */
96- export function runCommandQuiet ( command , args = [ ] , options = { } ) {
97- return new Promise ( ( resolve , reject ) => {
98- let stdout = ''
99- let stderr = ''
100-
101- const child = spawn ( command , args , {
96+ export async function runCommandQuiet ( command , args = [ ] , options = { } ) {
97+ try {
98+ const result = await spawn ( command , args , {
10299 ...options ,
103100 ...( process . platform === 'win32' && { shell : true } ) ,
104- stdio : [ 'inherit' , 'pipe' , 'pipe' ] ,
105- } )
106-
107- child . stdout ?. on ( 'data' , data => {
108- stdout += data . toString ( )
101+ stdio : 'pipe' ,
102+ stdioString : true ,
109103 } )
110104
111- child . stderr ?. on ( 'data' , data => {
112- stderr += data . toString ( )
113- } )
114-
115- child . on ( 'exit' , code => {
116- resolve ( {
117- exitCode : code || 0 ,
118- stderr,
119- stdout,
120- } )
121- } )
122-
123- child . on ( 'error' , error => {
124- reject ( error )
125- } )
126- } )
105+ return {
106+ exitCode : result . code ,
107+ stderr : result . stderr ,
108+ stdout : result . stdout ,
109+ }
110+ } catch ( error ) {
111+ // spawn() from @socketsecurity/lib throws on non-zero exit
112+ // Return the exit code and output from the error
113+ if (
114+ error &&
115+ typeof error === 'object' &&
116+ 'code' in error &&
117+ 'stdout' in error &&
118+ 'stderr' in error
119+ ) {
120+ return {
121+ exitCode : error . code ,
122+ stderr : error . stderr ,
123+ stdout : error . stdout ,
124+ }
125+ }
126+ throw error
127+ }
127128}
128129
129130/**
0 commit comments