From b34e17dd9195fc487287665300c9e2045b6adee6 Mon Sep 17 00:00:00 2001 From: bithavoc Date: Wed, 9 May 2018 10:05:11 -0500 Subject: [PATCH] fixes #150 exit code when os kills child process --- .all-contributorsrc | 12 ++++++- README.md | 4 +-- src/__tests__/index.js | 72 ++++++++++++++++++++++++++++-------------- src/index.js | 7 ++-- 4 files changed, 66 insertions(+), 29 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b2e11f5..dff2b09 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -163,6 +163,16 @@ "contributions": [ "code" ] + }, + { + "login": "bithavoc", + "name": "Johan Hernandez", + "avatar_url": "https://avatars3.githubusercontent.com/u/219289?v=4", + "profile": "http://bithavoc.io", + "contributions": [ + "code" + ] } - ] + ], + "repoType": "github" } diff --git a/README.md b/README.md index 1471a74..5a200ac 100755 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Run scripts that set and use environment variables across platforms [![downloads][downloads-badge]][npm-stat] [![MIT License][license-badge]][LICENSE] -[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors) [![PRs Welcome][prs-badge]][prs] [![Donate][donate-badge]][donate] [![Code of Conduct][coc-badge]][coc] @@ -158,7 +158,7 @@ Thanks goes to these people ([emoji key][emojis]): | [
Kent C. Dodds](https://kentcdodds.com)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds "Code") [πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds "Documentation") [πŸš‡](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds "Tests") | [
Ya Zhuang ](https://zhuangya.me)
[πŸ”Œ](#plugin-zhuangya "Plugin/utility libraries") [πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=zhuangya "Documentation") | [
James Harris](https://wopian.me)
[πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=wopian "Documentation") | [
compumike08](https://github.com/compumike08)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Acompumike08 "Bug reports") [πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=compumike08 "Documentation") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=compumike08 "Tests") | [
Daniel RodrΓ­guez Rivero](https://github.com/danielo515)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Adanielo515 "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=danielo515 "Code") [πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=danielo515 "Documentation") | [
Jonas Keinholz](https://github.com/inyono)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Ainyono "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=inyono "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=inyono "Tests") | [
Hugo Wood](https://github.com/hgwood)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Ahgwood "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=hgwood "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=hgwood "Tests") | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | [
Thiebaud Thomas](https://github.com/thomasthiebaud)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Athomasthiebaud "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=thomasthiebaud "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=thomasthiebaud "Tests") | [
Daniel Rey LΓ³pez](https://daniel.blog)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=DanReyLop "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=DanReyLop "Tests") | [
Amila Welihinda](http://amilajack.com)
[πŸš‡](#infra-amilajack "Infrastructure (Hosting, Build-Tools, etc)") | [
Paul Betts](https://twitter.com/paulcbetts)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Apaulcbetts "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=paulcbetts "Code") | [
Turner Hayes](https://github.com/turnerhayes)
[πŸ›](https://github.com/kentcdodds/cross-env/issues?q=author%3Aturnerhayes "Bug reports") [πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=turnerhayes "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=turnerhayes "Tests") | [
Suhas Karanth](https://github.com/sudo-suhas)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=sudo-suhas "Code") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=sudo-suhas "Tests") | [
Sven](https://github.com/sventschui)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=sventschui "Code") [πŸ“–](https://github.com/kentcdodds/cross-env/commits?author=sventschui "Documentation") [πŸ’‘](#example-sventschui "Examples") [⚠️](https://github.com/kentcdodds/cross-env/commits?author=sventschui "Tests") | -| [
D. NicolΓ‘s Lopez Zelaya](https://github.com/NicoZelaya)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=NicoZelaya "Code") | +| [
D. NicolΓ‘s Lopez Zelaya](https://github.com/NicoZelaya)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=NicoZelaya "Code") | [
Johan Hernandez](http://bithavoc.io)
[πŸ’»](https://github.com/kentcdodds/cross-env/commits?author=bithavoc "Code") | This project follows the [all-contributors][all-contributors] specification. Contributions of any kind welcome! diff --git a/src/__tests__/index.js b/src/__tests__/index.js index f009d6c..24c76fb 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -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`, () => { @@ -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']) @@ -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 diff --git a/src/index.js b/src/index.js index 9db75a7..ce6a3c5 100644 --- a/src/index.js +++ b/src/index.js @@ -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 @@ -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 '' })