Skip to content
Permalink
Browse files

fix(core): keep track of application restarts and close stdin pipe co…

…rrectly (#567)

previously we weren't tracking application restarts in the CLI module or closing our stdin pipe once
the child app had quit

ISSUES CLOSED: #545
  • Loading branch information
MarshallOfSound committed Sep 10, 2018
1 parent 5431dfa commit eb29dd6d0fc69e05b3b250f517d92120d2b4656d
@@ -1,5 +1,6 @@
import { api, StartOptions } from '@electron-forge/core';

import { ChildProcess } from 'child_process';
import fs from 'fs-extra';
import path from 'path';
import program from 'commander';
@@ -64,12 +65,26 @@ import './util/terminate';
const spawned = await api.start(opts);

await new Promise((resolve) => {
spawned.on('exit', (code: number) => {
if ((spawned as any).restarted) return;
if (code !== 0) {
process.exit(code);
}
resolve();
});
const listenForExit = (child: ChildProcess) => {
const removeListeners = () => {
child.removeListener('exit', onExit);
child.removeListener('restarted', onRestart);
};
const onExit = (code: number) => {
removeListeners();
if ((spawned as any).restarted) return;
if (code !== 0) {
process.exit(code);
}
resolve();
};
const onRestart = (newChild: ChildProcess) => {
removeListeners();
listenForExit(newChild);
};
child.on('exit', onExit);
child.on('restarted', onRestart);
};
listenForExit(spawned);
});
})();
@@ -53,6 +53,21 @@ export default async ({

const forgeSpawnWrapper = async () => {
lastSpawned = await forgeSpawn();
// When the child app is closed we should stop listening for stdin
if (lastSpawned) {
if (interactive && process.stdin.isPaused()) {
process.stdin.resume();
}
lastSpawned.on('exit', () => {
if ((lastSpawned as any).restarted) return;

if (!process.stdin.isPaused()) process.stdin.pause();
});
} else {
if (interactive && !process.stdin.isPaused()) {
process.stdin.pause();
}
}
return lastSpawned;
};

@@ -114,12 +129,12 @@ export default async ({
};

if (interactive) {
process.stdin.on('data', (data) => {
process.stdin.on('data', async (data) => {
if (data.toString().trim() === 'rs' && lastSpawned) {
console.info('\nRestarting App\n'.cyan);
(lastSpawned as any).restarted = true;
lastSpawned.kill('SIGTERM');
forgeSpawnWrapper();
lastSpawned.emit('restarted', await forgeSpawnWrapper());
}
});
}
@@ -11,7 +11,7 @@ describe('start', () => {
let packageJSON: any;
let resolveStub: SinonStub;
let spawnStub: SinonStub;
let shouldOverride: boolean;
let shouldOverride: any;
let processOn: SinonStub;

beforeEach(() => {
@@ -58,7 +58,7 @@ describe('start', () => {

it('should not spawn if a plugin overrides the start command', async () => {
resolveStub.returnsArg(0);
shouldOverride = true;
shouldOverride = { on: () => {} };
await start({
dir: __dirname,
interactive: false,
@@ -172,12 +172,13 @@ describe('start', () => {

it('should resolve with a handle to the spawned instance', async () => {
resolveStub.returnsArg(0);
spawnStub.returns('child');
const fakeChild = { on: () => {} };
spawnStub.returns(fakeChild);

await expect(start({
dir: __dirname,
interactive: false,
enableLogging: true,
})).to.eventually.equal('child');
})).to.eventually.equal(fakeChild);
});
});

0 comments on commit eb29dd6

Please sign in to comment.
You can’t perform that action at this time.