From 2fca80ad0f38610f637e3013701239e9ffe05d5a Mon Sep 17 00:00:00 2001 From: DanieleAurilio Date: Sun, 24 Nov 2024 17:09:40 +0100 Subject: [PATCH 1/5] fix(runtime/ops): Fix watchfs remove event --- runtime/ops/fs_events.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs index a91722f91a1ad0..d78a03040809f9 100644 --- a/runtime/ops/fs_events.rs +++ b/runtime/ops/fs_events.rs @@ -150,6 +150,16 @@ fn start_watcher( }) }) { let _ = sender.try_send(Ok(event.clone())); + } else { + // If the event is a remove event, we need to check if the path that was deleted + if event.kind.eq("remove") && event.paths.iter().any(|event_path| !event_path.exists()) { + let remove_event = FsEvent { + kind: "remove", + paths: event.paths.iter().map(PathBuf::from).collect(), + flag: None, + }; + let _ = sender.try_send(Ok(remove_event)); + } } } } From d6b28cae578a7ade5c59d7ae42e492b3a5d69b16 Mon Sep 17 00:00:00 2001 From: DanieleAurilio Date: Sun, 24 Nov 2024 18:04:43 +0100 Subject: [PATCH 2/5] Lint and fix check with std fs --- runtime/ops/fs_events.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs index d78a03040809f9..3468b6572180f7 100644 --- a/runtime/ops/fs_events.rs +++ b/runtime/ops/fs_events.rs @@ -152,7 +152,12 @@ fn start_watcher( let _ = sender.try_send(Ok(event.clone())); } else { // If the event is a remove event, we need to check if the path that was deleted - if event.kind.eq("remove") && event.paths.iter().any(|event_path| !event_path.exists()) { + if event.kind.eq("remove") + && event + .paths + .iter() + .any(|event_path| std::fs::exists(event_path).unwrap_or(false)) + { let remove_event = FsEvent { kind: "remove", paths: event.paths.iter().map(PathBuf::from).collect(), From 44611fae7bda6c2104d9b079bb51d3487dabd4ff Mon Sep 17 00:00:00 2001 From: DanieleAurilio Date: Sun, 24 Nov 2024 18:27:48 +0100 Subject: [PATCH 3/5] Add watchFSRemove test --- tests/unit/fs_events_test.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/unit/fs_events_test.ts b/tests/unit/fs_events_test.ts index cc2f2cd5711242..1b3277431fe8a8 100644 --- a/tests/unit/fs_events_test.ts +++ b/tests/unit/fs_events_test.ts @@ -45,6 +45,14 @@ async function makeTempDir(): Promise { return testDir; } +async function makeTempFile(): Promise { + const testFile = await Deno.makeTempFile(); + // The watcher sometimes witnesses the creation of it's own root + // directory. Delay a bit. + await delay(100); + return testFile; +} + Deno.test( { permissions: { read: true, write: true } }, async function watchFsBasic() { @@ -155,3 +163,20 @@ Deno.test( assert(done); }, ); + +Deno.test( + { permissions: { read: true, write: true } }, + async function watchFsRemove() { + const testDir = await makeTempDir(); + const testFile = await makeTempFile(); + using iter = Deno.watchFs(testDir); + + await Deno.remove(testFile, { recursive: true }); + + const res = iter[Symbol.asyncIterator]().next(); + + iter.close(); + const { done } = await res; + assert(done); + }, +); From 0da96443d6cc802489e7242ec7a760b11121b9d4 Mon Sep 17 00:00:00 2001 From: DanieleAurilio Date: Sun, 24 Nov 2024 18:48:57 +0100 Subject: [PATCH 4/5] Fix watchFSRemove test --- tests/unit/fs_events_test.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/unit/fs_events_test.ts b/tests/unit/fs_events_test.ts index 1b3277431fe8a8..3be99304affa0d 100644 --- a/tests/unit/fs_events_test.ts +++ b/tests/unit/fs_events_test.ts @@ -167,16 +167,21 @@ Deno.test( Deno.test( { permissions: { read: true, write: true } }, async function watchFsRemove() { - const testDir = await makeTempDir(); const testFile = await makeTempFile(); - using iter = Deno.watchFs(testDir); + using watcher = Deno.watchFs(testFile); + async function waitForRemove() { + for await (const event of watcher) { + if (event.kind === "remove") { + return event; + } + } + } + const eventsPromise = waitForRemove(); - await Deno.remove(testFile, { recursive: true }); + await Deno.remove(testFile); - const res = iter[Symbol.asyncIterator]().next(); - - iter.close(); - const { done } = await res; - assert(done); + // Expect zero events. + const events = await eventsPromise; + assertEquals(events!.kind, "remove"); }, ); From 02123d565622fc68cab63c3a27e30de4c3366323 Mon Sep 17 00:00:00 2001 From: DanieleAurilio Date: Sun, 24 Nov 2024 20:53:55 +0100 Subject: [PATCH 5/5] Refactor code --- runtime/ops/fs_events.rs | 30 +++++++++++++++--------------- tests/unit/fs_events_test.ts | 6 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs index 3468b6572180f7..f6e5ceff5c8488 100644 --- a/runtime/ops/fs_events.rs +++ b/runtime/ops/fs_events.rs @@ -109,6 +109,14 @@ fn starts_with_canonicalized(path: &Path, prefix: &str) -> bool { } } +fn is_file_removed(event_path: &PathBuf) -> bool { + let exists_path = std::fs::exists(event_path); + match exists_path { + Ok(res) => !res, + Err(_) => false, + } +} + #[derive(Debug, thiserror::Error)] pub enum FsEventsError { #[error(transparent)] @@ -150,21 +158,13 @@ fn start_watcher( }) }) { let _ = sender.try_send(Ok(event.clone())); - } else { - // If the event is a remove event, we need to check if the path that was deleted - if event.kind.eq("remove") - && event - .paths - .iter() - .any(|event_path| std::fs::exists(event_path).unwrap_or(false)) - { - let remove_event = FsEvent { - kind: "remove", - paths: event.paths.iter().map(PathBuf::from).collect(), - flag: None, - }; - let _ = sender.try_send(Ok(remove_event)); - } + } else if event.paths.iter().any(is_file_removed) { + let remove_event = FsEvent { + kind: "remove", + paths: event.paths.clone(), + flag: None, + }; + let _ = sender.try_send(Ok(remove_event)); } } } diff --git a/tests/unit/fs_events_test.ts b/tests/unit/fs_events_test.ts index 3be99304affa0d..7489626b9f68bc 100644 --- a/tests/unit/fs_events_test.ts +++ b/tests/unit/fs_events_test.ts @@ -176,12 +176,12 @@ Deno.test( } } } - const eventsPromise = waitForRemove(); + const eventPromise = waitForRemove(); await Deno.remove(testFile); // Expect zero events. - const events = await eventsPromise; - assertEquals(events!.kind, "remove"); + const event = await eventPromise; + assertEquals(event!.kind, "remove"); }, );