diff --git a/src/file.rs b/src/file.rs index 7e2085b..5adc38e 100644 --- a/src/file.rs +++ b/src/file.rs @@ -27,7 +27,7 @@ use traits::Process; pub struct FileProcess<'a> { cmd: &'a str, env: Option>, - file: &'a str, + files: Vec<&'a str>, method: WatchEventType, poll: Duration, } @@ -36,14 +36,14 @@ impl<'a> FileProcess<'a> { pub fn new( cmd: &'a str, env: Option>, - file: &'a str, + file: Vec<&'a str>, method: WatchEventType, poll: Duration, ) -> FileProcess<'a> { FileProcess { cmd: cmd, env: env, - file: file, + files: file, method: method, poll: poll, } @@ -104,14 +104,23 @@ fn spawn_runner_thread( fn wait_for_fs_events( lock: Arc>, method: WatchEventType, - file: &str, + files: &Vec<&str>, ) -> Result<(), CommandError> { // Notify requires a channel for communication. let (tx, rx) = channel(); let mut watcher = watcher(tx, Duration::from_secs(1))?; // TODO(jwall): Better error handling. - watcher.watch(file, RecursiveMode::Recursive)?; - println!("Watching {:?}", file); + for file in files { + // NOTE(jwall): this is necessary because notify::fsEventWatcher panics + // if the path doesn't exist. :-( + if !Path::new(*file).exists() { + return Err(CommandError::new( + format!("No such path! {0}", *file).to_string(), + )); + } + watcher.watch(*file, RecursiveMode::Recursive)?; + println!("Watching {:?}", *file); + } loop { let evt: WatchEventType = match rx.recv() { Ok(event) => WatchEventType::from(event), @@ -128,6 +137,8 @@ fn wait_for_fs_events( if method == WatchEventType::Touched { let mut signal = lock.lock().unwrap(); *signal = true; + } else { + println!("Ignoring touched event"); } } WatchEventType::Changed => match lock.lock() { @@ -143,13 +154,6 @@ fn wait_for_fs_events( impl<'a> Process for FileProcess<'a> { fn run(&self) -> Result<(), CommandError> { - // NOTE(jwall): this is necessary because notify::fsEventWatcher panics - // if the path doesn't exist. :-( - if !Path::new(self.file).exists() { - return Err(CommandError::new( - format!("No such path! {0}", self.file).to_string(), - )); - } // TODO(jeremy): Is this sufficent or do we want to ignore // any events that come in while the command is running? let lock = Arc::new(Mutex::new(false)); @@ -159,6 +163,6 @@ impl<'a> Process for FileProcess<'a> { self.env.clone(), self.poll, ); - wait_for_fs_events(lock, self.method.clone(), self.file) + wait_for_fs_events(lock, self.method.clone(), &self.files) } } diff --git a/src/main.rs b/src/main.rs index b6610c2..5218e81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,11 +40,11 @@ fn do_flags<'a>() -> clap::ArgMatches<'a> { (author: crate_authors!()) (about: "Runs a command on user defined triggers.") (@arg cmd: -c --cmd +required +takes_value "Command to run on supplied triggers") - (@arg env: -e --env +takes_value ... "Command to run on supplied triggers") + (@arg env: -e --env +takes_value ... "Env variables to set for the command") (@subcommand watch => (about: "Trigger that fires when a file or directory changes.") // TODO(jeremy): We need to support filters - (@arg file: -f --file +takes_value + (@arg file: -f --file +takes_value ... "File/Directory to watch. (default current working directory)") (@arg filetouch: --touch "Watches for attribute modifications as well as content changes.") @@ -85,8 +85,11 @@ fn main() { } let mut process: Option> = None; if let Some(matches) = app.subcommand_matches("watch") { - // Unwrap because this flag is required. - let file = matches.value_of("file").unwrap_or("."); + let file = match matches.values_of("file") { + Some(v) => v.collect(), + // The default is our current directory + None => vec!["."], + }; let mut method = WatchEventType::Changed; if matches.is_present("filetouch") { method = WatchEventType::Touched;