Skip to content

Commit

Permalink
fixes kentcdodds#150 exit code when os kills child process
Browse files Browse the repository at this point in the history
  • Loading branch information
bithavoc committed May 9, 2018
1 parent 450dae9 commit d639bb9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 26 deletions.
72 changes: 48 additions & 24 deletions src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,33 +62,40 @@ it(`should handle quoted scripts`, () => {
crossEnv(['GREETING=Hi', 'NAME=Joe', 'echo $GREETING && echo $NAME'], {
shell: true,
})
expect(
crossSpawnMock.spawn,
).toHaveBeenCalledWith('echo $GREETING && echo $NAME', [], {
stdio: 'inherit',
shell: true,
env: Object.assign({}, process.env, {
GREETING: 'Hi',
NAME: 'Joe',
}),
})
expect(crossSpawnMock.spawn).toHaveBeenCalledWith(
'echo $GREETING && echo $NAME',
[],
{
stdio: 'inherit',
shell: true,
env: Object.assign({}, process.env, {
GREETING: 'Hi',
NAME: 'Joe',
}),
},
)
})

it(`should handle escaped characters`, () => {
// this escapes \,",' and $
crossEnv(['GREETING=Hi', 'NAME=Joe', 'echo \\"\\\'\\$GREETING\\\'\\" && echo $NAME'], {
shell: true,
})
expect(
crossSpawnMock.spawn,
).toHaveBeenCalledWith("echo \"'$GREETING'\" && echo $NAME", [], {
stdio: 'inherit',
shell: true,
env: Object.assign({}, process.env, {
GREETING: 'Hi',
NAME: 'Joe',
}),
})
crossEnv(
['GREETING=Hi', 'NAME=Joe', 'echo \\"\\\'\\$GREETING\\\'\\" && echo $NAME'],
{
shell: true,
},
)
expect(crossSpawnMock.spawn).toHaveBeenCalledWith(
'echo "\'$GREETING\'" && echo $NAME',
[],
{
stdio: 'inherit',
shell: true,
env: Object.assign({}, process.env, {
GREETING: 'Hi',
NAME: 'Joe',
}),
},
)
})

it(`should do nothing given no command`, () => {
Expand Down Expand Up @@ -133,6 +140,24 @@ it(`should propagate kill signals`, () => {
expect(crossSpawnMock.__mock.spawned.kill).toHaveBeenCalledWith('SIGBREAK')
})

it(`should propagate unhandled exit signal`, () => {
process.exit = jest.fn()
testEnvSetting({FOO_ENV: 'foo=bar'}, 'FOO_ENV="foo=bar"')
const spawnExitCallback = crossSpawnMock.__mock.spawned.on.mock.calls[0][1]
const spawnExitCode = null
spawnExitCallback(spawnExitCode)
expect(process.exit).toHaveBeenCalledWith(1)
})

it(`should propagate regular exit code`, () => {
process.exit = jest.fn()
testEnvSetting({FOO_ENV: 'foo=bar'}, 'FOO_ENV="foo=bar"')
const spawnExitCallback = crossSpawnMock.__mock.spawned.on.mock.calls[0][1]
const spawnExitCode = 0
spawnExitCallback(spawnExitCode)
expect(process.exit).toHaveBeenCalledWith(0)
})

it(`should keep backslashes`, () => {
isWindowsMock.__mock.returnValue = true
crossEnv(['echo', '\\\\\\\\someshare\\\\somefolder'])
Expand All @@ -147,7 +172,6 @@ it(`should keep backslashes`, () => {
isWindowsMock.__mock.reset()
})


function testEnvSetting(expected, ...envSettings) {
if (expected.APPDATA === 2) {
// kill the APPDATA to test both is undefined
Expand Down
7 changes: 5 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ function crossEnv(args, options = {}) {
process.on('SIGINT', () => proc.kill('SIGINT'))
process.on('SIGBREAK', () => proc.kill('SIGBREAK'))
process.on('SIGHUP', () => proc.kill('SIGHUP'))
proc.on('exit', process.exit)
proc.on('exit', code => {
// exit code could be null when OS kills the process(out of memory, etc)
process.exit(code === null ? 1 : code)
})
return proc
}
return null
Expand Down Expand Up @@ -61,7 +64,7 @@ function parseCommand(args) {
const re = /\\\\|(\\)?'|([\\])(?=[$"\\])/g
// Eliminate all matches except for "\'" => "'"
return a.replace(re, m => {
if (m === "\\\\") return "\\"
if (m === '\\\\') return '\\'
if (m === "\\'") return "'"
return ''
})
Expand Down

0 comments on commit d639bb9

Please sign in to comment.