diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 1a270d7..e258343 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -13,7 +13,10 @@ use clap::{ ValueHint, }; use miette::{IntoDiagnostic, Result}; -use tokio::{fs::File, io::AsyncReadExt}; +use tokio::{ + fs::File, + io::{AsyncBufReadExt, AsyncReadExt, BufReader}, +}; use tracing::{debug, info, trace, warn}; use tracing_appender::non_blocking::WorkerGuard; use watchexec::{paths::PATH_SEPARATOR, sources::fs::WatchedPath}; @@ -151,6 +154,23 @@ pub struct Args { )] pub non_recursive_paths: Vec, + /// Watch files and directories from a file + /// + /// Each line in the file will be interpreted as if given to '-w'. + /// + /// For more complex uses (like watching non-recursively), use the argfile capability: build a + /// file containing command-line options and pass it to watchexec with `@path/to/argfile`. + /// + /// The special value '-' will read from STDIN; this in incompatible with '--stdin-quit'. + #[arg( + short = 'F', + long, + help_heading = OPTSET_FILTERING, + value_hint = ValueHint::AnyPath, + value_name = "PATH", + )] + pub watch_file: Option, + #[doc(hidden)] #[arg(skip)] pub paths: Vec, @@ -1216,6 +1236,15 @@ pub async fn get_args() -> Result<(Args, Option)> { .exit(); } + if args.stdin_quit && args.watch_file == Some(PathBuf::from("-")) { + Args::command() + .error( + ErrorKind::InvalidValue, + "stdin-quit cannot be used when --watch-file=-", + ) + .exit(); + } + let workdir = if let Some(w) = take(&mut args.workdir) { w } else { @@ -1233,6 +1262,14 @@ pub async fn get_args() -> Result<(Args, Option)> { info!(path=?project_origin, "effective project origin"); args.project_origin = Some(project_origin.clone()); + if let Some(watch_file) = args.watch_file.as_ref() { + let file = BufReader::new(File::open(watch_file).await.into_diagnostic()?); + let mut lines = file.lines(); + while let Ok(Some(line)) = lines.next_line().await { + args.recursive_paths.push(line.into()); + } + } + args.paths = take(&mut args.recursive_paths) .into_iter() .map(|path| { diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 125137a..95ca1fe 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -74,8 +74,8 @@ mod watchexec; #[doc(inline)] pub use crate::{ id::Id, - watchexec::{ErrorHook, Watchexec}, watched_path::WatchedPath, + watchexec::{ErrorHook, Watchexec}, }; #[doc(no_inline)]