Normalise paths to unix on windows for filtering only (#558)

This commit is contained in:
Félix Saparelli 2023-03-22 23:55:19 +13:00 committed by GitHub
parent 38109b8128
commit 8a2808027f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 95 additions and 1 deletions

View File

@ -129,6 +129,100 @@ impl Filterer for WatchexecFilterer {
}
}
self.inner.check_event(event, priority)
#[cfg(windows)]
{
let normalised = windows_norm::normalise_event_to_unix(event, false);
trace!(event=?normalised, "check against unix-normalised event");
if !self.inner.check_event(&normalised, priority)? {
return Ok(false);
}
let prefixed_normalised = windows_norm::normalise_event_to_unix(event, true);
trace!(event=?prefixed_normalised, "check against prefixed unix-normalised event");
if !self.inner.check_event(&prefixed_normalised, priority)? {
return Ok(false);
}
}
trace!("check against original event");
if !self.inner.check_event(event, priority)? {
return Ok(false);
}
Ok(true)
}
}
#[cfg(windows)]
mod windows_norm {
use std::{
ffi::OsString,
path::{Component, Path, PathBuf},
};
use watchexec_events::{Event, Tag};
pub fn normalise_event_to_unix(event: &Event, with_prefix: bool) -> Event {
let mut path_normalised_event = event.clone();
for mut tag in &mut path_normalised_event.tags {
if let Tag::Path { ref mut path, .. } = &mut tag {
*path = normalise_path_to_unix(path, with_prefix);
}
}
path_normalised_event
}
pub fn normalise_path_to_unix(path: &Path, with_prefix: bool) -> PathBuf {
let mut newpath = OsString::with_capacity(path.as_os_str().len());
let mut skip_root = false;
for component in path.components() {
if matches!(component, Component::Prefix(_)) {
if with_prefix {
newpath.push(component.as_os_str());
skip_root = true;
}
} else if matches!(component, Component::RootDir) && skip_root {
// skip
} else {
newpath.push("/");
newpath.push(component.as_os_str());
}
}
PathBuf::from(newpath)
}
#[cfg(test)]
#[test]
fn test_normalise_path_to_unix() {
assert_eq!(
normalise_path_to_unix(Path::new("C:\\Users\\foo\\bar"), false),
PathBuf::from("/Users/foo/bar")
);
assert_eq!(
normalise_path_to_unix(Path::new("C:\\Users\\foo\\bar"), true),
PathBuf::from("C:/Users/foo/bar")
);
assert_eq!(
normalise_path_to_unix(Path::new("E:\\_temp\\folder_to_watch\\private"), false),
PathBuf::from("/_temp/folder_to_watch/private")
);
assert_eq!(
normalise_path_to_unix(Path::new("E:\\_temp\\folder_to_watch\\private"), true),
PathBuf::from("E:/_temp/folder_to_watch/private")
);
assert_eq!(
normalise_path_to_unix(
Path::new("\\\\?\\E:\\_temp\\folder_to_watch\\public\\.hgignore"),
false
),
PathBuf::from("/_temp/folder_to_watch/public/.hgignore")
);
assert_eq!(
normalise_path_to_unix(
Path::new("\\\\?\\E:\\_temp\\folder_to_watch\\public\\.hgignore"),
true
),
PathBuf::from("\\\\?\\E:/_temp/folder_to_watch/public/.hgignore")
);
}
}