1 | var spawn = require('child_process').spawn;
|
2 |
|
3 | var FLAGS = [
|
4 | 'debug',
|
5 | '--debug',
|
6 | '--debug-brk',
|
7 | '--inspect',
|
8 | '--inspect-brk',
|
9 | '--expose-gc',
|
10 | '--gc-global',
|
11 | '--es_staging',
|
12 | '--no-deprecation',
|
13 | '--prof',
|
14 | '--log-timer-events',
|
15 | '--throw-deprecation',
|
16 | '--trace-deprecation',
|
17 | '--use_strict',
|
18 | '--allow-natives-syntax',
|
19 | '--perf-basic-prof',
|
20 | '--experimental-repl-await'
|
21 | ];
|
22 |
|
23 | var FLAG_PREFIXES = [
|
24 | '--harmony',
|
25 | '--trace',
|
26 | '--icu-data-dir',
|
27 | '--max-old-space-size',
|
28 | '--preserve-symlinks'
|
29 | ];
|
30 |
|
31 | var DEFAULT_FORCED_KILL_DELAY = 30000;
|
32 |
|
33 | function getChildArgs (cliPath, ignore) {
|
34 | var args = [cliPath];
|
35 |
|
36 | process.argv.slice(2).forEach(function (arg) {
|
37 | var flag = arg.split('=')[0];
|
38 |
|
39 | if (ignore.indexOf(flag) > -1) {
|
40 | args.push(arg);
|
41 | return;
|
42 | }
|
43 |
|
44 | if (FLAGS.indexOf(flag) > -1) {
|
45 | args.unshift(arg);
|
46 | return;
|
47 | }
|
48 |
|
49 | for (var i = 0; i < FLAG_PREFIXES.length; i++) {
|
50 | if (arg.indexOf(FLAG_PREFIXES[i]) === 0) {
|
51 | args.unshift(arg);
|
52 | return;
|
53 | }
|
54 | }
|
55 |
|
56 | args.push(arg);
|
57 | });
|
58 |
|
59 | return args;
|
60 | }
|
61 |
|
62 | function setupSignalHandler (signal, childProcess, useShutdownMessage, forcedKillDelay) {
|
63 | function forceKill () {
|
64 | childProcess.kill('SIGTERM');
|
65 | }
|
66 |
|
67 | function handler () {
|
68 | if (useShutdownMessage)
|
69 | childProcess.send('shutdown');
|
70 | else
|
71 | childProcess.kill(signal);
|
72 |
|
73 | setTimeout(forceKill, forcedKillDelay).unref();
|
74 | }
|
75 |
|
76 | process.on(signal, handler);
|
77 | }
|
78 |
|
79 | module.exports = function (cliPath, opts) {
|
80 | var useShutdownMessage = opts && opts.useShutdownMessage;
|
81 | var forcedKillDelay = opts && opts.forcedKillDelay || DEFAULT_FORCED_KILL_DELAY;
|
82 | var ignore = opts && opts.ignore || [];
|
83 | var args = getChildArgs(cliPath, ignore);
|
84 |
|
85 | var cliProc = spawn(process.execPath, args, { stdio: [process.stdin, process.stdout, process.stderr, useShutdownMessage ? 'ipc' : null] });
|
86 |
|
87 | cliProc.on('exit', function (code, signal) {
|
88 | if (useShutdownMessage && process.disconnect)
|
89 | process.disconnect();
|
90 |
|
91 | process.on('exit', function () {
|
92 | if (signal)
|
93 | process.kill(process.pid, signal);
|
94 | else
|
95 | process.exit(code);
|
96 | });
|
97 | });
|
98 |
|
99 | setupSignalHandler('SIGINT', cliProc, useShutdownMessage, forcedKillDelay);
|
100 | setupSignalHandler('SIGBREAK', cliProc, useShutdownMessage, forcedKillDelay);
|
101 |
|
102 | if (useShutdownMessage) {
|
103 | process.on('message', function (message) {
|
104 | if (message === 'shutdown')
|
105 | cliProc.send('shutdown');
|
106 | });
|
107 | }
|
108 | };
|