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> {
|
pub struct FileProcess<'a> {
|
||||||
cmd: &'a str,
|
cmd: &'a str,
|
||||||
env: Option<Vec<&'a str>>,
|
env: Option<Vec<&'a str>>,
|
||||||
file: &'a str,
|
files: Vec<&'a str>,
|
||||||
method: WatchEventType,
|
method: WatchEventType,
|
||||||
poll: Duration,
|
poll: Duration,
|
||||||
}
|
}
|
||||||
@ -36,14 +36,14 @@ impl<'a> FileProcess<'a> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
cmd: &'a str,
|
cmd: &'a str,
|
||||||
env: Option<Vec<&'a str>>,
|
env: Option<Vec<&'a str>>,
|
||||||
file: &'a str,
|
file: Vec<&'a str>,
|
||||||
method: WatchEventType,
|
method: WatchEventType,
|
||||||
poll: Duration,
|
poll: Duration,
|
||||||
) -> FileProcess<'a> {
|
) -> FileProcess<'a> {
|
||||||
FileProcess {
|
FileProcess {
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
env: env,
|
env: env,
|
||||||
file: file,
|
files: file,
|
||||||
method: method,
|
method: method,
|
||||||
poll: poll,
|
poll: poll,
|
||||||
}
|
}
|
||||||
@ -104,14 +104,23 @@ fn spawn_runner_thread(
|
|||||||
fn wait_for_fs_events(
|
fn wait_for_fs_events(
|
||||||
lock: Arc<Mutex<bool>>,
|
lock: Arc<Mutex<bool>>,
|
||||||
method: WatchEventType,
|
method: WatchEventType,
|
||||||
file: &str,
|
files: &Vec<&str>,
|
||||||
) -> Result<(), CommandError> {
|
) -> Result<(), CommandError> {
|
||||||
// Notify requires a channel for communication.
|
// Notify requires a channel for communication.
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut watcher = watcher(tx, Duration::from_secs(1))?;
|
let mut watcher = watcher(tx, Duration::from_secs(1))?;
|
||||||
// TODO(jwall): Better error handling.
|
// TODO(jwall): Better error handling.
|
||||||
watcher.watch(file, RecursiveMode::Recursive)?;
|
for file in files {
|
||||||
println!("Watching {:?}", file);
|
// 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 {
|
loop {
|
||||||
let evt: WatchEventType = match rx.recv() {
|
let evt: WatchEventType = match rx.recv() {
|
||||||
Ok(event) => WatchEventType::from(event),
|
Ok(event) => WatchEventType::from(event),
|
||||||
@ -128,6 +137,8 @@ fn wait_for_fs_events(
|
|||||||
if method == WatchEventType::Touched {
|
if method == WatchEventType::Touched {
|
||||||
let mut signal = lock.lock().unwrap();
|
let mut signal = lock.lock().unwrap();
|
||||||
*signal = true;
|
*signal = true;
|
||||||
|
} else {
|
||||||
|
println!("Ignoring touched event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WatchEventType::Changed => match lock.lock() {
|
WatchEventType::Changed => match lock.lock() {
|
||||||
@ -143,13 +154,6 @@ fn wait_for_fs_events(
|
|||||||
|
|
||||||
impl<'a> Process for FileProcess<'a> {
|
impl<'a> Process for FileProcess<'a> {
|
||||||
fn run(&self) -> Result<(), CommandError> {
|
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
|
// TODO(jeremy): Is this sufficent or do we want to ignore
|
||||||
// any events that come in while the command is running?
|
// any events that come in while the command is running?
|
||||||
let lock = Arc::new(Mutex::new(false));
|
let lock = Arc::new(Mutex::new(false));
|
||||||
@ -159,6 +163,6 @@ impl<'a> Process for FileProcess<'a> {
|
|||||||
self.env.clone(),
|
self.env.clone(),
|
||||||
self.poll,
|
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!())
|
(author: crate_authors!())
|
||||||
(about: "Runs a command on user defined triggers.")
|
(about: "Runs a command on user defined triggers.")
|
||||||
(@arg cmd: -c --cmd +required +takes_value "Command to run on supplied 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 =>
|
(@subcommand watch =>
|
||||||
(about: "Trigger that fires when a file or directory changes.")
|
(about: "Trigger that fires when a file or directory changes.")
|
||||||
// TODO(jeremy): We need to support filters
|
// 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)")
|
"File/Directory to watch. (default current working directory)")
|
||||||
(@arg filetouch: --touch
|
(@arg filetouch: --touch
|
||||||
"Watches for attribute modifications as well as content changes.")
|
"Watches for attribute modifications as well as content changes.")
|
||||||
@ -85,8 +85,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
let mut process: Option<Box<dyn Process>> = None;
|
let mut process: Option<Box<dyn Process>> = None;
|
||||||
if let Some(matches) = app.subcommand_matches("watch") {
|
if let Some(matches) = app.subcommand_matches("watch") {
|
||||||
// Unwrap because this flag is required.
|
let file = match matches.values_of("file") {
|
||||||
let file = matches.value_of("file").unwrap_or(".");
|
Some(v) => v.collect(),
|
||||||
|
// The default is our current directory
|
||||||
|
None => vec!["."],
|
||||||
|
};
|
||||||
let mut method = WatchEventType::Changed;
|
let mut method = WatchEventType::Changed;
|
||||||
if matches.is_present("filetouch") {
|
if matches.is_present("filetouch") {
|
||||||
method = WatchEventType::Touched;
|
method = WatchEventType::Touched;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user