Translate notify::Event to fsevent::Event on linux (#7545)
This isn't exactly a great solution, but it's a step in the right direction, and it's simple allowing us to quickly unblock linux. Without this (or an equivalent) PR linux builds are broken. I spent a bunch of time investigating using notify on macos, and have a branch with that working and FakeFs updated to use notify events. unfortunately I think this would come with some drawbacks. Primarily that files that don't yet exist yet aren't handled as well as with using events directly leading to some less than ideal tradeoffs. This PR is very much a placeholder for a better cross platform solution. Most problematically, it only fills in the portion of fsevent::Event that is currently used, despite there being a lot more information in the ones collected from macos. At the very least a followup PR should hide those implementation details behind a cross platform Event type so that if people try and access data that hasn't been translated, they find out about it. Release Notes: - N/A
This commit is contained in:
parent
006e7a77d5
commit
17c203fef9
4 changed files with 416 additions and 406 deletions
|
@ -1,15 +1,15 @@
|
|||
pub mod repository;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use fsevent::Event;
|
||||
#[cfg(target_os = "macos")]
|
||||
use fsevent::EventStream;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub use notify::Event;
|
||||
use fsevent::StreamFlags;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
use notify::{Config, Watcher};
|
||||
use notify::{Config, EventKind, Watcher};
|
||||
|
||||
use futures::{future::BoxFuture, Stream, StreamExt};
|
||||
use git2::Repository as LibGitRepository;
|
||||
|
@ -292,15 +292,30 @@ impl Fs for RealFs {
|
|||
return Box::pin(rx);
|
||||
}
|
||||
|
||||
let mut watcher = notify::recommended_watcher(move |res| match res {
|
||||
Ok(event) => {
|
||||
let _ = tx.try_send(vec![event]);
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("watch error: {}", err);
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
let mut watcher =
|
||||
notify::recommended_watcher(move |res: Result<notify::Event, _>| match res {
|
||||
Ok(event) => {
|
||||
let flags = match event.kind {
|
||||
// ITEM_REMOVED is currently the only flag we care about
|
||||
EventKind::Remove(_) => StreamFlags::ITEM_REMOVED,
|
||||
_ => StreamFlags::NONE,
|
||||
};
|
||||
let events = event
|
||||
.paths
|
||||
.into_iter()
|
||||
.map(|path| Event {
|
||||
event_id: 0,
|
||||
flags,
|
||||
path,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let _ = tx.try_send(events);
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("watch error: {}", err);
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
watcher
|
||||
.configure(Config::default().with_poll_interval(latency))
|
||||
|
@ -330,20 +345,10 @@ impl Fs for RealFs {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn fs_events_paths(events: Vec<Event>) -> Vec<PathBuf> {
|
||||
events.into_iter().map(|event| event.path).collect()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub fn fs_events_paths(events: Vec<Event>) -> Vec<PathBuf> {
|
||||
events
|
||||
.into_iter()
|
||||
.map(|event| event.paths.into_iter())
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub struct FakeFs {
|
||||
// Use an unfair lock to ensure tests are deterministic.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue