From 442e59f62e50d48a8a0464247714a2566a558e41 Mon Sep 17 00:00:00 2001
From: Debadree Chatterjee <debadree333@gmail.com>
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<std::string> watch_mode_paths;
 
   bool syntax_check_only = false;

From a7c305342f6ce4b548f0b11aa3d305d16aae81d6 Mon Sep 17 00:00:00 2001
From: Debadree Chatterjee <debadree333@gmail.com>
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 <debadree333@gmail.com>
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 <debadree333@gmail.com>
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<std::string> 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 <debadree333@gmail.com>
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`
 
 <!-- YAML
@@ -1933,6 +1941,7 @@ Node.js options that are allowed are:
 * `--v8-pool-size`
 * `--watch-path`
 * `--watch`
+* `--watch-preserve-output`
 * `--zero-fill-buffers`
 
 <!-- node-options-node end -->

From 624c2084c67c6d90161686ca0aa06289d438cb89 Mon Sep 17 00:00:00 2001
From: Debadree Chatterjee <debadree333@gmail.com>
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`
 
 <!-- node-options-node end -->

From 2b4a7c164fe3ad4289343b0f18877aa65003c264 Mon Sep 17 00:00:00 2001
From: Debadree Chatterjee <debadree333@gmail.com>
Date: Sat, 3 Dec 2022 01:45:10 +0530
Subject: [PATCH 07/12] test: remove unnecessary console

Co-authored-by: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
---
 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 <debadree333@gmail.com>
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 <debadree333@gmail.com>
Date: Sun, 11 Dec 2022 22:44:53 +0530
Subject: [PATCH 09/12] doc: update content

Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
---
 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 <debadree333@gmail.com>
Date: Sun, 11 Dec 2022 22:45:42 +0530
Subject: [PATCH 10/12] lib: refactor writing output

Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
---
 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 <debadree333@gmail.com>
Date: Sun, 11 Dec 2022 23:00:25 +0530
Subject: [PATCH 11/12] doc: update content

Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
---
 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 <debadree333@gmail.com>
Date: Sun, 11 Dec 2022 23:00:44 +0530
Subject: [PATCH 12/12] doc: update content

Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
---
 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