@@ -103,6 +103,7 @@ export type ProcessConfig = Omit<
103103 args ?: string [ ] ;
104104 observer ?: ProcessObserver ;
105105 ignoreExitCode ?: boolean ;
106+ silent ?: boolean ;
106107} ;
107108
108109/**
@@ -127,6 +128,9 @@ export type ProcessObserver = {
127128/**
128129 * Executes a process and returns a promise with the result as `ProcessResult`.
129130 *
131+ * By default, displays a spinner via `logger.command()`. Use `silent: true` to bypass
132+ * the spinner for commands that may run concurrently (e.g., plugin setup steps).
133+ *
130134 * @example
131135 *
132136 * // sync process execution
@@ -153,62 +157,72 @@ export type ProcessObserver = {
153157 * @param cfg - see {@link ProcessConfig}
154158 */
155159export function executeProcess ( cfg : ProcessConfig ) : Promise < ProcessResult > {
156- const { command, args, observer, ignoreExitCode = false , ...options } = cfg ;
160+ const {
161+ command,
162+ args,
163+ observer,
164+ ignoreExitCode = false ,
165+ silent = false ,
166+ ...options
167+ } = cfg ;
157168 const { onStdout, onStderr, onError, onComplete } = observer ?? { } ;
158169
159170 const bin = [ command , ...( args ?? [ ] ) ] . join ( ' ' ) ;
160171
161- return logger . command (
162- bin ,
163- ( ) =>
164- new Promise ( ( resolve , reject ) => {
165- const spawnedProcess = spawn ( command , args ?? [ ] , {
166- // shell:true tells Windows to use shell command for spawning a child process
167- // https://stackoverflow.com/questions/60386867/node-spawn-child-process-not-working-in-windows
168- shell : true ,
169- windowsHide : true ,
170- ...options ,
171- } ) as ChildProcessByStdio < Writable , Readable , Readable > ;
172-
173- // eslint-disable-next-line functional/no-let
174- let stdout = '' ;
175- // eslint-disable-next-line functional/no-let
176- let stderr = '' ;
177- // eslint-disable-next-line functional/no-let
178- let output = '' ; // interleaved stdout and stderr
179-
180- spawnedProcess . stdout . on ( 'data' , ( data : unknown ) => {
181- const message = String ( data ) ;
182- stdout += message ;
183- output += message ;
184- onStdout ?.( message , spawnedProcess ) ;
185- } ) ;
186-
187- spawnedProcess . stderr . on ( 'data' , ( data : unknown ) => {
188- const message = String ( data ) ;
189- stderr += message ;
190- output += message ;
191- onStderr ?.( message , spawnedProcess ) ;
192- } ) ;
193-
194- spawnedProcess . on ( 'error' , error => {
172+ const worker = ( ) =>
173+ new Promise < ProcessResult > ( ( resolve , reject ) => {
174+ const spawnedProcess = spawn ( command , args ?? [ ] , {
175+ // shell:true tells Windows to use shell command for spawning a child process
176+ // https://stackoverflow.com/questions/60386867/node-spawn-child-process-not-working-in-windows
177+ shell : true ,
178+ windowsHide : true ,
179+ ...options ,
180+ } ) as ChildProcessByStdio < Writable , Readable , Readable > ;
181+
182+ // eslint-disable-next-line functional/no-let
183+ let stdout = '' ;
184+ // eslint-disable-next-line functional/no-let
185+ let stderr = '' ;
186+ // eslint-disable-next-line functional/no-let
187+ let output = '' ; // interleaved stdout and stderr
188+
189+ spawnedProcess . stdout . on ( 'data' , ( data : unknown ) => {
190+ const message = String ( data ) ;
191+ stdout += message ;
192+ output += message ;
193+ onStdout ?.( message , spawnedProcess ) ;
194+ } ) ;
195+
196+ spawnedProcess . stderr . on ( 'data' , ( data : unknown ) => {
197+ const message = String ( data ) ;
198+ stderr += message ;
199+ output += message ;
200+ onStderr ?.( message , spawnedProcess ) ;
201+ } ) ;
202+
203+ spawnedProcess . on ( 'error' , error => {
204+ reject ( error ) ;
205+ } ) ;
206+
207+ spawnedProcess . on ( 'close' , ( code , signal ) => {
208+ const result : ProcessResult = { bin, code, signal, stdout, stderr } ;
209+ if ( code === 0 || ignoreExitCode ) {
210+ logger . debug ( output ) ;
211+ onComplete ?.( ) ;
212+ resolve ( result ) ;
213+ } else {
214+ // ensure stdout and stderr are logged to help debug failure
215+ logger . debug ( output , { force : true } ) ;
216+ const error = new ProcessError ( result ) ;
217+ onError ?.( error ) ;
195218 reject ( error ) ;
196- } ) ;
197-
198- spawnedProcess . on ( 'close' , ( code , signal ) => {
199- const result : ProcessResult = { bin, code, signal, stdout, stderr } ;
200- if ( code === 0 || ignoreExitCode ) {
201- logger . debug ( output ) ;
202- onComplete ?.( ) ;
203- resolve ( result ) ;
204- } else {
205- // ensure stdout and stderr are logged to help debug failure
206- logger . debug ( output , { force : true } ) ;
207- const error = new ProcessError ( result ) ;
208- onError ?.( error ) ;
209- reject ( error ) ;
210- }
211- } ) ;
212- } ) ,
213- ) ;
219+ }
220+ } ) ;
221+ } ) ;
222+
223+ if ( silent ) {
224+ return worker ( ) ;
225+ }
226+
227+ return logger . command ( bin , worker ) ;
214228}
0 commit comments