Skip to content

Commit 551a92d

Browse files
committed
fs: fix nonNativeWatcher watching folder with existing files
PR-URL: nodejs#45500 Reviewed-By: Yagiz Nizipli <[email protected]>
1 parent 1c6772a commit 551a92d

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/internal/fs/recursive_watch.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ class FSWatcher extends EventEmitter {
199199
this.emit('change', 'rename', pathRelative(this.#rootPath, file));
200200
} else if (currentStats.isDirectory()) {
201201
this.#watchFolder(file);
202+
} else {
203+
// Watching a directory will trigger a change event for child files)
204+
this.emit('change', 'change', pathRelative(this.#rootPath, file));
202205
}
203206
});
204207
}

test/parallel/test-fs-watch-recursive.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,36 @@ process.on('exit', function() {
5454
assert(watcherClosed, 'watcher Object was not closed');
5555
});
5656

57+
(async () => {
58+
// Watch a folder and update an already existing file in it.
59+
60+
const rootDirectory = fs.mkdtempSync(testDir + path.sep);
61+
const testDirectory = path.join(rootDirectory, 'test-0');
62+
fs.mkdirSync(testDirectory);
63+
64+
const testFile = path.join(testDirectory, 'file-1.txt');
65+
fs.writeFileSync(testFile, 'hello');
66+
67+
const watcher = fs.watch(testDirectory, { recursive: true });
68+
let watcherClosed = false;
69+
watcher.on('change', common.mustCallAtLeast(function(event, filename) {
70+
// Libuv inconsistenly emits a rename event for the file we are watching
71+
assert.ok(event === 'change' || event === 'rename');
72+
73+
if (filename === path.basename(testFile)) {
74+
watcher.close();
75+
watcherClosed = true;
76+
}
77+
}));
78+
79+
await setTimeout(common.platformTimeout(100));
80+
fs.writeFileSync(testFile, 'hello');
81+
82+
process.once('exit', function() {
83+
assert(watcherClosed, 'watcher Object was not closed');
84+
});
85+
})().then(common.mustCall());
86+
5787
(async () => {
5888
// Assert recursive watch does not leak handles
5989
const rootDirectory = fs.mkdtempSync(testDir + path.sep);

0 commit comments

Comments
 (0)