mirror of
https://github.com/zaphar/runwhen.git
synced 2025-07-22 20:39:49 -04:00
Allow more than one --file arg
This commit is contained in:
parent
69f6334dc8
commit
ebb999af95
32
src/file.rs
32
src/file.rs
@ -27,7 +27,7 @@ use traits::Process;
|
||||
pub struct FileProcess<'a> {
|
||||
cmd: &'a str,
|
||||
env: Option<Vec<&'a str>>,
|
||||
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<Vec<&'a str>>,
|
||||
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<Mutex<bool>>,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
11
src/main.rs
11
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<Box<dyn Process>> = 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user