mirror of
https://github.com/watchexec/watchexec.git
synced 2024-09-29 22:51:33 +02:00
Use ArgsBuilder ourselves
This commit is contained in:
parent
0c6b1bf2e4
commit
757de0d92e
97
src/cli.rs
97
src/cli.rs
@ -14,7 +14,8 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use clap::{App, Arg, Error};
|
use clap::{App, Arg};
|
||||||
|
use log::LevelFilter;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
path::{PathBuf, MAIN_SEPARATOR},
|
path::{PathBuf, MAIN_SEPARATOR},
|
||||||
@ -242,25 +243,30 @@ where
|
|||||||
Some(i) => app.get_matches_from(i),
|
Some(i) => app.get_matches_from(i),
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmd: Vec<String> = values_t!(args.values_of("command"), String)?;
|
let mut builder = ArgsBuilder::default();
|
||||||
let paths = values_t!(args.values_of("path"), String)
|
|
||||||
|
let cmd: Vec<String> = values_t!(args.values_of("command"), String).map_err(|err| err.to_string())?;
|
||||||
|
builder.cmd(cmd);
|
||||||
|
|
||||||
|
let paths: Vec<PathBuf> = values_t!(args.values_of("path"), String)
|
||||||
.unwrap_or_else(|_| vec![".".into()])
|
.unwrap_or_else(|_| vec![".".into()])
|
||||||
.iter()
|
.iter()
|
||||||
.map(|string_path| string_path.into())
|
.map(|string_path| string_path.into())
|
||||||
.collect();
|
.collect();
|
||||||
|
builder.paths(paths);
|
||||||
|
|
||||||
// Treat --kill as --signal SIGKILL (for compatibility with older syntax)
|
// Treat --kill as --signal SIGKILL (for compatibility with deprecated syntax)
|
||||||
let signal = if args.is_present("kill") {
|
if args.is_present("kill") {
|
||||||
Some("SIGKILL".to_string())
|
builder.signal("SIGKILL");
|
||||||
} else {
|
}
|
||||||
// Convert Option<&str> to Option<String>
|
|
||||||
args.value_of("signal").map(str::to_string)
|
if let Some(signal) = args.value_of("signal") {
|
||||||
};
|
builder.signal(signal);
|
||||||
|
}
|
||||||
|
|
||||||
let mut filters = values_t!(args.values_of("filter"), String).unwrap_or_else(|_| Vec::new());
|
let mut filters = values_t!(args.values_of("filter"), String).unwrap_or_else(|_| Vec::new());
|
||||||
|
|
||||||
if let Some(extensions) = args.values_of("extensions") {
|
if let Some(extensions) = args.values_of("extensions") {
|
||||||
for exts in extensions {
|
for exts in extensions { // TODO: refactor with flatten()
|
||||||
filters.extend(exts.split(',').filter_map(|ext| {
|
filters.extend(exts.split(',').filter_map(|ext| {
|
||||||
if ext.is_empty() {
|
if ext.is_empty() {
|
||||||
None
|
None
|
||||||
@ -271,6 +277,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.filters(filters);
|
||||||
|
|
||||||
let mut ignores = vec![];
|
let mut ignores = vec![];
|
||||||
let default_ignores = vec![
|
let default_ignores = vec![
|
||||||
format!("**{}.DS_Store", MAIN_SEPARATOR),
|
format!("**{}.DS_Store", MAIN_SEPARATOR),
|
||||||
@ -290,50 +298,33 @@ where
|
|||||||
};
|
};
|
||||||
ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or_else(|_| Vec::new()));
|
ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or_else(|_| Vec::new()));
|
||||||
|
|
||||||
let poll_interval = if args.occurrences_of("poll") > 0 {
|
builder.ignores(ignores);
|
||||||
value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit())
|
|
||||||
} else {
|
|
||||||
1000
|
|
||||||
};
|
|
||||||
|
|
||||||
let debounce = if args.occurrences_of("debounce") > 0 {
|
if args.occurrences_of("poll") > 0 {
|
||||||
value_t!(args.value_of("debounce"), u64).unwrap_or_else(|e| e.exit())
|
builder.poll_interval(value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit()));
|
||||||
} else {
|
|
||||||
500
|
|
||||||
};
|
|
||||||
|
|
||||||
if signal.is_some() && args.is_present("postpone") {
|
|
||||||
// TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
|
|
||||||
Error::value_validation_auto("--postpone and --signal are mutually exclusive".to_string())
|
|
||||||
.exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if signal.is_some() && args.is_present("kill") {
|
if args.occurrences_of("debounce") > 0 {
|
||||||
// TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
|
builder.debounce(value_t!(args.value_of("debounce"), u64).unwrap_or_else(|e| e.exit()));
|
||||||
Error::value_validation_auto("--kill and --signal is ambiguous.\n Hint: Use only '--signal SIGKILL' without --kill".to_string())
|
|
||||||
.exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Args {
|
// TODO: check how postpone + signal behaves
|
||||||
cmd,
|
|
||||||
paths,
|
builder.clear_screen(args.is_present("clear"));
|
||||||
filters,
|
builder.restart(args.is_present("restart"));
|
||||||
ignores,
|
builder.run_initially(!args.is_present("postpone"));
|
||||||
signal,
|
builder.no_shell(args.is_present("no-shell"));
|
||||||
clear_screen: args.is_present("clear"),
|
builder.no_meta(args.is_present("no-meta"));
|
||||||
restart: args.is_present("restart"),
|
builder.no_environment(args.is_present("no-environment"));
|
||||||
debounce,
|
builder.no_vcs_ignore(args.is_present("no-vcs-ignore"));
|
||||||
debug: args.is_present("verbose"),
|
builder.no_ignore(args.is_present("no-ignore"));
|
||||||
changes: args.is_present("changes"),
|
builder.poll(args.occurrences_of("poll") > 0);
|
||||||
run_initially: !args.is_present("postpone"),
|
builder.watch_when_idle(args.is_present("watch-when-idle"));
|
||||||
no_shell: args.is_present("no-shell"),
|
|
||||||
no_meta: args.is_present("no-meta"),
|
let mut config = builder.build()?;
|
||||||
no_environment: args.is_present("no-environment"),
|
if args.is_present("once") {
|
||||||
no_vcs_ignore: args.is_present("no-vcs-ignore"),
|
config.once = true;
|
||||||
no_ignore: args.is_present("no-ignore"),
|
}
|
||||||
once: args.is_present("once"),
|
|
||||||
poll: args.occurrences_of("poll") > 0,
|
Ok(config)
|
||||||
poll_interval,
|
|
||||||
watch_when_idle: args.is_present("watch-when-idle"),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
18
src/error.rs
18
src/error.rs
@ -4,24 +4,18 @@ pub type Result<T> = ::std::result::Result<T, Error>;
|
|||||||
|
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Canonicalization(String, io::Error),
|
Canonicalization(String, io::Error),
|
||||||
Clap(clap::Error),
|
|
||||||
Glob(globset::Error),
|
Glob(globset::Error),
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
Notify(notify::Error),
|
Notify(notify::Error),
|
||||||
|
Generic(String),
|
||||||
PoisonedLock,
|
PoisonedLock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdError for Error {
|
impl StdError for Error {}
|
||||||
fn description(&self) -> &str {
|
|
||||||
// This method is soft-deprecated and shouldn't be used,
|
|
||||||
// see Display for the actual description.
|
|
||||||
"a watchexec error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<clap::Error> for Error {
|
impl From<String> for Error {
|
||||||
fn from(err: clap::Error) -> Self {
|
fn from(err: String) -> Self {
|
||||||
Self::Clap(err)
|
Self::Generic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +62,7 @@ impl fmt::Display for Error {
|
|||||||
"Path",
|
"Path",
|
||||||
format!("couldn't canonicalize '{}':\n{}", path, err),
|
format!("couldn't canonicalize '{}':\n{}", path, err),
|
||||||
),
|
),
|
||||||
Self::Clap(err) => ("Argument", err.to_string()),
|
Self::Generic(err) => ("", err.clone()),
|
||||||
Self::Glob(err) => ("Globset", err.to_string()),
|
Self::Glob(err) => ("Globset", err.to_string()),
|
||||||
Self::Io(err) => ("I/O", err.to_string()),
|
Self::Io(err) => ("I/O", err.to_string()),
|
||||||
Self::Notify(err) => ("Notify", err.to_string()),
|
Self::Notify(err) => ("Notify", err.to_string()),
|
||||||
|
Loading…
Reference in New Issue
Block a user