diff --git a/lib/src/filter/globset.rs b/lib/src/filter/globset.rs index 380e631e..499910dd 100644 --- a/lib/src/filter/globset.rs +++ b/lib/src/filter/globset.rs @@ -109,44 +109,50 @@ impl Filterer for GlobsetFilterer { return Ok(false); } } + + let mut paths = event.paths().peekable(); + if paths.peek().is_none() { + trace!("non-path event (pass)"); + Ok(true) + } else { + Ok(paths.any(|(path, file_type)| { + let _span = trace_span!("path", ?path).entered(); + let is_dir = file_type + .map(|t| matches!(t, FileType::Dir)) + .unwrap_or(false); - Ok(event.paths().any(|(path, file_type)| { - let _span = trace_span!("path", ?path).entered(); - let is_dir = file_type - .map(|t| matches!(t, FileType::Dir)) - .unwrap_or(false); - - if self.ignores.matched(path, is_dir).is_ignore() { - trace!("ignored by globset ignore"); - return false; - } - - if self.filters.num_ignores() > 0 && !self.filters.matched(path, is_dir).is_ignore() { - trace!("ignored by globset filters"); - return false; - } - - if !self.extensions.is_empty() { - if is_dir { - trace!("failed on extension check due to being a dir"); + if self.ignores.matched(path, is_dir).is_ignore() { + trace!("ignored by globset ignore"); return false; } - if let Some(ext) = path.extension() { - if !self.extensions.iter().any(|e| e == ext) { - trace!("ignored by extension filter"); + if self.filters.num_ignores() > 0 && !self.filters.matched(path, is_dir).is_ignore() { + trace!("ignored by globset filters"); + return false; + } + + if !self.extensions.is_empty() { + if is_dir { + trace!("failed on extension check due to being a dir"); return false; } - } else { - trace!( - ?path, - "failed on extension check due to having no extension" - ); - return false; - } - } - true - })) + if let Some(ext) = path.extension() { + if !self.extensions.iter().any(|e| e == ext) { + trace!("ignored by extension filter"); + return false; + } + } else { + trace!( + ?path, + "failed on extension check due to having no extension" + ); + return false; + } + } + + true + })) + } } } diff --git a/lib/tests/filter_globset.rs b/lib/tests/filter_globset.rs index a19f3a7b..33c935bb 100644 --- a/lib/tests/filter_globset.rs +++ b/lib/tests/filter_globset.rs @@ -347,6 +347,26 @@ async fn multipath_allow_on_any_one_pass() { assert!(filterer.check_event(&event).unwrap()); } +#[tokio::test] +async fn nonpath_event_passes() { + use watchexec::{ + event::{Event, Tag, Source}, + filter::Filterer, + }; + + let filterer = filt(&[], &[], &["py"]).await; + + assert!(filterer.check_event(&Event { + tags: vec![Tag::Source(Source::Internal)], + metadata: Default::default(), + }).unwrap()); + + assert!(filterer.check_event(&Event { + tags: vec![Tag::Source(Source::Keyboard)], + metadata: Default::default(), + }).unwrap()); +} + // The following tests replicate the "buggy"/"confusing" watchexec v1 behaviour. #[tokio::test]