watch: print name of changed file that triggers restart

Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/63781
Fixes: https://github.com/nodejs/node/issues/63767
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Marco authored and GitHub committed 2026-06-22 05:55:19 +00:00
1 parent 519294e4c8
commit ac6ee057fb
5 files changed
+57 -5

No files matched your search

+7 -4
View File
@@ -20,7 +20,7 @@ const {
const { getOptionValue } = require('internal/options');
const { FilesWatcher } = require('internal/watch_mode/files_watcher');
const { green, blue, red, white, clear } = require('internal/util/colors');
const { convertToValidSignal } = require('internal/util');
const { convertToValidSignal, kEmptyObject } = require('internal/util');
const { spawn } = require('child_process');
const { inspect } = require('util');
@@ -169,11 +169,14 @@ async function stop(child) {
let restarting = false;
async function restart(child) {
async function restart(child, trigger) {
if (restarting) return;
restarting = true;
try {
if (!kPreserveOutput) process.stdout.write(clear);
if (trigger) {
process.stdout.write(`${blue}Change detected in ${inspect(trigger)}${white}\n`);
}
process.stdout.write(`${green}Restarting ${kCommandStr}${white}\n`);
await stop(child);
return start();
@@ -184,8 +187,8 @@ async function restart(child) {
async function init() {
let child = start();
const restartChild = async () => {
child = await restart(child);
const restartChild = async ({ trigger } = kEmptyObject) => {
child = await restart(child, trigger);
};
watcher
.on('changed', restartChild)
+5 -1
View File
@@ -39,6 +39,7 @@ class FilesWatcher extends EventEmitter {
#ownerDependencies = new SafeMap();
#debounceOwners = new SafeSet();
#debounceTimer;
#debounceTrigger;
#debounce;
#mode;
#signal;
@@ -98,11 +99,13 @@ class FilesWatcher extends EventEmitter {
this.#debounceOwners.add(owner);
}
}
this.#debounceTrigger = trigger;
clearTimeout(this.#debounceTimer);
this.#debounceTimer = setTimeout(() => {
this.#debounceTimer = null;
this.emit('changed', { owners: this.#debounceOwners, eventType });
this.emit('changed', { owners: this.#debounceOwners, eventType, trigger: this.#debounceTrigger });
this.#debounceOwners.clear();
this.#debounceTrigger = undefined;
}, this.#debounce).unref();
}
@@ -207,6 +210,7 @@ class FilesWatcher extends EventEmitter {
clearTimeout(this.#debounceTimer);
this.#debounceTimer = null;
this.#debounceOwners.clear();
this.#debounceTrigger = undefined;
this.#watchers.forEach(this.#unwatch);
this.#watchers.clear();
this.#filteredFiles.clear();
@@ -120,6 +120,7 @@ try {
const { stderr: stderr2, stdout: stdout2 } = await failedRestart;
assert.match(stderr2, /SyntaxError: Invalid or unexpected token/);
assert.deepStrictEqual(stdout2, [
`Change detected in ${inspect(file)}`,
`Restarting ${inspect(file)}`,
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
@@ -132,6 +133,7 @@ try {
// Verify it recovered and ran successfully
assert.strictEqual(stderr3, '');
assert.deepStrictEqual(stdout3, [
`Change detected in ${inspect(file)}`,
`Restarting ${inspect(file)}`,
'hello again, world',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -19,6 +19,10 @@ function restart(file) {
return () => clearInterval(timer);
}
function changeDetected(file) {
return `Change detected in ${inspect(file)}`;
}
let tmpFiles = 0;
function createTmpFile(content = 'console.log(\'running\');', ext = '.js', basename = tmpdir.path) {
const file = path.join(basename, `${tmpFiles++}${ext}`);
@@ -108,6 +112,7 @@ const w = new Worker(${JSON.stringify(worker)});
assert.deepStrictEqual(stdout, [
'worker running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(worker),
`Restarting ${inspect(file)}`,
'worker running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -142,6 +147,7 @@ const w = new Worker(${JSON.stringify(worker)});
assert.deepStrictEqual(stdout, [
'dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(dep),
`Restarting ${inspect(file)}`,
'dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -182,6 +188,7 @@ const w = new Worker(${JSON.stringify(worker)});
assert.deepStrictEqual(stdout, [
'sub-dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(subDep),
`Restarting ${inspect(file)}`,
'sub-dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -210,6 +217,7 @@ new Worker(new URL(${JSON.stringify(pathToFileURL(worker))}));
assert.deepStrictEqual(stdout, [
'worker running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(worker),
`Restarting ${inspect(file)}`,
'worker running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -244,6 +252,7 @@ new Worker(new URL(${JSON.stringify(pathToFileURL(worker))}));
assert.deepStrictEqual(stdout, [
'dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(dep),
`Restarting ${inspect(file)}`,
'dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -284,6 +293,7 @@ new Worker(new URL(${JSON.stringify(pathToFileURL(worker))}));
assert.deepStrictEqual(stdout, [
'sub-dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(subDep),
`Restarting ${inspect(file)}`,
'sub-dep v1',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
+33
View File
@@ -23,6 +23,10 @@ function restart(file, content = readFileSync(file)) {
return () => clearInterval(timer);
}
function changeDetected(file) {
return `Change detected in ${inspect(file)}`;
}
let tmpFiles = 0;
function createTmpFile(content = 'console.log("running");', ext = '.js', basename = tmpdir.path) {
const file = path.join(basename, `${tmpFiles++}${ext}`);
@@ -198,6 +202,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -212,6 +217,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -233,6 +239,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
changeDetected(envFile),
`Restarting ${inspect(jsFile)}`,
'ENV: value2',
`Completed running ${inspect(jsFile)}. Waiting for file changes before restarting...`,
@@ -258,6 +265,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
changeDetected(envFile),
`Restarting ${inspect(jsFile)}`,
'ENV: value1',
'ENV2: newValue',
@@ -284,6 +292,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
changeDetected(envFile),
`Restarting ${inspect(jsFile)}`,
'ENV: value1',
'ENV2: newValue',
@@ -327,6 +336,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.match(stderr, /Error: fails\r?\n/);
assert.deepStrictEqual(stdout, [
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
@@ -346,6 +356,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -372,6 +383,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.match(stderr, /Error: Cannot find module/g);
assert.deepStrictEqual(stdout, [
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
@@ -396,6 +408,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.match(stderr, /Error: Cannot find module/g);
assert.deepStrictEqual(stdout, [
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
`Failed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
@@ -411,6 +424,7 @@ console.log("don't show me");`);
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
'running',
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
]);
@@ -428,6 +442,7 @@ console.log(dependency);
assert.deepStrictEqual(stdout, [
'{}',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(dependency),
`Restarting ${inspect(file)}`,
'{}',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -446,6 +461,7 @@ console.log(dependency);
assert.deepStrictEqual(stdout, [
'{}',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(dependency),
`Restarting ${inspect(file)}`,
'{}',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -460,9 +476,11 @@ console.log(dependency);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -483,6 +501,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
random,
`Completed running ${inspect(`${file} --random ${random}`)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(`${file} --random ${random}`)}`,
random,
`Completed running ${inspect(`${file} --random ${random}`)}. Waiting for file changes before restarting...`,
@@ -500,6 +519,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -520,6 +540,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -569,6 +590,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -584,6 +606,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -615,6 +638,7 @@ console.log(values.random);
'hello',
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'hello',
'running',
@@ -647,6 +671,7 @@ console.log(values.random);
'hello',
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'hello',
'running',
@@ -679,6 +704,7 @@ console.log(values.random);
'hello',
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'hello',
'running',
@@ -711,6 +737,7 @@ console.log(values.random);
'hello',
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'hello',
'running',
@@ -727,6 +754,7 @@ console.log(values.random);
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -752,6 +780,7 @@ console.log(values.random);
'hello',
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'hello',
'running',
@@ -832,6 +861,7 @@ process.on('message', (message) => {
assert.deepStrictEqual(lines, [
'running',
'Received: first message',
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
'Received: second message',
@@ -852,6 +882,7 @@ process.on('message', (message) => {
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -874,6 +905,7 @@ process.on('message', (message) => {
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(watchedFile),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
@@ -902,6 +934,7 @@ process.on('message', (message) => {
assert.deepStrictEqual(stdout, [
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
changeDetected(file),
`Restarting ${inspect(file)}`,
'running',
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,