Implement --no-meta for default filterer

This commit is contained in:
Félix Saparelli 2021-12-29 19:29:45 +13:00
parent e2f6fe147a
commit a00912f17f
No known key found for this signature in database
GPG Key ID: B948C4BAE44FC474
2 changed files with 42 additions and 10 deletions

View File

@ -94,11 +94,11 @@ pub fn get_args(tagged_filterer: bool) -> Result<ArgMatches<'static>> {
.help("Print events that trigger actions")
.long("print-events")
.alias("changes-only")) // --changes-only is deprecated (remove at v2)
.arg(Arg::with_name("no-vcs-ignore") // TODO
.arg(Arg::with_name("no-vcs-ignore")
.help_heading(Some(OPTSET_FILTERING))
.help("Skip auto-loading of VCS (Git, etc) ignore files")
.long("no-vcs-ignore"))
.arg(Arg::with_name("no-project-ignore") // TODO
.arg(Arg::with_name("no-project-ignore")
.help_heading(Some(OPTSET_FILTERING))
.help("Skip auto-loading of project ignore files (.gitignore, .ignore, etc)")
.long("no-ignore"))
@ -106,7 +106,7 @@ pub fn get_args(tagged_filterer: bool) -> Result<ArgMatches<'static>> {
.help_heading(Some(OPTSET_FILTERING))
.help("Skip auto-ignoring of commonly ignored globs")
.long("no-default-ignore"))
.arg(Arg::with_name("no-global-ignore") // TODO
.arg(Arg::with_name("no-global-ignore")
.help_heading(Some(OPTSET_FILTERING))
.help("Skip auto-loading of global or environment-wide ignore files")
.long("no-global-ignore"))
@ -186,7 +186,7 @@ pub fn get_args(tagged_filterer: bool) -> Result<ArgMatches<'static>> {
.long("no-default-filters"),
)
.arg(
Arg::with_name("no-meta") // TODO
Arg::with_name("no-meta")
.help_heading(Some(OPTSET_FILTERING))
.help("Ignore metadata changes (equivalent of `-f 'kind*!Modify(Metadata(*))'`)")
.long("no-meta"),
@ -223,7 +223,7 @@ pub fn get_args(tagged_filterer: bool) -> Result<ArgMatches<'static>> {
.value_name("pattern"),
)
.arg(
Arg::with_name("no-meta") // TODO
Arg::with_name("no-meta")
.help_heading(Some(OPTSET_FILTERING))
.help("Ignore metadata changes")
.long("no-meta"),

View File

@ -5,9 +5,16 @@ use std::{
use clap::ArgMatches;
use miette::{IntoDiagnostic, Result};
use watchexec::filter::globset::GlobsetFilterer;
use watchexec::{
error::RuntimeError,
event::{
filekind::{FileEventKind, ModifyKind},
Event, Tag,
},
filter::{globset::GlobsetFilterer, Filterer},
};
pub async fn globset(args: &ArgMatches<'static>) -> Result<Arc<GlobsetFilterer>> {
pub async fn globset(args: &ArgMatches<'static>) -> Result<Arc<WatchexecFilterer>> {
let (project_origin, workdir) = super::common::dirs(args).await?;
let ignorefiles = super::common::ignores(args, &project_origin).await?;
@ -33,9 +40,34 @@ pub async fn globset(args: &ArgMatches<'static>) -> Result<Arc<GlobsetFilterer>>
.map(|s| s.split(b','))
.flatten();
Ok(Arc::new(
GlobsetFilterer::new(project_origin, filters, ignores, exts).into_diagnostic()?,
))
Ok(Arc::new(WatchexecFilterer {
inner: GlobsetFilterer::new(project_origin, filters, ignores, exts).into_diagnostic()?,
no_meta: args.is_present("no-meta"),
}))
}
/// A custom filterer that combines the library's Globset filterer and a switch for --no-meta
#[derive(Debug)]
pub struct WatchexecFilterer {
inner: GlobsetFilterer,
no_meta: bool,
}
impl Filterer for WatchexecFilterer {
fn check_event(&self, event: &Event) -> Result<bool, RuntimeError> {
let is_meta = event.tags.iter().any(|tag| {
matches!(
tag,
Tag::FileEventKind(FileEventKind::Modify(ModifyKind::Metadata(_)))
)
});
if self.no_meta && is_meta {
Ok(false)
} else {
self.inner.check_event(event)
}
}
}
trait OsStringSplit {