From a00912f17f829fb82d33b2d813289e4632a3d66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Wed, 29 Dec 2021 19:29:45 +1300 Subject: [PATCH] Implement --no-meta for default filterer --- cli/src/args.rs | 10 ++++----- cli/src/filterer/globset.rs | 42 ++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/cli/src/args.rs b/cli/src/args.rs index bf39af4..744757f 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -94,11 +94,11 @@ pub fn get_args(tagged_filterer: bool) -> Result> { .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> { .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> { .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> { .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"), diff --git a/cli/src/filterer/globset.rs b/cli/src/filterer/globset.rs index 666dd71..38ca25c 100644 --- a/cli/src/filterer/globset.rs +++ b/cli/src/filterer/globset.rs @@ -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> { +pub async fn globset(args: &ArgMatches<'static>) -> Result> { 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> .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 { + 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 {