From 6782af5c483450eb3044578bb83c1addce2d840f Mon Sep 17 00:00:00 2001 From: clavin Date: Thu, 7 Jul 2022 11:50:52 -0600 Subject: [PATCH 1/3] fix: keep stdin unpaused after ora completes --- packages/api/core/src/api/start.ts | 10 ++++++++-- packages/utils/async-ora/src/ora-handler.ts | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/api/core/src/api/start.ts b/packages/api/core/src/api/start.ts index 8b5d69fa0f..168761c08f 100644 --- a/packages/api/core/src/api/start.ts +++ b/packages/api/core/src/api/start.ts @@ -27,6 +27,7 @@ export default async ({ inspectBrk = false, }: StartOptions): Promise => { asyncOra.interactive = interactive; + asyncOra.keepStdinFlowing = true; await asyncOra('Locating Application', async () => { const resolvedDir = await resolveDir(dir); @@ -131,9 +132,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(); @@ -153,6 +158,7 @@ export default async ({ lastSpawned.emit('restarted', await forgeSpawnWrapper()); } }); + process.stdin.resume(); } return forgeSpawnWrapper(); diff --git a/packages/utils/async-ora/src/ora-handler.ts b/packages/utils/async-ora/src/ora-handler.ts index 0e3f54af77..068cfe1f03 100644 --- a/packages/utils/async-ora/src/ora-handler.ts +++ b/packages/utils/async-ora/src/ora-handler.ts @@ -30,6 +30,13 @@ export class OraImpl { export interface AsyncOraMethod { (initialOraValue: string, asyncFn: (oraImpl: OraImpl) => Promise, processExitFn?: (code: number) => void): Promise; 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. + */ + keepStdinFlowing?: boolean; } const asyncOra: AsyncOraMethod = (initialOraValue, asyncFn, processExitFn = process.exit) => { @@ -40,7 +47,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) => { From ee0595347043e46b2917815424ebba055326c2d9 Mon Sep 17 00:00:00 2001 From: clavin Date: Fri, 8 Jul 2022 10:34:05 -0600 Subject: [PATCH 2/3] add more context --- packages/utils/async-ora/src/ora-handler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/utils/async-ora/src/ora-handler.ts b/packages/utils/async-ora/src/ora-handler.ts index 068cfe1f03..feee847adf 100644 --- a/packages/utils/async-ora/src/ora-handler.ts +++ b/packages/utils/async-ora/src/ora-handler.ts @@ -35,6 +35,9 @@ export interface AsyncOraMethod { * 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; } From 2265971fc4eddd8eebcfcb0bb28044073301359a Mon Sep 17 00:00:00 2001 From: clavin Date: Fri, 8 Jul 2022 15:35:31 -0600 Subject: [PATCH 3/3] sprinkle just a little bit more context on top --- packages/api/core/src/api/start.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/api/core/src/api/start.ts b/packages/api/core/src/api/start.ts index 168761c08f..5416987764 100644 --- a/packages/api/core/src/api/start.ts +++ b/packages/api/core/src/api/start.ts @@ -27,6 +27,10 @@ export default async ({ inspectBrk = false, }: StartOptions): Promise => { 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 () => {