From 442e59f62e50d48a8a0464247714a2566a558e41 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Fri, 2 Dec 2022 23:26:43 +0530 Subject: [PATCH 01/12] watch: add CLI flag to preserve output Added a --watch-preserve-output flag to watch mode Fixes: https://github.com/nodejs/node/issues/45713 --- lib/internal/main/watch_mode.js | 7 ++++--- src/node_options.cc | 4 ++++ src/node_options.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index ea02190fa13d00..c943d9432065f5 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -34,10 +34,11 @@ markBootstrapComplete(); const kKillSignal = 'SIGTERM'; const kShouldFilterModules = getOptionValue('--watch-path').length === 0; const kWatchedPaths = ArrayPrototypeMap(getOptionValue('--watch-path'), (path) => resolve(path)); +const kPreserveOutput = getOptionValue('--preserve-output'); const kCommand = ArrayPrototypeSlice(process.argv, 1); const kCommandStr = inspect(ArrayPrototypeJoin(kCommand, ' ')); const args = ArrayPrototypeFilter(process.execArgv, (arg, i, arr) => - arg !== '--watch-path' && arr[i - 1] !== '--watch-path' && arg !== '--watch'); + arg !== '--watch-path' && arr[i - 1] !== '--watch-path' && arg !== '--watch' && arg !== '--preserve-output'); ArrayPrototypePushApply(args, kCommand); const watcher = new FilesWatcher({ throttle: 500, mode: kShouldFilterModules ? 'filter' : 'all' }); @@ -99,8 +100,8 @@ async function stop() { clearGraceReport(); } -async function restart() { - process.stdout.write(`${clear}${green}Restarting ${kCommandStr}${white}\n`); +async function restart() {; + process.stdout.write(`${kPreserveOutput ? '' : clear}${green}Restarting ${kCommandStr}${white}\n`); await stop(); start(); } diff --git a/src/node_options.cc b/src/node_options.cc index a5365987129ac7..d6d9b9363fde21 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -613,6 +613,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "path to watch", &EnvironmentOptions::watch_mode_paths, kAllowedInEnvvar); + AddOption("--preserve-output", + "preserve outputs on watch mode restart", + &EnvironmentOptions::preserve_output, + kAllowedInEnvvar); Implies("--watch-path", "--watch"); AddOption("--check", "syntax check script without executing", diff --git a/src/node_options.h b/src/node_options.h index 02beddccdf01c8..60abcbdd64dc98 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -177,6 +177,7 @@ class EnvironmentOptions : public Options { bool watch_mode = false; bool watch_mode_report_to_parent = false; + bool preserve_output = false; std::vector watch_mode_paths; bool syntax_check_only = false; From a7c305342f6ce4b548f0b11aa3d305d16aae81d6 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 00:27:34 +0530 Subject: [PATCH 02/12] test: add test for preserve-output --- test/sequential/test-watch-mode.mjs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/sequential/test-watch-mode.mjs b/test/sequential/test-watch-mode.mjs index c8d0474d031c44..b0d7c5612f2e46 100644 --- a/test/sequential/test-watch-mode.mjs +++ b/test/sequential/test-watch-mode.mjs @@ -280,4 +280,30 @@ describe('watch mode', { concurrency: false, timeout: 60_000 }, () => { await failWriteSucceed({ file: dependant, watchedFile: dependency }); }); + + it('should preserve output when --preserve-output flag is passed', async () => { + const file = createTmpFile(); + console.log(file); + const { stderr, stdout } = await spawnWithRestarts({ + file, + args: ['--preserve-output', file], + }); + + assert.strictEqual(stderr, ''); + // Checks if the existing output is preserved + assertRestartedCorrectly({ + stdout, + messages: { + inner: 'running', + restarted: `Restarting ${inspect(file)}`, + completed: `Completed running ${inspect(file)}`, + }, + }); + // Remove the first 3 lines from stdout + const lines = stdout.split(/\r?\n/).filter(Boolean).slice(3); + assert.deepStrictEqual(lines, [ + 'running', + `Completed running ${inspect(file)}`, + ]); + }); }); From ae8d1fa5f93f23c82358e094fb9626f7fcfcd727 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 00:27:59 +0530 Subject: [PATCH 03/12] lib,src: fixed linting issues --- lib/internal/main/watch_mode.js | 6 ++++-- src/node_options.cc | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index c943d9432065f5..f611ec42ed4210 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -100,8 +100,10 @@ async function stop() { clearGraceReport(); } -async function restart() {; - process.stdout.write(`${kPreserveOutput ? '' : clear}${green}Restarting ${kCommandStr}${white}\n`); +async function restart() { + process.stdout.write( + `${kPreserveOutput ? '' : clear}${green}Restarting ${kCommandStr}${white}\n` + ); await stop(); start(); } diff --git a/src/node_options.cc b/src/node_options.cc index d6d9b9363fde21..f97de32e676c66 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -613,7 +613,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "path to watch", &EnvironmentOptions::watch_mode_paths, kAllowedInEnvvar); - AddOption("--preserve-output", + AddOption("--preserve-output", "preserve outputs on watch mode restart", &EnvironmentOptions::preserve_output, kAllowedInEnvvar); From ffb79dcafdf9cdfcfd4e45ebab0e360edc012f4e Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 01:02:40 +0530 Subject: [PATCH 04/12] lib,src: refactor naming of flag --- lib/internal/main/watch_mode.js | 4 ++-- src/node_options.cc | 4 ++-- src/node_options.h | 2 +- test/sequential/test-watch-mode.mjs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index f611ec42ed4210..2f133cfe0695a2 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -34,11 +34,11 @@ markBootstrapComplete(); const kKillSignal = 'SIGTERM'; const kShouldFilterModules = getOptionValue('--watch-path').length === 0; const kWatchedPaths = ArrayPrototypeMap(getOptionValue('--watch-path'), (path) => resolve(path)); -const kPreserveOutput = getOptionValue('--preserve-output'); +const kPreserveOutput = getOptionValue('--watch-preserve-output'); const kCommand = ArrayPrototypeSlice(process.argv, 1); const kCommandStr = inspect(ArrayPrototypeJoin(kCommand, ' ')); const args = ArrayPrototypeFilter(process.execArgv, (arg, i, arr) => - arg !== '--watch-path' && arr[i - 1] !== '--watch-path' && arg !== '--watch' && arg !== '--preserve-output'); + arg !== '--watch-path' && arr[i - 1] !== '--watch-path' && arg !== '--watch' && arg !== '--watch-preserve-output'); ArrayPrototypePushApply(args, kCommand); const watcher = new FilesWatcher({ throttle: 500, mode: kShouldFilterModules ? 'filter' : 'all' }); diff --git a/src/node_options.cc b/src/node_options.cc index f97de32e676c66..64ceecb972f656 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -613,9 +613,9 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "path to watch", &EnvironmentOptions::watch_mode_paths, kAllowedInEnvvar); - AddOption("--preserve-output", + AddOption("--watch-preserve-output", "preserve outputs on watch mode restart", - &EnvironmentOptions::preserve_output, + &EnvironmentOptions::watch_mode_preserve_output, kAllowedInEnvvar); Implies("--watch-path", "--watch"); AddOption("--check", diff --git a/src/node_options.h b/src/node_options.h index 60abcbdd64dc98..d812a1aa4698e1 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -177,7 +177,7 @@ class EnvironmentOptions : public Options { bool watch_mode = false; bool watch_mode_report_to_parent = false; - bool preserve_output = false; + bool watch_mode_preserve_output = false; std::vector watch_mode_paths; bool syntax_check_only = false; diff --git a/test/sequential/test-watch-mode.mjs b/test/sequential/test-watch-mode.mjs index b0d7c5612f2e46..5478d4a151b9dc 100644 --- a/test/sequential/test-watch-mode.mjs +++ b/test/sequential/test-watch-mode.mjs @@ -281,12 +281,12 @@ describe('watch mode', { concurrency: false, timeout: 60_000 }, () => { await failWriteSucceed({ file: dependant, watchedFile: dependency }); }); - it('should preserve output when --preserve-output flag is passed', async () => { + it('should preserve output when --watch-preserve-output flag is passed', async () => { const file = createTmpFile(); console.log(file); const { stderr, stdout } = await spawnWithRestarts({ file, - args: ['--preserve-output', file], + args: ['--watch-preserve-output', file], }); assert.strictEqual(stderr, ''); From 821649555f0f9088ce53a745b2fcf3307efa9230 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 01:02:59 +0530 Subject: [PATCH 05/12] doc: add option to doc --- doc/api/cli.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/api/cli.md b/doc/api/cli.md index c09066a29a1dec..a98c6d73ed4a3f 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1628,6 +1628,14 @@ This option is only supported on macOS and Windows. An `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` exception will be thrown when the option is used on a platform that does not support it. +### --watch-preserve-output + +Option to ensure output of stdout is preserved during --watch on restart + +```console +$ node --watch --watch-preserve-output test.js +``` + ### `--zero-fill-buffers` From 624c2084c67c6d90161686ca0aa06289d438cb89 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 01:10:07 +0530 Subject: [PATCH 06/12] doc: fix option ordering --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index a98c6d73ed4a3f..cab429e6ca3390 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1940,8 +1940,8 @@ Node.js options that are allowed are: * `--use-openssl-ca` * `--v8-pool-size` * `--watch-path` -* `--watch` * `--watch-preserve-output` +* `--watch` * `--zero-fill-buffers` From 2b4a7c164fe3ad4289343b0f18877aa65003c264 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 01:45:10 +0530 Subject: [PATCH 07/12] test: remove unnecessary console Co-authored-by: Mohammed Keyvanzadeh --- test/sequential/test-watch-mode.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/sequential/test-watch-mode.mjs b/test/sequential/test-watch-mode.mjs index 5478d4a151b9dc..fbfd887571e6af 100644 --- a/test/sequential/test-watch-mode.mjs +++ b/test/sequential/test-watch-mode.mjs @@ -283,7 +283,6 @@ describe('watch mode', { concurrency: false, timeout: 60_000 }, () => { it('should preserve output when --watch-preserve-output flag is passed', async () => { const file = createTmpFile(); - console.log(file); const { stderr, stdout } = await spawnWithRestarts({ file, args: ['--watch-preserve-output', file], From fd60b8517fd5f2c3f375195d4bfc68f3a5e2ae6d Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sat, 3 Dec 2022 23:14:55 +0530 Subject: [PATCH 08/12] lib: store clear output in a const --- lib/internal/main/watch_mode.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index 2f133cfe0695a2..f72288d10beb74 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -101,8 +101,9 @@ async function stop() { } async function restart() { + const clearOutput = kPreserveOutput ? '' : clear; process.stdout.write( - `${kPreserveOutput ? '' : clear}${green}Restarting ${kCommandStr}${white}\n` + `${clearOutput}${green}Restarting ${kCommandStr}${white}\n` ); await stop(); start(); From 4b510fe60ea95bf5bf73fe05b4997fa72072ce48 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sun, 11 Dec 2022 22:44:53 +0530 Subject: [PATCH 09/12] doc: update content Co-authored-by: Antoine du Hamel --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index cab429e6ca3390..491512057867b1 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1630,7 +1630,7 @@ when the option is used on a platform that does not support it. ### --watch-preserve-output -Option to ensure output of stdout is preserved during --watch on restart +Option to ensure output of stdout is preserved during --watch on restart. ```console $ node --watch --watch-preserve-output test.js From 337274b2858d345e147b56c87f89bb856198b0eb Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sun, 11 Dec 2022 22:45:42 +0530 Subject: [PATCH 10/12] lib: refactor writing output Co-authored-by: Antoine du Hamel --- lib/internal/main/watch_mode.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index f72288d10beb74..219b31d8c20e16 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -101,10 +101,8 @@ async function stop() { } async function restart() { - const clearOutput = kPreserveOutput ? '' : clear; - process.stdout.write( - `${clearOutput}${green}Restarting ${kCommandStr}${white}\n` - ); + if (!kPreserveOutput) process.stdout.write(clear); + process.stdout.write(`${green}Restarting ${kCommandStr}${white}\n`); await stop(); start(); } From 41ed235d6d74049d796267e0407912b29a1e7277 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sun, 11 Dec 2022 23:00:25 +0530 Subject: [PATCH 11/12] doc: update content Co-authored-by: Antoine du Hamel --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 491512057867b1..d288f56a69349b 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1628,7 +1628,7 @@ This option is only supported on macOS and Windows. An `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` exception will be thrown when the option is used on a platform that does not support it. -### --watch-preserve-output +### `--watch-preserve-output` Option to ensure output of stdout is preserved during --watch on restart. From dafdb5827c397b3be68beb57a39d450e71451338 Mon Sep 17 00:00:00 2001 From: Debadree Chatterjee Date: Sun, 11 Dec 2022 23:00:44 +0530 Subject: [PATCH 12/12] doc: update content Co-authored-by: Antoine du Hamel --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index d288f56a69349b..988ded3d679ced 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1630,7 +1630,7 @@ when the option is used on a platform that does not support it. ### `--watch-preserve-output` -Option to ensure output of stdout is preserved during --watch on restart. +Disable the clearing of the console when watch mode restarts the process. ```console $ node --watch --watch-preserve-output test.js