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:
parent
d59bd5e8c9
commit
38b618ce35
2 changed files with 45 additions and 0 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
},
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue