/
launcher.js
121 lines (111 loc) · 3.47 KB
/
launcher.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
var child_process = require('child_process')
var EventEmitter = require('events').EventEmitter
var log = require('winston')
var fs = require('fs')
var path = require('path')
var fileExists = fs.exists || path.exists
var async = require('async')
var ProcessRunner = require('./runners').ProcessRunner
var template = require('./strutils').template
function Launcher(name, settings, app){
this.name = name
this.app = app
this.settings = settings
this.setupDefaultSettings()
}
Launcher.prototype = {
__proto__: EventEmitter.prototype
, setupDefaultSettings: function(){
var settings = this.settings
if (settings.protocol === 'tap' && !('hide_stdout' in settings)){
settings.hide_stdout = true
}
}
, isProcess: function(){
return this.settings.protocol !== 'browser'
}
, start: function(){
if (this.isProcess()){
var self = this
var app = this.app
self.runner = new ProcessRunner({
app: app
, launcher: self
})
app.runners.push(self.runner)
}else{
this.launch()
}
}
, launch: function(cb){
var self = this
var app = this.app
var url = app.url
var settings = this.settings
this.kill('SIGTERM', function(){
if (settings.setup){
settings.setup(app, function(){
self.doLaunch(cb)
})
}else{
self.doLaunch(cb)
}
})
}
, doLaunch: function(cb){
var app = this.app
var url = app.url
var settings = this.settings
var self = this
var options = {}
if (settings.cwd) options.cwd = settings.cwd
if (settings.exe){
function spawn(exe){
args = args.map(app.template.bind(app))
self.process = child_process.spawn(exe, args, options)
self.process.once('exit', self.onExit.bind(self))
self.emit('processStarted', self.process)
if (cb) cb(self.process)
}
var args = [url]
if (settings.args instanceof Array)
args = settings.args.concat(args)
else if (settings.args instanceof Function)
args = settings.args(app)
if (Array.isArray(settings.exe)){
async.filter(settings.exe, fileExists, function(found){
spawn(found[0])
})
}else{
spawn(settings.exe)
}
}else if (settings.command){
var cmd = app.template(settings.command)
this.process = child_process.exec(cmd, options)
this.process.on('exit', self.onExit.bind(self))
self.emit('processStarted', self.process)
if (cb) cb(self.process)
}
}
, onExit: function(code){
this.exitCode = code
this.emit('processExit', code)
this.process = null
}
, kill: function(sig, cb){
if (!this.process){
if(cb) cb(this.exitCode)
return
}
var process = this.process
process.stdout.removeAllListeners()
process.stderr.removeAllListeners()
sig = sig || 'SIGKILL'
process.once('exit', function(){
process.removeAllListeners()
if (cb) cb()
})
process.kill(sig)
}
}
module.exports = Launcher