mirror of
https://github.com/denoland/deno.git
synced 2025-01-04 13:28:47 -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)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum FsEventsError {
|
pub enum FsEventsError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -150,6 +158,13 @@ fn start_watcher(
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
let _ = sender.try_send(Ok(event.clone()));
|
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;
|
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(
|
Deno.test(
|
||||||
{ permissions: { read: true, write: true } },
|
{ permissions: { read: true, write: true } },
|
||||||
async function watchFsBasic() {
|
async function watchFsBasic() {
|
||||||
|
@ -155,3 +163,25 @@ Deno.test(
|
||||||
assert(done);
|
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