Skip to content

Commit 507e539

Browse files
committed
feat: always include code/signal in output
1 parent cc8f6b3 commit 507e539

File tree

3 files changed

+68
-45
lines changed

3 files changed

+68
-45
lines changed

index.d.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,26 @@ import {
66
ForkOptions,
77
} from 'child_process'
88

9-
interface Output {
9+
export interface Output {
1010
stdout?: string | Buffer | null | undefined
1111
stderr?: string | Buffer | null | undefined
12+
code?: number | null
13+
signal?: string | null
1214
}
1315

14-
interface ExitReason {
15-
code?: number
16-
signal?: string
17-
}
18-
19-
type ErrorWithOutput = Error & Output & ExitReason
16+
export type ErrorWithOutput = Error & Output
2017

21-
type ChildProcessPromise = ChildProcess & Promise<Output>
18+
export type ChildProcessPromise = ChildProcess & Promise<Output>
2219

23-
interface PromisifyChildProcessOptions {
20+
export interface PromisifyChildProcessOptions {
2421
encoding?: string
2522
killSignal?: string
2623
maxBuffer?: number
2724
}
2825

29-
type PromisifySpawnOptions = SpawnOptions & PromisifyChildProcessOptions
26+
export type PromisifySpawnOptions = SpawnOptions & PromisifyChildProcessOptions
3027

31-
type PromisifyForkOptions = ForkOptions & PromisifyChildProcessOptions
28+
export type PromisifyForkOptions = ForkOptions & PromisifyChildProcessOptions
3229

3330
export function promisifyChildProcess(
3431
child: ChildProcess,

src/index.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ import type { ChildProcess } from 'child_process'
44
const child_process = require('child_process')
55

66
export type ChildProcessOutput = {
7-
stdout: ?(string | Buffer),
8-
stderr: ?(string | Buffer),
9-
}
10-
11-
export type ErrorWithOutput = Error & {
127
stdout?: ?(string | Buffer),
138
stderr?: ?(string | Buffer),
14-
code?: ?number,
15-
signal?: ?string,
9+
code?: number | null,
10+
signal?: string | null,
1611
}
1712

13+
export interface ExitReason {
14+
code?: number | null;
15+
signal?: string | null;
16+
}
17+
18+
export type ErrorWithOutput = Error & ChildProcessOutput
19+
1820
export type ChildProcessPromise = ChildProcess & Promise<ChildProcessOutput>
1921

2022
type PromisifyChildProcessBaseOpts = {
@@ -100,6 +102,8 @@ export function promisifyChildProcess(
100102
}
101103
}
102104
function defineOutputs(obj: Object) {
105+
obj.code = code
106+
obj.signal = signal
103107
if (captureStdio) {
104108
obj.stdout = joinChunks(stdoutChunks, encoding)
105109
obj.stderr = joinChunks(stderrChunks, encoding)
@@ -124,15 +128,13 @@ export function promisifyChildProcess(
124128
})
125129
}
126130
}
127-
const output: ChildProcessOutput = ({}: any)
128-
defineOutputs(output)
129131
const finalError: ?ErrorWithOutput = error
130132
if (finalError) {
131-
finalError.code = code
132-
finalError.signal = signal
133133
defineOutputs(finalError)
134134
reject(finalError)
135135
} else {
136+
const output: ChildProcessOutput = ({}: any)
137+
defineOutputs(output)
136138
resolve(output)
137139
}
138140
}
@@ -190,7 +192,7 @@ function promisifyExecMethod(method: any): any {
190192
err.stderr = stderr
191193
reject(err)
192194
} else {
193-
resolve({ stdout, stderr })
195+
resolve({ code: 0, signal: null, stdout, stderr })
194196
}
195197
}
196198
)

test/index.js

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('spawn', function() {
5252

5353
it('resolves with process output', async () => {
5454
let finallyDone = false
55-
const { stdout, stderr } = await spawn(
55+
const { code, signal, stdout, stderr } = await spawn(
5656
process.execPath,
5757
[require.resolve('./resolvesWithProcessOutput')],
5858
{ maxBuffer: 200 * 1024 }
@@ -61,6 +61,8 @@ describe('spawn', function() {
6161
finallyDone = true
6262
})
6363
expect(finallyDone, 'finally handler finished').to.be.true
64+
expect(code, 'code').to.equal(0)
65+
expect(signal, 'signal').to.equal(null)
6466
if (stdout == null || stderr == null) throw new Error('missing output')
6567
if (!(stdout instanceof Buffer))
6668
throw new Error('expected stdout to be a buffer')
@@ -85,7 +87,11 @@ describe('spawn', function() {
8587
{ maxBuffer: 1 }
8688
).catch(err => (error = err))
8789
if (error == null) throw new Error('missing error')
88-
const { stdout, stderr } = error
90+
const { code, signal, stdout, stderr } = error
91+
if (process.env.BABEL_ENV !== 'coverage')
92+
expect(code, 'code').to.equal(null)
93+
if (process.env.BABEL_ENV !== 'coverage')
94+
expect(signal, 'signal').to.equal('SIGTERM')
8995
expect(stdout.toString('utf8')).to.equal('h')
9096
expect(stderr.toString('utf8')).to.equal('')
9197
})
@@ -112,9 +118,10 @@ describe('spawn', function() {
112118
.catch(err => (error = err))
113119
expect(finallyDone, 'finally handler finished').to.be.true
114120
if (error == null) throw new Error('missing error')
115-
const { code, message, stdout, stderr } = error
121+
const { code, signal, message, stdout, stderr } = error
116122
expect(message).to.equal('Process exited with code 2')
117-
expect(code).to.equal(2)
123+
expect(code, 'code').to.equal(2)
124+
expect(signal, 'signal').to.equal(null)
118125
if (!(stdout instanceof Buffer))
119126
throw new Error('expected stdout to be a buffer')
120127
if (!(stderr instanceof Buffer))
@@ -145,9 +152,10 @@ describe('spawn', function() {
145152
})
146153
await child.catch(err => (error = err))
147154
if (error == null) throw new Error('missing error')
148-
const { signal, message, stdout, stderr } = error
155+
const { code, signal, message, stdout, stderr } = error
149156
expect(message).to.equal('Process was killed with SIGINT')
150-
expect(signal).to.equal('SIGINT')
157+
expect(code, 'code').to.equal(null)
158+
expect(signal, 'signal').to.equal('SIGINT')
151159
if (!(stdout instanceof Buffer))
152160
throw new Error('expected stdout to be a buffer')
153161
if (!(stderr instanceof Buffer))
@@ -171,13 +179,15 @@ describe('fork', function() {
171179

172180
it('resolves with process output', async () => {
173181
let finallyDone = false
174-
const { stdout, stderr } = await fork(
182+
const { code, signal, stdout, stderr } = await fork(
175183
require.resolve('./resolvesWithProcessOutput'),
176184
{ silent: true, maxBuffer: 200 * 1024 }
177185
).finally(async () => {
178186
await delay(50)
179187
finallyDone = true
180188
})
189+
expect(code, 'code').to.equal(0)
190+
expect(signal, 'signal').to.equal(null)
181191
expect(finallyDone, 'finally handler finished').to.be.true
182192
if (stdout == null || stderr == null) throw new Error('missing output')
183193
if (!(stdout instanceof Buffer))
@@ -202,7 +212,11 @@ describe('fork', function() {
202212
maxBuffer: 1,
203213
}).catch(err => (error = err))
204214
if (error == null) throw new Error('missing error')
205-
const { stdout, stderr } = error
215+
const { code, signal, stdout, stderr } = error
216+
if (process.env.BABEL_ENV !== 'coverage')
217+
expect(code, 'code').to.equal(null)
218+
if (process.env.BABEL_ENV !== 'coverage')
219+
expect(signal, 'signal').to.equal('SIGTERM')
206220
expect(stdout.toString('utf8')).to.equal('h')
207221
expect(stderr.toString('utf8')).to.equal('')
208222
})
@@ -229,9 +243,10 @@ describe('fork', function() {
229243
.catch(err => (error = err))
230244
expect(finallyDone, 'finally handler finished').to.be.true
231245
if (error == null) throw new Error('missing error')
232-
const { code, message, stdout, stderr } = error
246+
const { code, signal, message, stdout, stderr } = error
233247
expect(message).to.equal('Process exited with code 2')
234-
expect(code).to.equal(2)
248+
expect(code, 'code').to.equal(2)
249+
expect(signal, 'signal').to.equal(null)
235250
if (!(stdout instanceof Buffer))
236251
throw new Error('expected stdout to be a buffer')
237252
if (!(stderr instanceof Buffer))
@@ -259,9 +274,10 @@ describe('fork', function() {
259274
})
260275
await child.catch(err => (error = err))
261276
if (error == null) throw new Error('missing error')
262-
const { signal, message, stdout, stderr } = error
277+
const { code, signal, message, stdout, stderr } = error
263278
expect(message).to.equal('Process was killed with SIGINT')
264-
expect(signal).to.equal('SIGINT')
279+
expect(code, 'code').to.equal(null)
280+
expect(signal, 'signal').to.equal('SIGINT')
265281
if (!(stdout instanceof Buffer))
266282
throw new Error('expected stdout to be a buffer')
267283
if (!(stderr instanceof Buffer))
@@ -281,10 +297,12 @@ describe('exec', function() {
281297
this.timeout(30000)
282298

283299
it('resolves with process output', async () => {
284-
const { stdout, stderr } = await exec(
300+
const { code, signal, stdout, stderr } = await exec(
285301
`${process.execPath} ${require.resolve('./resolvesWithProcessOutput')}`
286302
)
287303
if (stdout == null || stderr == null) throw new Error('missing output')
304+
expect(code, 'code').to.equal(0)
305+
expect(signal, 'signal').to.equal(null)
288306
expect(stdout).to.equal('hello')
289307
expect(stderr).to.equal('world')
290308
})
@@ -294,8 +312,9 @@ describe('exec', function() {
294312
`${process.execPath} ${require.resolve('./rejectsWithExitCode')}`
295313
).catch(err => (error = err))
296314
if (error == null) throw new Error('missing error')
297-
const { code, stdout, stderr } = error
298-
expect(code).to.equal(2)
315+
const { code, signal, stdout, stderr } = error
316+
expect(code, 'code').to.equal(2)
317+
expect(signal, 'signal').to.equal(null)
299318
expect(stdout).to.equal('hello')
300319
expect(stderr).to.equal('world')
301320
})
@@ -318,8 +337,9 @@ describe('exec', function() {
318337
})
319338
await child.catch(err => (error = err))
320339
if (error == null) throw new Error('missing error')
321-
const { signal, stdout, stderr } = error
322-
expect(signal).to.equal('SIGINT')
340+
const { code, signal, stdout, stderr } = error
341+
expect(code, 'code').to.equal(null)
342+
expect(signal, 'signal').to.equal('SIGINT')
323343
expect(stdout).to.equal('hello')
324344
expect(stderr).to.equal('world')
325345
})
@@ -329,10 +349,12 @@ describe('execFile', function() {
329349
this.timeout(30000)
330350

331351
it('resolves with process output', async () => {
332-
const { stdout, stderr } = await execFile(
352+
const { code, signal, stdout, stderr } = await execFile(
333353
require.resolve('./resolvesWithProcessOutput')
334354
)
335355
if (stdout == null || stderr == null) throw new Error('missing output')
356+
expect(code, 'code').to.equal(0)
357+
expect(signal, 'signal').to.equal(null)
336358
expect(stdout).to.equal('hello')
337359
expect(stderr).to.equal('world')
338360
})
@@ -342,8 +364,9 @@ describe('execFile', function() {
342364
err => (error = err)
343365
)
344366
if (error == null) throw new Error('missing error')
345-
const { code, stdout, stderr } = error
346-
expect(code).to.equal(2)
367+
const { code, signal, stdout, stderr } = error
368+
expect(code, 'code').to.equal(2)
369+
expect(signal, 'signal').to.equal(null)
347370
expect(stdout).to.equal('hello')
348371
expect(stderr).to.equal('world')
349372
})
@@ -364,8 +387,9 @@ describe('execFile', function() {
364387
})
365388
await child.catch(err => (error = err))
366389
if (error == null) throw new Error('missing error')
367-
const { signal, stdout, stderr } = error
368-
expect(signal).to.equal('SIGINT')
390+
const { code, signal, stdout, stderr } = error
391+
expect(code, 'code').to.equal(null)
392+
expect(signal, 'signal').to.equal('SIGINT')
369393
expect(stdout).to.equal('hello')
370394
expect(stderr).to.equal('world')
371395
})

0 commit comments

Comments
 (0)