diff --git a/Cargo.lock b/Cargo.lock index 57823cd..45eeefd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2552,6 +2552,7 @@ dependencies = [ "console-subscriber", "dunce", "embed-resource", + "futures", "insta", "miette", "mimalloc", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d46c247..b47e054 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,6 +27,7 @@ miette = { version = "3.2.0", features = ["fancy"] } notify-rust = "4.5.2" tracing = "0.1.26" watchexec = { path = "../lib" } +futures = "0.3.17" [dependencies.clap] version = "2.33.3" diff --git a/cli/src/args.rs b/cli/src/args.rs index 816f223..152cf4e 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -106,6 +106,10 @@ 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 + .help_heading(Some(OPTSET_FILTERING)) + .help("Skip auto-loading of global or environment-wide ignore files") + .long("no-default-ignore")) .arg(Arg::with_name("postpone") .help_heading(Some(OPTSET_BEHAVIOUR)) .help("Wait until first change to execute command") @@ -165,7 +169,7 @@ pub fn get_args(tagged_filterer: bool) -> Result> { .value_name("tagged filter"), ) .arg( - Arg::with_name("filter-files") // TODO + Arg::with_name("filter-files") .help_heading(Some(OPTSET_FILTERING)) .help("Load tagged filters from a file") .short("F") @@ -175,6 +179,12 @@ pub fn get_args(tagged_filterer: bool) -> Result> { .takes_value(true) .value_name("path"), ) + .arg( + Arg::with_name("no-global-filters") + .help_heading(Some(OPTSET_FILTERING)) + .help("Skip auto-loading of global or environment-wide ignore files") + .long("no-default-filters"), + ) .arg( Arg::with_name("no-meta") // TODO .help_heading(Some(OPTSET_FILTERING)) diff --git a/cli/src/filterer/tagged.rs b/cli/src/filterer/tagged.rs index 397d44e..18d0327 100644 --- a/cli/src/filterer/tagged.rs +++ b/cli/src/filterer/tagged.rs @@ -1,9 +1,16 @@ -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use clap::ArgMatches; +use futures::future::try_join_all; use miette::Result; use tracing::debug; -use watchexec::filter::tagged::{Filter, TaggedFilterer}; +use watchexec::{ + filter::tagged::{ + files::{self, FilterFile}, + Filter, TaggedFilterer, + }, + ignore_files::IgnoreFile, +}; pub async fn tagged(args: &ArgMatches<'static>) -> Result> { let (project_origin, workdir) = super::common::dirs(args).await?; @@ -27,8 +34,32 @@ pub async fn tagged(args: &ArgMatches<'static>) -> Result> { filterer.add_ignore_file(ignore).await?; } - // TODO: load global/env filter files - // TODO: load -F filter files + let mut filter_files = Vec::new(); + for path in args.values_of_os("filter-file").unwrap_or_default() { + let file = FilterFile(IgnoreFile { + applies_in: None, + applies_to: None, + path: PathBuf::from(path), + }); + filter_files.push(file); + } + + if !args.is_present("no-global-filters") { + // TODO: handle errors + let (global_filter_files, _errors) = files::from_environment().await; + filter_files.extend(global_filter_files); + } + + let filters = try_join_all( + filter_files + .into_iter() + .map(|file| async move { file.load().await }), + ) + .await? + .into_iter() + .flatten() + .collect::>(); + filterer.add_filters(&filters).await?; Ok(filterer) }