1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-01 20:09:02 -05:00

fix(runtime/ops): Fix watchfs remove event (#27041)

Fix related to #26906. 
Currently, if a file is removed, no event is emitted because the file
path no longer exists. As a result, [this
check](12b377247b/runtime/ops/fs_events.rs (L149))
returns false.

With this PR, an additional check is introduced to verify if the file
exists. If the file does not exist, a custom "remove" event is emitted.
This change is necessary because, based on tests conducted on macOS and
Linux (Ubuntu 24.04.1 LTS), Linux emits a "rename" event instead of a
"remove" event when a file is deleted. Introducing a dedicated "remove"
event ensures consistent and clearer behavior across platforms.
This commit is contained in:
ctrl+d 2024-11-25 16:38:52 +01:00 committed by GitHub
parent d59bd5e8c9
commit 38b618ce35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 0 deletions

View file

@ -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,6 +158,13 @@ fn start_watcher(
})
}) {
let _ = sender.try_send(Ok(event.clone()));
} 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));
}
}
}

View file

@ -45,6 +45,14 @@ async function makeTempDir(): Promise<string> {
return testDir;
}
async function makeTempFile(): Promise<string> {
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,25 @@ Deno.test(
assert(done);
},
);
Deno.test(
{ permissions: { read: true, write: true } },
async function watchFsRemove() {
const testFile = await makeTempFile();
using watcher = Deno.watchFs(testFile);
async function waitForRemove() {
for await (const event of watcher) {
if (event.kind === "remove") {
return event;
}
}
}
const eventPromise = waitForRemove();
await Deno.remove(testFile);
// Expect zero events.
const event = await eventPromise;
assertEquals(event!.kind, "remove");
},
);