Skip to content

Commit ac424c0

Browse files
authored
fix: expose kill, ref & unref methods (#11)
* fix: expose kill, ref & unref methods closes #10 * ci: remove node16 * ci: avoid npx it's failing in windows
1 parent a4c572d commit ac424c0

File tree

4 files changed

+58
-29
lines changed

4 files changed

+58
-29
lines changed

.github/workflows/pull_request.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
strategy:
1616
matrix:
17-
node-version: ['16', '18', 'lts/*', 'latest']
17+
node-version: ['18', 'lts/*', 'latest']
1818
steps:
1919
- name: Checkout
2020
uses: actions/checkout@v4
@@ -32,7 +32,7 @@ jobs:
3232
- name: Test
3333
run: pnpm test
3434
- name: Report
35-
run: npx c8 report --reporter=text-lcov > coverage/lcov.info
35+
run: ./node_modules/.bin/c8 report --reporter=text-lcov > coverage/lcov.info
3636
- name: Coverage
3737
uses: coverallsapp/github-action@main
3838
with:
@@ -43,7 +43,7 @@ jobs:
4343
runs-on: windows-latest
4444
strategy:
4545
matrix:
46-
node-version: ['16', '18', 'lts/*', 'latest']
46+
node-version: ['18', 'lts/*', 'latest']
4747
steps:
4848
- name: Checkout
4949
uses: actions/checkout@v4
@@ -61,7 +61,7 @@ jobs:
6161
- name: Test
6262
run: pnpm test
6363
- name: Report
64-
run: npx c8 report --reporter=text-lcov > coverage/lcov.info
64+
run: ./node_modules/.bin/c8 report --reporter=text-lcov > coverage/lcov.info
6565
- name: Coverage
6666
uses: coverallsapp/github-action@main
6767
with:

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"standard-version": "latest"
6060
},
6161
"engines": {
62-
"node": ">= 16"
62+
"node": ">= 18"
6363
},
6464
"files": [
6565
"src"

src/index.js

+43-24
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,29 @@
33
const { spawn } = require('child_process')
44
const { EOL } = require('os')
55

6-
const EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype).filter(name => !name.startsWith('_'))
6+
const EE_PROPS = Object.getOwnPropertyNames(
7+
require('events').EventEmitter.prototype
8+
)
9+
.filter(name => !name.startsWith('_'))
10+
.concat(['kill', 'ref', 'unref'])
711

8-
const eos = (stream, listener, buffer = []) => stream[listener].on('data', data => buffer.push(data)) && buffer
12+
const eos = (stream, listener, buffer = []) =>
13+
stream[listener].on('data', data => buffer.push(data)) && buffer
914

1015
const clean = str => str.trim().replace(/\n$/, '')
1116

12-
const parse = (buffer, { json } = {}) => (encoding, start, end) => {
13-
const data = clean(Buffer.concat(buffer).toString(encoding, start, end))
14-
return json ? JSON.parse(data) : data
15-
}
17+
const parse =
18+
(buffer, { json } = {}) =>
19+
(encoding, start, end) => {
20+
const data = clean(Buffer.concat(buffer).toString(encoding, start, end))
21+
return json ? JSON.parse(data) : data
22+
}
1623

1724
const extend = defaults => (input, args, options) => {
18-
if (!(args instanceof Array)) { options = args; args = [] }
25+
if (!(args instanceof Array)) {
26+
options = args
27+
args = []
28+
}
1929
const [cmd, ...cmdArgs] = input.split(' ').concat(args).filter(Boolean)
2030
let childProcess
2131

@@ -25,27 +35,36 @@ const extend = defaults => (input, args, options) => {
2535
const stdout = eos(childProcess, 'stdout')
2636
const stderr = eos(childProcess, 'stderr')
2737

28-
childProcess
29-
.on('error', reject)
30-
.on('exit', code => {
31-
Object.defineProperty(childProcess, 'stdout', { get: parse(stdout, opts) })
32-
Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })
33-
if (code === 0) return resolve(childProcess)
34-
const command = `${cmd} ${cmdArgs.join(' ')}`
35-
let message = `The command spawned as:${EOL}${EOL}`
36-
message += ` ${command}${EOL}${EOL}`
37-
message += `exited with \`{ code: ${code} }\` and the following trace:${EOL}${EOL}`
38-
message += String(stderr).split(EOL).map(line => ` ${line}`).join(EOL)
39-
const error = new Error(message)
40-
error.command = command
41-
error.name = 'ChildProcessError'
42-
Object.keys(childProcess).forEach(key => { error[key] = childProcess[key] })
43-
reject(error)
38+
childProcess.on('error', reject).on('exit', code => {
39+
Object.defineProperty(childProcess, 'stdout', {
40+
get: parse(stdout, opts)
41+
})
42+
Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })
43+
if (code === 0) return resolve(childProcess)
44+
const command = `${cmd} ${cmdArgs.join(' ')}`
45+
let message = `The command spawned as:${EOL}${EOL}`
46+
message += ` ${command}${EOL}${EOL}`
47+
message += `exited with \`{ code: ${code} }\` and the following trace:${EOL}${EOL}`
48+
message += String(stderr)
49+
.split(EOL)
50+
.map(line => ` ${line}`)
51+
.join(EOL)
52+
const error = new Error(message)
53+
error.command = command
54+
error.name = 'ChildProcessError'
55+
Object.keys(childProcess).forEach(key => {
56+
error[key] = childProcess[key]
4457
})
58+
reject(error)
59+
})
4560
})
4661

4762
const subprocess = Object.assign(promise, childProcess)
48-
if (childProcess) EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))
63+
if (childProcess) {
64+
EE_PROPS.forEach(
65+
name => (subprocess[name] = childProcess[name].bind(childProcess))
66+
)
67+
}
4968
return subprocess
5069
}
5170

test/index.js

+10
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ test('piping subprocess', async t => {
127127

128128
test('passing timeout', async t => {
129129
const result = await $('sleep 3 && echo OK', {
130+
shell: true,
130131
timeout: 1,
131132
killSignal: 'SIGKILL'
132133
}).catch(err => err)
@@ -159,3 +160,12 @@ test('event emitter properties are availables', async t => {
159160
'eventNames'
160161
].forEach(name => t.truthy(subprocess[name]))
161162
})
163+
164+
test('child process properties are available', async t => {
165+
const subprocess = $('echo 1234567890')
166+
await new Promise(resolve => subprocess.once('spawn', resolve))
167+
const result = await subprocess
168+
t.is(result.stdout, '1234567890')
169+
t.is(result.exitCode, 0)
170+
;['kill', 'ref', 'unref'].forEach(name => t.truthy(subprocess[name]))
171+
})

0 commit comments

Comments
 (0)