diff --git a/src/bun.js/node/fs_events.zig b/src/bun.js/node/fs_events.zig index 27132aa773..ed1e6100a0 100644 --- a/src/bun.js/node/fs_events.zig +++ b/src/bun.js/node/fs_events.zig @@ -374,23 +374,19 @@ pub const FSEventsLoop = struct { path = path[handle_path.len..]; // Ignore events with path equal to directory itself - if (path.len <= 1 and is_file) { + if (path.len <= 1 and !is_file) { continue; } - if (path.len == 0) { - // Since we're using fsevents to watch the file itself, path == handle_path, and we now need to get the basename of the file back - while (path.len > 0) { - if (bun.strings.startsWithChar(path, '/')) { - path = path[1..]; - break; - } else { - path = path[1..]; - } - } + if (path.len == 0) { + // Since we're using fsevents to watch the file itself handle_path == path, and we now need to get the basename of the file back + const basename = bun.strings.lastIndexOfChar(handle_path, '/') orelse handle_path.len; + path = handle_path[basename..]; // Created and Removed seem to be always set, but don't make sense flags &= ~kFSEventsRenamed; - } else { + } + + if (bun.strings.startsWithChar(path, '/')) { // Skip forward slash path = path[1..]; } diff --git a/src/bun.js/node/path_watcher.zig b/src/bun.js/node/path_watcher.zig index 663858947b..2560e8ed62 100644 --- a/src/bun.js/node/path_watcher.zig +++ b/src/bun.js/node/path_watcher.zig @@ -239,16 +239,8 @@ pub const PathWatcherManager = struct { if (path.len <= 1) { continue; } - if (path.len == 0) { - while (path.len > 0) { - if (bun.strings.startsWithChar(path, '/')) { - path = path[1..]; - break; - } else { - path = path[1..]; - } - } - } else { + + if (bun.strings.startsWithChar(path, '/')) { // Skip forward slash path = path[1..]; } diff --git a/test/js/node/watch/fixtures/relative.js b/test/js/node/watch/fixtures/relative.js index 692d809ec9..01254e598a 100644 --- a/test/js/node/watch/fixtures/relative.js +++ b/test/js/node/watch/fixtures/relative.js @@ -3,7 +3,7 @@ try { const watcher = fs.watch("relative.txt", { signal: AbortSignal.timeout(2000) }); watcher.on("change", function (event, filename) { - if (filename !== "relative.txt" && event !== "change") { + if (filename !== "relative.txt" || event !== "change") { console.error("fail"); clearInterval(interval); watcher.close(); diff --git a/test/js/node/watch/fixtures/relative_dir.js b/test/js/node/watch/fixtures/relative_dir.js new file mode 100644 index 0000000000..4ad6c17133 --- /dev/null +++ b/test/js/node/watch/fixtures/relative_dir.js @@ -0,0 +1,28 @@ +import fs from "fs"; +try { + const watcher = fs.watch("./myrelativedir/", { signal: AbortSignal.timeout(2000) }); + + watcher.on("change", function (event, filename) { + if (filename !== "relative.txt") { + console.error("fail", filename, event); + clearInterval(interval); + watcher.close(); + process.exit(1); + } else { + clearInterval(interval); + watcher.close(); + } + }); + watcher.on("error", err => { + clearInterval(interval); + console.error(err.message); + process.exit(1); + }); + + const interval = setInterval(() => { + fs.writeFileSync("./myrelativedir/relative.txt", "world"); + }, 10); +} catch (err) { + console.error(err.message); + process.exit(1); +} diff --git a/test/js/node/watch/fs.watch.test.ts b/test/js/node/watch/fs.watch.test.ts index 4a95fc13a6..72393ee9e0 100644 --- a/test/js/node/watch/fs.watch.test.ts +++ b/test/js/node/watch/fs.watch.test.ts @@ -64,6 +64,19 @@ describe("fs.watch", () => { } }); + test("should work with relative dirs", done => { + try { + const myrelativedir = path.join(testDir, "myrelativedir"); + try { + fs.mkdirSync(myrelativedir); + } catch {} + fs.writeFileSync(path.join(myrelativedir, "relative.txt"), "hello"); + bunRunAsScript(testDir, path.join(import.meta.dir, "fixtures", "relative_dir.js")); + done(); + } catch (e: any) { + done(e); + } + }); test("add file/folder to folder", done => { let count = 0; const root = path.join(testDir, "add-directory");