1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | return new (P || (P = Promise))(function (resolve, reject) {
|
4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
7 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8 | });
|
9 | };
|
10 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
11 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
12 | };
|
13 | var __importStar = (this && this.__importStar) || function (mod) {
|
14 | if (mod && mod.__esModule) return mod;
|
15 | var result = {};
|
16 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
17 | result["default"] = mod;
|
18 | return result;
|
19 | };
|
20 | Object.defineProperty(exports, "__esModule", { value: true });
|
21 | const chalk_1 = __importDefault(require("chalk"));
|
22 | const child_process_1 = require("child_process");
|
23 | const pstree_remy_1 = __importStar(require("pstree.remy"));
|
24 | const platform_1 = require("../util/platform");
|
25 | function invariant(condition, message) {
|
26 | if (!condition) {
|
27 | const err = new Error(message);
|
28 | err.name = 'Invariant Violation';
|
29 | throw err;
|
30 | }
|
31 | }
|
32 | class AppController {
|
33 | constructor(executablePath, argv) {
|
34 | this.state = {
|
35 | appRunning: false,
|
36 | proc: null,
|
37 | pid: null,
|
38 | };
|
39 | this.executablePath = executablePath;
|
40 | this.argv = argv;
|
41 | }
|
42 | stopApp() {
|
43 | return __awaiter(this, void 0, void 0, function* () {
|
44 | return new Promise(resolve => {
|
45 | if (this.state.appRunning) {
|
46 | console.log('Sending SIGTERM signal to app...');
|
47 | const { pid } = this.state;
|
48 | const closeHandler = (code, signal) => {
|
49 | this.setState({
|
50 | appRunning: false,
|
51 | proc: null,
|
52 | pid: null,
|
53 | });
|
54 | resolve();
|
55 | };
|
56 | if (platform_1.isWindows()) {
|
57 | child_process_1.exec('taskkill /pid ' + pid + ' /T /F').on('close', closeHandler);
|
58 | }
|
59 | else {
|
60 |
|
61 | pstree_remy_1.default(pid, (_, children) => {
|
62 | if (pstree_remy_1.hasPS) {
|
63 |
|
64 | child_process_1.spawn('kill', ['-s', 'SIGTERM', pid].concat(children)).on('close', closeHandler);
|
65 | }
|
66 | else {
|
67 | const pids = children.concat(pid).sort();
|
68 | pids.forEach(childPid => {
|
69 |
|
70 | child_process_1.exec('kill -15 ' + childPid).on('close', closeHandler);
|
71 | });
|
72 | }
|
73 | });
|
74 | }
|
75 | }
|
76 | else {
|
77 | resolve();
|
78 | }
|
79 | });
|
80 | });
|
81 | }
|
82 | runApp() {
|
83 | invariant(!this.state.appRunning, "Can't start app when app is already running!");
|
84 |
|
85 | const proc = child_process_1.spawn('node', [this.executablePath, ...this.argv]);
|
86 |
|
87 | proc.on('error', e => {
|
88 | console.log(chalk_1.default.red('Failed to start app: ' + e.message));
|
89 | this.setState({
|
90 | appRunning: false,
|
91 | proc: null,
|
92 | pid: null,
|
93 | });
|
94 | });
|
95 | proc.on('exit', (code, signal) => {
|
96 | if (code !== null) {
|
97 | console.log(code > 0
|
98 | ? chalk_1.default.red('App exited with code ' + code + '.')
|
99 | : chalk_1.default.green('App exited with code ' + code + '.'));
|
100 | }
|
101 | if (signal !== null) {
|
102 | console.log(signal !== 'SIGTERM'
|
103 | ? chalk_1.default.red('App killed with signal ' + signal + '.')
|
104 | : chalk_1.default.green('App killed with signal SIGTERM.'));
|
105 | }
|
106 | this.setState({
|
107 | appRunning: false,
|
108 | proc: null,
|
109 | pid: null,
|
110 | });
|
111 | });
|
112 |
|
113 | proc.stdout.pipe(process.stdout);
|
114 | proc.stderr.pipe(process.stderr);
|
115 | console.log(chalk_1.default.green('App started!'));
|
116 | this.setState({
|
117 | proc,
|
118 | pid: proc.pid.toString(),
|
119 | appRunning: true,
|
120 | });
|
121 | }
|
122 | setState(state) {
|
123 | this.state = state;
|
124 | }
|
125 | }
|
126 | exports.AppController = AppController;
|
127 |
|
\ | No newline at end of file |