-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexec.js
80 lines (69 loc) · 2.13 KB
/
exec.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
'use strict'
const proc = require('child_process')
const u = require('@elife/utils')
/* understand/
* `proc.spawn` creates an `EventEmitter` with the following events:
* + 'error': Failed to start the given process
* + 'exit': Process exited (fires sometimes)
* + 'close': Process exited cleanly
* `exit` and `close` may both be fired or not.
*
* outcome/
* We spawn the process and set up the even listeners:
* - when we get data, we show them line by line
* (stdout and stderror streams)
* - on error we dump whatever we have and callback
* with the error
* - on exit/close we dump whatever we have and call
* back based on the return code (error or ok)
* - we ensure we don't call back more than once
*/
module.exports = function(cmd, args, cwd, env, pfx_, cb) {
let child
if(env) child = proc.spawn(cmd, args, { cwd: cwd, env: env })
else child = proc.spawn(cmd, args, { cwd: cwd })
let op = ""
let er = ""
child.stdout.on('data', (data) => {
op += data
op = show_lines_1(op, u.showMsg)
})
child.stderr.on('data', (data) => {
er += data
er = show_lines_1(er, u.showErr)
})
child.on('error', (err) => {
call_back_with(err)
})
child.on('exit', on_done_1)
child.on('close', on_done_1)
function on_done_1(code, signal) {
if(code || signal) call_back_with(`Exited with error: ${cmd} ${args}`)
else call_back_with()
}
let cb_done = false
function call_back_with(err) {
dump_full_stream_1()
if(cb_done) return
cb_done = true
cb(err)
}
function show_lines_1(f, w) {
if(!f) return f
let lines = f.split(/[\n\r]+/)
for(let i = 0;i < lines.length-1;i++) {
w(pfx(lines[i]))
}
return lines[lines.length-1]
}
function dump_full_stream_1() {
if(op && op.trim()) u.showMsg(pfx(op.trim()))
if(er && er.trim()) u.showErr(pfx(er.trim()))
op = ""
er = ""
}
function pfx(v) {
if(pfx_) return pfx_ + ":" + v
else return v
}
}