forked from gnosis/run-with-testrpc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
executable file
·92 lines (79 loc) · 2.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const { spawn, execSync } = require('child_process');
const onExit = require('signal-exit')
/**
* launch command, and wait for it to start.
* @param cmd
* @param args
* @param waitFor
* @param verbose
* @returns the started ChildProcess
*/
async function waitForCmdToStart({cmd, args, waitFor, verbose}) {
let testrpc
if (typeof cmd != 'string') throw new Error('missing {cmd:"..."} param')
if (typeof waitFor != 'string') throw new Error('missing {waitFor:"..."} param')
if (args && !Array.isArray(args)) throw new Error('args param is not an array')
let lastData
await new Promise((resolve, reject) => {
const handleError = (err) => {
if(err.code === 'ENOENT')
return reject(new Error(`Could not find ${cmd}`))
if(err.code === 'EACCES')
return reject(new Error(`Need permission to execute ${cmd}`))
return reject(err)
}
try {
testrpc = spawn(cmd, args)
} catch(err) {
return handleError(err)
}
testrpc.stdout.on('data', (data) => {
const dataFiltered = data.toString().replace(/\d+/g,'')
if (verbose && dataFiltered != lastData) {
process.stdout.write(data)
}
lastData = dataFiltered
if(data.includes(waitFor)) {
resolve(testrpc)
}
})
let error = ''
testrpc.stderr.on('data', (data) => {
if (verbose) { process.stderr.write(data) }
error += data
})
testrpc.on('error', handleError)
testrpc.on('close', (code) =>
reject(new Error(`${cmd} exited early with code ${code}`))
)
})
return testrpc
}
/**
*
* @param cmd external command to run.
* @param args parameters for external command
* @param waitFor wait for this output string of command, before launching innerCmd
* @param innerCmd inner command to launch, once cmd had reached the "waitFor" output string
* @param verbose true to dump cmd's output. false to hide extenral cmd output
* note that innerCmd's output is always dumped to output
*/
async function runWithCmd({ cmd, args, waitFor, innerCmd, verbose }) {
let testrpc
//catch process abort with signals (which bypasses the "finally", below)
onExit(()=>{
if (testrpc) {
testrpc.kill()
}
})
try {
testrpc = await waitForCmdToStart({cmd, args, waitFor, verbose})
execSync(innerCmd, { stdio: 'inherit' })
} finally {
if(testrpc) {
testrpc.kill()
testrpc = null
}
}
}
module.exports = { waitForCmdToStart, runWithCmd }