-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
index.js
executable file
·134 lines (104 loc) · 2.96 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env node
process.title = 'lil-pids'
var fs = require('fs')
var readFile = require('read-file-live')
var respawn = require('respawn')
var chalk = require('chalk')
var BIN_SH = process.platform === 'android' ? '/system/bin/sh' : '/bin/sh'
var CMD_EXE = process.env.comspec || 'cmd.exe'
var colors = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray']
var currentColor = 0
var servicesFile = process.argv[2]
var pidsFile = process.argv[3]
if (!servicesFile) {
console.error('Usage: lil-pids [services-file] [pids-file?]')
process.exit(1)
}
var padding = ['', ' ', ' ', ' ', ' ']
var services = []
var monitors = {}
readFile(servicesFile, update)
function writePids (cb) {
if (!pidsFile) return
var cmds = Object.keys(monitors).sort(function (a, b) {
var i = services.indexOf(a)
var j = services.indexOf(b)
return (i === -1 || j === -1) ? a.localeCompare(b) : i - j
})
var lines = cmds.map(function (cmd) {
if (!monitors[cmd].pid) return
return prefix(monitors[cmd].pid) + cmd + '\n'
})
fs.writeFile(pidsFile, lines.join(''), cb || noop)
}
function update (buf) {
var latest = parse(buf)
var prev = services
services = latest
prev.forEach(function (s) {
if (latest.indexOf(s) === -1) stop(s)
})
latest.forEach(function (s) {
if (prev.indexOf(s) === -1) start(s)
})
}
function stop (cmd) {
monitors[cmd].stop()
delete monitors[cmd]
}
function start (cmd) {
var m = monitors[cmd] = spawn(cmd)
var color = chalk[nextColor()]
m.on('spawn', onspawn)
m.on('exit', onexit)
m.on('stdout', onstdout)
m.on('stderr', onstderr)
m.on('stop', update)
m.start()
function onstdout (message) {
onlog('(out)', message)
}
function onstderr (message) {
onlog('(err)', message)
}
function onspawn () {
console.log(color(prefix(m.pid) + '!!!!! SPAWN ' + cmd))
writePids()
}
function onexit (code) {
console.log(color(prefix(m.pid) + '!!!!! EXIT(' + code + ') ' + cmd))
writePids()
}
function onlog (type, message) {
var ln = message.toString().split('\n')
if (ln[ln.length - 1] === '') ln.pop()
for (var i = 0; i < ln.length; i++) ln[i] = prefix(m.pid) + type + ' ' + ln[i]
console.log(color(ln.join('\n')))
}
function update () {
writePids()
}
}
function parse (buf) {
if (!buf) return []
return buf.toString().trim().split('\n')
.map(function (line) {
return line.trim()
})
.filter(function (line) {
return line && line[0] !== '#'
})
}
function prefix (pid) {
var spid = pid.toString()
return spid + padding[5 - spid.length] + ': '
}
function spawn (cmd) {
if (process.platform !== 'win32') return respawn([BIN_SH, '-c', cmd], {maxRestarts: Infinity})
return respawn([CMD_EXE, '/d', '/s', '/c', '"' + cmd + '"'], {maxRestarts: Infinity, windowsVerbatimArguments: true})
}
function nextColor () {
if (currentColor === colors.length) currentColor = 0
return colors[currentColor++]
}
function noop () {}