13
13
// limitations under the License.
14
14
15
15
import assert from 'node:assert'
16
- import { ChildProcess , spawn , StdioNull , StdioPipe } from 'node:child_process'
16
+ import { spawn , StdioNull , StdioPipe } from 'node:child_process'
17
17
import { AsyncLocalStorage , createHook } from 'node:async_hooks'
18
18
import { Readable , Writable } from 'node:stream'
19
19
import { inspect } from 'node:util'
20
20
import {
21
- TZurkShellResponse ,
22
- zurk$ ,
21
+ exec ,
23
22
buildCmd ,
24
23
chalk ,
25
24
which ,
@@ -155,7 +154,6 @@ type Resolve = (out: ProcessOutput) => void
155
154
type IO = StdioPipe | StdioNull
156
155
157
156
export class ProcessPromise extends Promise < ProcessOutput > {
158
- child ?: ChildProcess
159
157
private _command = ''
160
158
private _from = ''
161
159
private _resolve : Resolve = noop
@@ -165,11 +163,11 @@ export class ProcessPromise extends Promise<ProcessOutput> {
165
163
private _nothrow ?: boolean
166
164
private _quiet ?: boolean
167
165
private _timeout ?: number
168
- private _timeoutSignal ?: string
166
+ private _timeoutSignal = 'SIGTERM'
169
167
private _resolved = false
170
168
private _halted = false
171
169
private _piped = false
172
- private _zurk : TZurkShellResponse | null = null
170
+ private zurk : ReturnType < typeof exec > | null = null
173
171
_prerun = noop
174
172
_postrun = noop
175
173
@@ -199,72 +197,76 @@ export class ProcessPromise extends Promise<ProcessOutput> {
199
197
verbose : self . isVerbose ( ) ,
200
198
} )
201
199
202
- this . _zurk = zurk$ ( {
200
+ this . zurk = exec ( {
203
201
cmd : $ . prefix + this . _command ,
204
202
cwd : $ . cwd ?? $ [ processCwd ] ,
205
203
shell : typeof $ . shell === 'string' ? $ . shell : true ,
206
204
env : $ . env ,
207
205
spawn : $ . spawn ,
208
- quote : < T > ( v : T ) : T => v , // let zx handle quoting
209
206
stdio : this . _stdio as any ,
210
207
sync : false ,
211
- nothrow : true ,
212
- nohandle : true ,
213
208
detached : ! isWin ,
214
- onStdout ( data : any ) {
215
- // If process is piped, don't print output.
216
- if ( self . _piped ) return
217
- $ . log ( { kind : 'stdout' , data, verbose : self . isVerbose ( ) } )
218
- } ,
219
- onStderr ( data : any ) {
220
- // Stderr should be printed regardless of piping.
221
- $ . log ( { kind : 'stderr' , data, verbose : self . isVerbose ( ) } )
222
- } ,
223
209
run : ( cb ) => cb ( ) ,
224
- timeout : self . _timeout ,
225
- timeoutSignal : self . _timeoutSignal as NodeJS . Signals ,
226
- } ) ( ) as TZurkShellResponse
227
-
228
- this . child = this . _zurk . _ctx . child as ChildProcess
229
-
230
- this . _zurk . finally ( ( ) => ( self . _resolved = true ) )
231
- this . _zurk . then ( ( { error, stdout, stderr, stdall, status, signal } ) => {
232
- if ( error ) {
233
- const message = ProcessOutput . getErrorMessage ( error , self . _from )
234
- // Should we enable this?
235
- // (nothrow ? self._resolve : self._reject)(
236
- self . _reject (
237
- new ProcessOutput ( null , null , stdout , stderr , stdall , message )
238
- )
239
- } else {
240
- const message = ProcessOutput . getExitMessage (
241
- status ,
242
- signal ,
243
- stderr ,
244
- self . _from
245
- )
246
- const output = new ProcessOutput (
247
- status ,
248
- signal ,
249
- stdout ,
250
- stderr ,
251
- stdall ,
252
- message
253
- )
254
-
255
- if ( status === 0 || ( self . _nothrow ?? $ . nothrow ) ) {
256
- self . _resolve ( output )
257
- } else {
258
- self . _reject ( output )
259
- }
260
- }
210
+ on : {
211
+ start : ( ) => {
212
+ if ( self . _timeout ) {
213
+ const t = setTimeout ( ( ) => self . kill ( self . _timeoutSignal ) , self . _timeout )
214
+ self . finally ( ( ) => clearTimeout ( t ) ) . catch ( noop )
215
+ }
216
+ } ,
217
+ stdout : ( data ) => {
218
+ // If process is piped, don't print output.
219
+ if ( self . _piped ) return
220
+ $ . log ( { kind : 'stdout' , data, verbose : self . isVerbose ( ) } )
221
+ } ,
222
+ stderr : ( data ) => {
223
+ // Stderr should be printed regardless of piping.
224
+ $ . log ( { kind : 'stderr' , data, verbose : self . isVerbose ( ) } )
225
+ } ,
226
+ end : ( { error, stdout, stderr, stdall, status, signal } ) => {
227
+ self . _resolved = true
228
+
229
+ if ( error ) {
230
+ const message = ProcessOutput . getErrorMessage ( error , self . _from )
231
+ // Should we enable this?
232
+ // (nothrow ? self._resolve : self._reject)(
233
+ self . _reject (
234
+ new ProcessOutput ( null , null , stdout , stderr , stdall , message )
235
+ )
236
+ } else {
237
+ const message = ProcessOutput . getExitMessage (
238
+ status ,
239
+ signal ,
240
+ stderr ,
241
+ self . _from
242
+ )
243
+ const output = new ProcessOutput (
244
+ status ,
245
+ signal ,
246
+ stdout ,
247
+ stderr ,
248
+ stdall ,
249
+ message
250
+ )
251
+ if ( status === 0 || ( self . _nothrow ?? $ . nothrow ) ) {
252
+ self . _resolve ( output )
253
+ } else {
254
+ self . _reject ( output )
255
+ }
256
+ }
257
+ } ,
258
+ } ,
261
259
} )
262
260
263
261
this . _postrun ( ) // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin.
264
262
265
263
return this
266
264
}
267
265
266
+ get child ( ) {
267
+ return this . zurk ?. child
268
+ }
269
+
268
270
get stdin ( ) : Writable {
269
271
this . stdio ( 'pipe' )
270
272
this . run ( )
@@ -354,19 +356,15 @@ export class ProcessPromise extends Promise<ProcessOutput> {
354
356
throw new Error ( 'Trying to kill a process without creating one.' )
355
357
if ( ! this . child . pid ) throw new Error ( 'The process pid is undefined.' )
356
358
357
- await this . _zurk ?. kill ( signal as NodeJS . Signals )
358
- // zurk uses detached + process.kill(-p.pid)
359
- // Do we still need this?
360
-
361
- // let children = await psTree(this.child.pid)
362
- // for (const p of children) {
363
- // try {
364
- // process.kill(+p.PID, signal)
365
- // } catch (e) {}
366
- // }
367
- // try {
368
- // process.kill(this.child.pid, signal)
369
- // } catch (e) {}
359
+ let children = await psTree ( this . child . pid )
360
+ for ( const p of children ) {
361
+ try {
362
+ process . kill ( + p . PID , signal )
363
+ } catch ( e ) { }
364
+ }
365
+ try {
366
+ process . kill ( - this . child . pid , signal )
367
+ } catch ( e ) { }
370
368
}
371
369
372
370
stdio ( stdin : IO , stdout : IO = 'pipe' , stderr : IO = 'pipe' ) : ProcessPromise {
0 commit comments