Skip to content

Commit

Permalink
fix: keep stdin unpaused after ora completes (#2904)
Browse files Browse the repository at this point in the history
  • Loading branch information
clavin committed Jul 11, 2022
1 parent 345250c commit aad9c7e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
14 changes: 12 additions & 2 deletions packages/api/core/src/api/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export default async ({
inspectBrk = false,
}: StartOptions): Promise<ElectronProcess> => {
asyncOra.interactive = interactive;
// Since the `start` command is meant to be long-living (i.e. run forever,
// until interrupted) we should enable this to keep stdin flowing after ora
// completes. For more context:
// https://github.com/electron-userland/electron-forge/issues/2319
asyncOra.keepStdinFlowing = true;

await asyncOra('Locating Application', async () => {
const resolvedDir = await resolveDir(dir);
Expand Down Expand Up @@ -131,9 +136,13 @@ export default async ({
process.stdin.resume();
}
spawned.on('exit', () => {
if (spawned.restarted) return;
if (spawned.restarted) {
return;
}

if (!process.stdin.isPaused()) process.stdin.pause();
if (interactive && !process.stdin.isPaused()) {
process.stdin.pause();
}
});
} else if (interactive && !process.stdin.isPaused()) {
process.stdin.pause();
Expand All @@ -153,6 +162,7 @@ export default async ({
lastSpawned.emit('restarted', await forgeSpawnWrapper());
}
});
process.stdin.resume();
}

return forgeSpawnWrapper();
Expand Down
18 changes: 18 additions & 0 deletions packages/utils/async-ora/src/ora-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ export class OraImpl {
export interface AsyncOraMethod {
(initialOraValue: string, asyncFn: (oraImpl: OraImpl) => Promise<void>, processExitFn?: (code: number) => void): Promise<void>;
interactive?: boolean;

/**
* This will keep stdin unpaused if ora inadvertently pauses it. Beware that
* enabling this may keep the node process alive even when there is no more
* work to be done, as it will forever be waiting for input on stdin.
*
* More context:
* https://github.com/electron-userland/electron-forge/issues/2319
*/
keepStdinFlowing?: boolean;
}

const asyncOra: AsyncOraMethod = (initialOraValue, asyncFn, processExitFn = process.exit) => {
Expand All @@ -40,7 +50,15 @@ const asyncOra: AsyncOraMethod = (initialOraValue, asyncFn, processExitFn = proc
return new Promise((resolve, reject) => {
asyncFn(fnOra)
.then(() => {
const wasPaused = process.stdin.isPaused();

// Note: this may pause stdin as a side-effect in certain cases
fnOra.succeed();

if (asyncOra.keepStdinFlowing && !wasPaused && process.stdin.isPaused()) {
process.stdin.resume();
}

return resolve();
})
.catch((err) => {
Expand Down

0 comments on commit aad9c7e

Please sign in to comment.