mirror of https://github.com/passcod/cargo-watch
Reformat
This commit is contained in:
parent
089122821d
commit
093b443dbc
|
@ -1,12 +1,21 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.yml]
|
||||
[tests/snapshots/*]
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{md,ronn}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{cff,yml}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
hard_tabs = true
|
54
src/args.rs
54
src/args.rs
|
@ -2,11 +2,11 @@ use clap::{App, AppSettings, Arg, ArgMatches, ErrorKind, SubCommand};
|
|||
use std::{env, process};
|
||||
|
||||
pub fn parse() -> ArgMatches<'static> {
|
||||
let footnote = "You can use the `-- command` style instead, note you'll need to use full commands, it won't prefix `cargo` for you.\n\nBy default, your entire project is watched, except for the target/ and .git/ folders, and your .ignore and .gitignore files are used to filter paths.".to_owned();
|
||||
let footnote = "You can use the `-- command` style instead, note you'll need to use full commands, it won't prefix `cargo` for you.\n\nBy default, your entire project is watched, except for the target/ and .git/ folders, and your .ignore and .gitignore files are used to filter paths.".to_owned();
|
||||
|
||||
#[cfg(windows)] let footnote = format!("{}\n\nOn Windows, patterns given to -i have forward slashes (/) automatically converted to backward ones (\\) to ease command portability.", footnote);
|
||||
#[cfg(windows)] let footnote = format!("{}\n\nOn Windows, patterns given to -i have forward slashes (/) automatically converted to backward ones (\\) to ease command portability.", footnote);
|
||||
|
||||
let mut app = App::new(env!("CARGO_PKG_NAME"))
|
||||
let mut app = App::new(env!("CARGO_PKG_NAME"))
|
||||
.bin_name("cargo")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.help_message("")
|
||||
|
@ -207,32 +207,32 @@ pub fn parse() -> ArgMatches<'static> {
|
|||
.after_help(footnote.as_str()),
|
||||
);
|
||||
|
||||
// Allow invocation of cargo-watch with both `cargo-watch watch ARGS`
|
||||
// (as invoked by cargo) and `cargo-watch ARGS`.
|
||||
let mut args: Vec<String> = env::args().collect();
|
||||
args.insert(1, "watch".into());
|
||||
// Allow invocation of cargo-watch with both `cargo-watch watch ARGS`
|
||||
// (as invoked by cargo) and `cargo-watch ARGS`.
|
||||
let mut args: Vec<String> = env::args().collect();
|
||||
args.insert(1, "watch".into());
|
||||
|
||||
let matches = match app.get_matches_from_safe_borrow(args) {
|
||||
Ok(matches) => matches,
|
||||
Err(err) => {
|
||||
match err.kind {
|
||||
ErrorKind::HelpDisplayed => {
|
||||
println!("{}", err);
|
||||
process::exit(0);
|
||||
}
|
||||
let matches = match app.get_matches_from_safe_borrow(args) {
|
||||
Ok(matches) => matches,
|
||||
Err(err) => {
|
||||
match err.kind {
|
||||
ErrorKind::HelpDisplayed => {
|
||||
println!("{}", err);
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
ErrorKind::VersionDisplayed => {
|
||||
// Unlike HelpDisplayed, VersionDisplayed emits the output
|
||||
// by itself (clap-rs/clap#1390). It also does so without a
|
||||
// trailing newline, so we print one ourselves.
|
||||
println!();
|
||||
process::exit(0);
|
||||
}
|
||||
ErrorKind::VersionDisplayed => {
|
||||
// Unlike HelpDisplayed, VersionDisplayed emits the output
|
||||
// by itself (clap-rs/clap#1390). It also does so without a
|
||||
// trailing newline, so we print one ourselves.
|
||||
println!();
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
_ => app.get_matches(),
|
||||
}
|
||||
}
|
||||
};
|
||||
_ => app.get_matches(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
matches.subcommand.unwrap().matches
|
||||
matches.subcommand.unwrap().matches
|
||||
}
|
||||
|
|
68
src/main.rs
68
src/main.rs
|
@ -8,43 +8,43 @@ mod root;
|
|||
mod watch;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let matches = args::parse();
|
||||
let matches = args::parse();
|
||||
|
||||
let debug = matches.is_present("log:debug");
|
||||
let info = matches.is_present("log:info");
|
||||
let quiet = matches.is_present("log:quiet");
|
||||
let testing = matches.is_present("once");
|
||||
let debug = matches.is_present("log:debug");
|
||||
let info = matches.is_present("log:info");
|
||||
let quiet = matches.is_present("log:quiet");
|
||||
let testing = matches.is_present("once");
|
||||
|
||||
stderrlog::new()
|
||||
.quiet(quiet)
|
||||
.show_module_names(debug)
|
||||
.verbosity(if debug {
|
||||
3
|
||||
} else if info {
|
||||
2
|
||||
} else {
|
||||
1
|
||||
})
|
||||
.timestamp(if testing {
|
||||
Timestamp::Off
|
||||
} else {
|
||||
Timestamp::Millisecond
|
||||
})
|
||||
.init()
|
||||
.unwrap();
|
||||
stderrlog::new()
|
||||
.quiet(quiet)
|
||||
.show_module_names(debug)
|
||||
.verbosity(if debug {
|
||||
3
|
||||
} else if info {
|
||||
2
|
||||
} else {
|
||||
1
|
||||
})
|
||||
.timestamp(if testing {
|
||||
Timestamp::Off
|
||||
} else {
|
||||
Timestamp::Millisecond
|
||||
})
|
||||
.init()
|
||||
.unwrap();
|
||||
|
||||
root::change_dir(
|
||||
matches
|
||||
.value_of("workdir")
|
||||
.map(Utf8PathBuf::from)
|
||||
.unwrap_or_else(root::project_root),
|
||||
);
|
||||
root::change_dir(
|
||||
matches
|
||||
.value_of("workdir")
|
||||
.map(Utf8PathBuf::from)
|
||||
.unwrap_or_else(root::project_root),
|
||||
);
|
||||
|
||||
if let Some(b) = matches.value_of("rust-backtrace") {
|
||||
std::env::set_var("RUST_BACKTRACE", b);
|
||||
}
|
||||
if let Some(b) = matches.value_of("rust-backtrace") {
|
||||
std::env::set_var("RUST_BACKTRACE", b);
|
||||
}
|
||||
|
||||
let opts = options::get_options(&matches);
|
||||
let handler = watch::CwHandler::new(opts, quiet, matches.is_present("notif"))?;
|
||||
watch(&handler)
|
||||
let opts = options::get_options(&matches);
|
||||
let handler = watch::CwHandler::new(opts, quiet, matches.is_present("notif"))?;
|
||||
watch(&handler)
|
||||
}
|
||||
|
|
392
src/options.rs
392
src/options.rs
|
@ -3,260 +3,260 @@ use std::{env, path::MAIN_SEPARATOR, time::Duration};
|
|||
use clap::{value_t, values_t, ArgMatches};
|
||||
use log::{debug, warn};
|
||||
use watchexec::{
|
||||
config::{Config, ConfigBuilder},
|
||||
run::OnBusyUpdate,
|
||||
Shell,
|
||||
config::{Config, ConfigBuilder},
|
||||
run::OnBusyUpdate,
|
||||
Shell,
|
||||
};
|
||||
|
||||
pub fn set_commands(builder: &mut ConfigBuilder, matches: &ArgMatches) {
|
||||
let mut commands: Vec<String> = Vec::new();
|
||||
let mut commands: Vec<String> = Vec::new();
|
||||
|
||||
// --features are injected just after applicable cargo subcommands
|
||||
// and before the remaining arguments
|
||||
let features = value_t!(matches, "features", String).ok();
|
||||
// --features are injected just after applicable cargo subcommands
|
||||
// and before the remaining arguments
|
||||
let features = value_t!(matches, "features", String).ok();
|
||||
|
||||
if matches.is_present("cmd:trail") {
|
||||
debug!("trailing command is present, ignore all other command options");
|
||||
commands = vec![values_t!(matches, "cmd:trail", String)
|
||||
.unwrap_or_else(|e| e.exit())
|
||||
.into_iter()
|
||||
.map(|arg| shell_escape::escape(arg.into()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")];
|
||||
} else {
|
||||
let command_order = env::args().filter_map(|arg| match arg.as_str() {
|
||||
"-x" | "--exec" => Some("cargo"),
|
||||
"-s" | "--shell" => Some("shell"),
|
||||
_ => None,
|
||||
});
|
||||
if matches.is_present("cmd:trail") {
|
||||
debug!("trailing command is present, ignore all other command options");
|
||||
commands = vec![values_t!(matches, "cmd:trail", String)
|
||||
.unwrap_or_else(|e| e.exit())
|
||||
.into_iter()
|
||||
.map(|arg| shell_escape::escape(arg.into()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")];
|
||||
} else {
|
||||
let command_order = env::args().filter_map(|arg| match arg.as_str() {
|
||||
"-x" | "--exec" => Some("cargo"),
|
||||
"-s" | "--shell" => Some("shell"),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let mut cargos = if matches.is_present("cmd:cargo") {
|
||||
values_t!(matches, "cmd:cargo", String).unwrap_or_else(|e| e.exit())
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
.into_iter();
|
||||
let mut shells = if matches.is_present("cmd:shell") {
|
||||
values_t!(matches, "cmd:shell", String).unwrap_or_else(|e| e.exit())
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
.into_iter();
|
||||
let mut cargos = if matches.is_present("cmd:cargo") {
|
||||
values_t!(matches, "cmd:cargo", String).unwrap_or_else(|e| e.exit())
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
.into_iter();
|
||||
let mut shells = if matches.is_present("cmd:shell") {
|
||||
values_t!(matches, "cmd:shell", String).unwrap_or_else(|e| e.exit())
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
.into_iter();
|
||||
|
||||
for c in command_order {
|
||||
match c {
|
||||
"cargo" => {
|
||||
commands.push(cargo_command(
|
||||
cargos
|
||||
.next()
|
||||
.expect("Argument-order mismatch, this is a bug"),
|
||||
&features,
|
||||
));
|
||||
}
|
||||
"shell" => {
|
||||
commands.push(
|
||||
shells
|
||||
.next()
|
||||
.expect("Argument-order mismatch, this is a bug"),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
for c in command_order {
|
||||
match c {
|
||||
"cargo" => {
|
||||
commands.push(cargo_command(
|
||||
cargos
|
||||
.next()
|
||||
.expect("Argument-order mismatch, this is a bug"),
|
||||
&features,
|
||||
));
|
||||
}
|
||||
"shell" => {
|
||||
commands.push(
|
||||
shells
|
||||
.next()
|
||||
.expect("Argument-order mismatch, this is a bug"),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default to `cargo check`
|
||||
if commands.is_empty() {
|
||||
let mut cmd: String = "cargo check".into();
|
||||
if let Some(features) = features.as_ref() {
|
||||
cmd.push_str(" --features ");
|
||||
cmd.push_str(features);
|
||||
}
|
||||
commands.push(cmd);
|
||||
}
|
||||
// Default to `cargo check`
|
||||
if commands.is_empty() {
|
||||
let mut cmd: String = "cargo check".into();
|
||||
if let Some(features) = features.as_ref() {
|
||||
cmd.push_str(" --features ");
|
||||
cmd.push_str(features);
|
||||
}
|
||||
commands.push(cmd);
|
||||
}
|
||||
|
||||
debug!("Commands: {:?}", commands);
|
||||
builder.cmd(commands);
|
||||
debug!("Commands: {:?}", commands);
|
||||
builder.cmd(commands);
|
||||
}
|
||||
|
||||
fn cargo_command(cargo: String, features: &Option<String>) -> String {
|
||||
let mut cmd = String::from("cargo ");
|
||||
let mut cmd = String::from("cargo ");
|
||||
|
||||
let cargo = cargo.trim_start();
|
||||
if let Some(features) = features.as_ref() {
|
||||
if cargo.starts_with('b')
|
||||
|| cargo.starts_with("check")
|
||||
|| cargo.starts_with("doc")
|
||||
|| cargo.starts_with('r')
|
||||
|| cargo.starts_with("test")
|
||||
|| cargo.starts_with("install")
|
||||
{
|
||||
// Split command into first word and the arguments
|
||||
let word_boundary = cargo
|
||||
.find(|c: char| c.is_whitespace())
|
||||
.unwrap_or_else(|| cargo.len());
|
||||
let cargo = cargo.trim_start();
|
||||
if let Some(features) = features.as_ref() {
|
||||
if cargo.starts_with('b')
|
||||
|| cargo.starts_with("check")
|
||||
|| cargo.starts_with("doc")
|
||||
|| cargo.starts_with('r')
|
||||
|| cargo.starts_with("test")
|
||||
|| cargo.starts_with("install")
|
||||
{
|
||||
// Split command into first word and the arguments
|
||||
let word_boundary = cargo
|
||||
.find(|c: char| c.is_whitespace())
|
||||
.unwrap_or_else(|| cargo.len());
|
||||
|
||||
// Find returns the byte index, and split_at takes a byte offset.
|
||||
// This means the splitting is unicode-safe.
|
||||
let (subcommand, args) = cargo.split_at(word_boundary);
|
||||
cmd.push_str(subcommand);
|
||||
cmd.push_str(" --features ");
|
||||
cmd.push_str(features);
|
||||
cmd.push(' ');
|
||||
cmd.push_str(args);
|
||||
} else {
|
||||
cmd.push_str(&cargo);
|
||||
}
|
||||
} else {
|
||||
cmd.push_str(&cargo);
|
||||
}
|
||||
// Find returns the byte index, and split_at takes a byte offset.
|
||||
// This means the splitting is unicode-safe.
|
||||
let (subcommand, args) = cargo.split_at(word_boundary);
|
||||
cmd.push_str(subcommand);
|
||||
cmd.push_str(" --features ");
|
||||
cmd.push_str(features);
|
||||
cmd.push(' ');
|
||||
cmd.push_str(args);
|
||||
} else {
|
||||
cmd.push_str(&cargo);
|
||||
}
|
||||
} else {
|
||||
cmd.push_str(&cargo);
|
||||
}
|
||||
|
||||
cmd
|
||||
cmd
|
||||
}
|
||||
|
||||
pub fn set_ignores(builder: &mut ConfigBuilder, matches: &ArgMatches) {
|
||||
if matches.is_present("ignore-nothing") {
|
||||
debug!("Ignoring nothing");
|
||||
if matches.is_present("ignore-nothing") {
|
||||
debug!("Ignoring nothing");
|
||||
|
||||
builder.no_vcs_ignore(true);
|
||||
builder.no_ignore(true);
|
||||
return;
|
||||
}
|
||||
builder.no_vcs_ignore(true);
|
||||
builder.no_ignore(true);
|
||||
return;
|
||||
}
|
||||
|
||||
let novcs = matches.is_present("no-gitignore");
|
||||
builder.no_vcs_ignore(novcs);
|
||||
debug!("Load Git/VCS ignores: {:?}", !novcs);
|
||||
let novcs = matches.is_present("no-gitignore");
|
||||
builder.no_vcs_ignore(novcs);
|
||||
debug!("Load Git/VCS ignores: {:?}", !novcs);
|
||||
|
||||
let noignore = matches.is_present("no-ignore");
|
||||
builder.no_ignore(noignore);
|
||||
debug!("Load .ignore ignores: {:?}", !noignore);
|
||||
let noignore = matches.is_present("no-ignore");
|
||||
builder.no_ignore(noignore);
|
||||
debug!("Load .ignore ignores: {:?}", !noignore);
|
||||
|
||||
let mut list = vec![
|
||||
// Mac
|
||||
format!("*{}.DS_Store", MAIN_SEPARATOR),
|
||||
// Vim
|
||||
"*.sw?".into(),
|
||||
"*.sw?x".into(),
|
||||
// Emacs
|
||||
"#*#".into(),
|
||||
".#*".into(),
|
||||
// Kate
|
||||
".*.kate-swp".into(),
|
||||
// VCS
|
||||
format!("*{s}.hg{s}**", s = MAIN_SEPARATOR),
|
||||
format!("*{s}.git{s}**", s = MAIN_SEPARATOR),
|
||||
format!("*{s}.svn{s}**", s = MAIN_SEPARATOR),
|
||||
// SQLite
|
||||
"*.db".into(),
|
||||
"*.db-*".into(),
|
||||
format!("*{s}*.db-journal{s}**", s = MAIN_SEPARATOR),
|
||||
// Rust
|
||||
format!("*{s}target{s}**", s = MAIN_SEPARATOR),
|
||||
];
|
||||
let mut list = vec![
|
||||
// Mac
|
||||
format!("*{}.DS_Store", MAIN_SEPARATOR),
|
||||
// Vim
|
||||
"*.sw?".into(),
|
||||
"*.sw?x".into(),
|
||||
// Emacs
|
||||
"#*#".into(),
|
||||
".#*".into(),
|
||||
// Kate
|
||||
".*.kate-swp".into(),
|
||||
// VCS
|
||||
format!("*{s}.hg{s}**", s = MAIN_SEPARATOR),
|
||||
format!("*{s}.git{s}**", s = MAIN_SEPARATOR),
|
||||
format!("*{s}.svn{s}**", s = MAIN_SEPARATOR),
|
||||
// SQLite
|
||||
"*.db".into(),
|
||||
"*.db-*".into(),
|
||||
format!("*{s}*.db-journal{s}**", s = MAIN_SEPARATOR),
|
||||
// Rust
|
||||
format!("*{s}target{s}**", s = MAIN_SEPARATOR),
|
||||
];
|
||||
|
||||
debug!("Default ignores: {:?}", list);
|
||||
debug!("Default ignores: {:?}", list);
|
||||
|
||||
if matches.is_present("ignore") {
|
||||
for ignore in values_t!(matches, "ignore", String).unwrap_or_else(|e| e.exit()) {
|
||||
#[cfg(windows)]
|
||||
let ignore = ignore.replace("/", &MAIN_SEPARATOR.to_string());
|
||||
list.push(ignore);
|
||||
}
|
||||
}
|
||||
if matches.is_present("ignore") {
|
||||
for ignore in values_t!(matches, "ignore", String).unwrap_or_else(|e| e.exit()) {
|
||||
#[cfg(windows)]
|
||||
let ignore = ignore.replace("/", &MAIN_SEPARATOR.to_string());
|
||||
list.push(ignore);
|
||||
}
|
||||
}
|
||||
|
||||
debug!("All ignores: {:?}", list);
|
||||
builder.ignores(list);
|
||||
debug!("All ignores: {:?}", list);
|
||||
builder.ignores(list);
|
||||
}
|
||||
|
||||
pub fn set_debounce(builder: &mut ConfigBuilder, matches: &ArgMatches) {
|
||||
if matches.is_present("delay") {
|
||||
let debounce = value_t!(matches, "delay", f32).unwrap_or_else(|e| e.exit());
|
||||
debug!("File updates debounce: {} seconds", debounce);
|
||||
if matches.is_present("delay") {
|
||||
let debounce = value_t!(matches, "delay", f32).unwrap_or_else(|e| e.exit());
|
||||
debug!("File updates debounce: {} seconds", debounce);
|
||||
|
||||
let d = Duration::from_millis((debounce * 1000.0) as u64);
|
||||
builder.poll_interval(d).debounce(d);
|
||||
}
|
||||
let d = Duration::from_millis((debounce * 1000.0) as u64);
|
||||
builder.poll_interval(d).debounce(d);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_watches(builder: &mut ConfigBuilder, matches: &ArgMatches) {
|
||||
let mut opts = Vec::new();
|
||||
if matches.is_present("watch") {
|
||||
for watch in values_t!(matches, "watch", String).unwrap_or_else(|e| e.exit()) {
|
||||
opts.push(watch.into());
|
||||
}
|
||||
}
|
||||
let mut opts = Vec::new();
|
||||
if matches.is_present("watch") {
|
||||
for watch in values_t!(matches, "watch", String).unwrap_or_else(|e| e.exit()) {
|
||||
opts.push(watch.into());
|
||||
}
|
||||
}
|
||||
|
||||
if opts.is_empty() {
|
||||
opts.push(".".into());
|
||||
}
|
||||
if opts.is_empty() {
|
||||
opts.push(".".into());
|
||||
}
|
||||
|
||||
debug!("Watches: {:?}", opts);
|
||||
builder.paths(opts);
|
||||
debug!("Watches: {:?}", opts);
|
||||
builder.paths(opts);
|
||||
}
|
||||
|
||||
pub fn get_options(matches: &ArgMatches) -> Config {
|
||||
let mut builder = ConfigBuilder::default();
|
||||
builder
|
||||
.poll(matches.is_present("poll"))
|
||||
.clear_screen(matches.is_present("clear"))
|
||||
.run_initially(!matches.is_present("postpone"))
|
||||
.no_environment(true);
|
||||
let mut builder = ConfigBuilder::default();
|
||||
builder
|
||||
.poll(matches.is_present("poll"))
|
||||
.clear_screen(matches.is_present("clear"))
|
||||
.run_initially(!matches.is_present("postpone"))
|
||||
.no_environment(true);
|
||||
|
||||
// TODO in 8.0: remove --watch-when-idle and switch --no-restart behaviour to DoNothing
|
||||
builder.on_busy_update(if matches.is_present("no-restart") {
|
||||
OnBusyUpdate::Queue
|
||||
} else if matches.is_present("watch-when-idle") {
|
||||
OnBusyUpdate::DoNothing
|
||||
} else {
|
||||
OnBusyUpdate::Restart
|
||||
});
|
||||
// TODO in 8.0: remove --watch-when-idle and switch --no-restart behaviour to DoNothing
|
||||
builder.on_busy_update(if matches.is_present("no-restart") {
|
||||
OnBusyUpdate::Queue
|
||||
} else if matches.is_present("watch-when-idle") {
|
||||
OnBusyUpdate::DoNothing
|
||||
} else {
|
||||
OnBusyUpdate::Restart
|
||||
});
|
||||
|
||||
builder.shell(if let Some(s) = matches.value_of("use-shell") {
|
||||
if s.eq_ignore_ascii_case("powershell") {
|
||||
Shell::Powershell
|
||||
} else if s.eq_ignore_ascii_case("none") {
|
||||
warn!("--use-shell=none is non-sensical for cargo-watch, ignoring");
|
||||
default_shell()
|
||||
} else if s.eq_ignore_ascii_case("cmd") {
|
||||
cmd_shell(s.into())
|
||||
} else {
|
||||
Shell::Unix(s.into())
|
||||
}
|
||||
} else {
|
||||
// in 8.0, just rely on default watchexec behaviour
|
||||
default_shell()
|
||||
});
|
||||
builder.shell(if let Some(s) = matches.value_of("use-shell") {
|
||||
if s.eq_ignore_ascii_case("powershell") {
|
||||
Shell::Powershell
|
||||
} else if s.eq_ignore_ascii_case("none") {
|
||||
warn!("--use-shell=none is non-sensical for cargo-watch, ignoring");
|
||||
default_shell()
|
||||
} else if s.eq_ignore_ascii_case("cmd") {
|
||||
cmd_shell(s.into())
|
||||
} else {
|
||||
Shell::Unix(s.into())
|
||||
}
|
||||
} else {
|
||||
// in 8.0, just rely on default watchexec behaviour
|
||||
default_shell()
|
||||
});
|
||||
|
||||
set_ignores(&mut builder, matches);
|
||||
set_debounce(&mut builder, matches);
|
||||
set_watches(&mut builder, matches);
|
||||
set_commands(&mut builder, matches);
|
||||
set_ignores(&mut builder, matches);
|
||||
set_debounce(&mut builder, matches);
|
||||
set_watches(&mut builder, matches);
|
||||
set_commands(&mut builder, matches);
|
||||
|
||||
let mut args = builder.build().unwrap();
|
||||
args.once = matches.is_present("once");
|
||||
let mut args = builder.build().unwrap();
|
||||
args.once = matches.is_present("once");
|
||||
|
||||
debug!("Watchexec arguments: {:?}", args);
|
||||
args
|
||||
debug!("Watchexec arguments: {:?}", args);
|
||||
args
|
||||
}
|
||||
|
||||
// until 8.0
|
||||
#[cfg(windows)]
|
||||
fn default_shell() -> Shell {
|
||||
Shell::Cmd
|
||||
Shell::Cmd
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn default_shell() -> Shell {
|
||||
Shell::default()
|
||||
Shell::default()
|
||||
}
|
||||
|
||||
// because Shell::Cmd is only on windows
|
||||
#[cfg(windows)]
|
||||
fn cmd_shell(_: String) -> Shell {
|
||||
Shell::Cmd
|
||||
Shell::Cmd
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn cmd_shell(s: String) -> Shell {
|
||||
Shell::Unix(s)
|
||||
Shell::Unix(s)
|
||||
}
|
||||
|
|
34
src/root.rs
34
src/root.rs
|
@ -4,24 +4,24 @@ use log::debug;
|
|||
use std::{env::set_current_dir, process::Command};
|
||||
|
||||
pub fn project_root() -> Utf8PathBuf {
|
||||
Command::new("cargo")
|
||||
.arg("locate-project")
|
||||
.arg("--message-format")
|
||||
.arg("plain")
|
||||
.output()
|
||||
.map_err(|err| err.to_string())
|
||||
.and_then(|out| String::from_utf8(out.stdout).map_err(|err| err.to_string()))
|
||||
.map(Utf8PathBuf::from)
|
||||
.and_then(|path| {
|
||||
path.parent()
|
||||
.ok_or_else(|| String::from("project root does not exist"))
|
||||
.map(ToOwned::to_owned)
|
||||
})
|
||||
.unwrap_or_else(|err| Error::with_description(&err, ErrorKind::Io).exit())
|
||||
Command::new("cargo")
|
||||
.arg("locate-project")
|
||||
.arg("--message-format")
|
||||
.arg("plain")
|
||||
.output()
|
||||
.map_err(|err| err.to_string())
|
||||
.and_then(|out| String::from_utf8(out.stdout).map_err(|err| err.to_string()))
|
||||
.map(Utf8PathBuf::from)
|
||||
.and_then(|path| {
|
||||
path.parent()
|
||||
.ok_or_else(|| String::from("project root does not exist"))
|
||||
.map(ToOwned::to_owned)
|
||||
})
|
||||
.unwrap_or_else(|err| Error::with_description(&err, ErrorKind::Io).exit())
|
||||
}
|
||||
|
||||
pub fn change_dir(dir: Utf8PathBuf) {
|
||||
debug!("change directory to: {}", dir);
|
||||
set_current_dir(dir)
|
||||
.unwrap_or_else(|err| Error::with_description(&err.to_string(), ErrorKind::Io).exit())
|
||||
debug!("change directory to: {}", dir);
|
||||
set_current_dir(dir)
|
||||
.unwrap_or_else(|err| Error::with_description(&err.to_string(), ErrorKind::Io).exit())
|
||||
}
|
||||
|
|
126
src/watch.rs
126
src/watch.rs
|
@ -1,80 +1,80 @@
|
|||
use watchexec::{
|
||||
config::Config,
|
||||
error::Result,
|
||||
pathop::PathOp,
|
||||
run::{ExecHandler, Handler},
|
||||
config::Config,
|
||||
error::Result,
|
||||
pathop::PathOp,
|
||||
run::{ExecHandler, Handler},
|
||||
};
|
||||
|
||||
pub struct CwHandler {
|
||||
cmd: String,
|
||||
once: bool,
|
||||
quiet: bool,
|
||||
notify: bool,
|
||||
inner: ExecHandler,
|
||||
cmd: String,
|
||||
once: bool,
|
||||
quiet: bool,
|
||||
notify: bool,
|
||||
inner: ExecHandler,
|
||||
}
|
||||
|
||||
impl Handler for CwHandler {
|
||||
fn args(&self) -> Config {
|
||||
self.inner.args()
|
||||
}
|
||||
fn args(&self) -> Config {
|
||||
self.inner.args()
|
||||
}
|
||||
|
||||
fn on_manual(&self) -> Result<bool> {
|
||||
if self.once {
|
||||
Ok(true)
|
||||
} else {
|
||||
self.start();
|
||||
self.inner.on_manual()
|
||||
}
|
||||
}
|
||||
fn on_manual(&self) -> Result<bool> {
|
||||
if self.once {
|
||||
Ok(true)
|
||||
} else {
|
||||
self.start();
|
||||
self.inner.on_manual()
|
||||
}
|
||||
}
|
||||
|
||||
fn on_update(&self, ops: &[PathOp]) -> Result<bool> {
|
||||
self.start();
|
||||
self.inner.on_update(ops).map(|o| {
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
if self.notify {
|
||||
notify_rust::Notification::new()
|
||||
.summary("Cargo Watch observed a change")
|
||||
.body("Cargo Watch has seen a change, the command may have restarted.")
|
||||
.show()
|
||||
.map(drop)
|
||||
.unwrap_or_else(|err| {
|
||||
log::warn!("Failed to send desktop notification: {}", err);
|
||||
});
|
||||
}
|
||||
fn on_update(&self, ops: &[PathOp]) -> Result<bool> {
|
||||
self.start();
|
||||
self.inner.on_update(ops).map(|o| {
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
if self.notify {
|
||||
notify_rust::Notification::new()
|
||||
.summary("Cargo Watch observed a change")
|
||||
.body("Cargo Watch has seen a change, the command may have restarted.")
|
||||
.show()
|
||||
.map(drop)
|
||||
.unwrap_or_else(|err| {
|
||||
log::warn!("Failed to send desktop notification: {}", err);
|
||||
});
|
||||
}
|
||||
|
||||
o
|
||||
})
|
||||
}
|
||||
o
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CwHandler {
|
||||
pub fn new(mut args: Config, quiet: bool, notify: bool) -> Result<Self> {
|
||||
let cmd = args.cmd.join(" && ");
|
||||
let mut final_cmd = cmd.clone();
|
||||
if !quiet {
|
||||
#[cfg(unix)]
|
||||
final_cmd.push_str(r#"; echo "[Finished running. Exit status: $?]""#);
|
||||
#[cfg(windows)]
|
||||
final_cmd.push_str(r#" & echo "[Finished running. Exit status: %ERRORLEVEL%]""#);
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
final_cmd.push_str(r#" ; echo "[Finished running]""#);
|
||||
// ^ could be wrong depending on the platform, to be fixed on demand
|
||||
}
|
||||
pub fn new(mut args: Config, quiet: bool, notify: bool) -> Result<Self> {
|
||||
let cmd = args.cmd.join(" && ");
|
||||
let mut final_cmd = cmd.clone();
|
||||
if !quiet {
|
||||
#[cfg(unix)]
|
||||
final_cmd.push_str(r#"; echo "[Finished running. Exit status: $?]""#);
|
||||
#[cfg(windows)]
|
||||
final_cmd.push_str(r#" & echo "[Finished running. Exit status: %ERRORLEVEL%]""#);
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
final_cmd.push_str(r#" ; echo "[Finished running]""#);
|
||||
// ^ could be wrong depending on the platform, to be fixed on demand
|
||||
}
|
||||
|
||||
args.cmd = vec![final_cmd];
|
||||
args.cmd = vec![final_cmd];
|
||||
|
||||
Ok(Self {
|
||||
once: args.once,
|
||||
cmd,
|
||||
inner: ExecHandler::new(args)?,
|
||||
quiet,
|
||||
notify,
|
||||
})
|
||||
}
|
||||
Ok(Self {
|
||||
once: args.once,
|
||||
cmd,
|
||||
inner: ExecHandler::new(args)?,
|
||||
quiet,
|
||||
notify,
|
||||
})
|
||||
}
|
||||
|
||||
fn start(&self) {
|
||||
if !self.quiet {
|
||||
println!("[Running '{}']", self.cmd);
|
||||
}
|
||||
}
|
||||
fn start(&self) {
|
||||
if !self.quiet {
|
||||
println!("[Running '{}']", self.cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
294
tests/echo.rs
294
tests/echo.rs
|
@ -1,197 +1,197 @@
|
|||
use assert_cmd::prelude::*;
|
||||
use std::{
|
||||
fs::OpenOptions,
|
||||
io::{self, Write},
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
fs::OpenOptions,
|
||||
io::{self, Write},
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use wait_timeout::ChildExt;
|
||||
|
||||
fn touch(n: u8) -> io::Result<()> {
|
||||
let path: PathBuf = format!("./tests/touchdata/{}.txt", n).into();
|
||||
let mut file = OpenOptions::new().create(true).write(true).open(path)?;
|
||||
let path: PathBuf = format!("./tests/touchdata/{}.txt", n).into();
|
||||
let mut file = OpenOptions::new().create(true).write(true).open(path)?;
|
||||
|
||||
writeln!(&mut file, "{:?}", Instant::now())?;
|
||||
Ok(())
|
||||
writeln!(&mut file, "{:?}", Instant::now())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn std_to_string<T: io::Read>(handle: &mut Option<T>) -> String {
|
||||
if let Some(ref mut handle) = handle {
|
||||
let mut buf = String::with_capacity(1024);
|
||||
handle.read_to_string(&mut buf).unwrap();
|
||||
buf
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
if let Some(ref mut handle) = handle {
|
||||
let mut buf = String::with_capacity(1024);
|
||||
handle.read_to_string(&mut buf).unwrap();
|
||||
buf
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
// fsevents has trouble
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
#[test]
|
||||
fn without_poll() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo it runs",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo it runs",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(0).unwrap();
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(0).unwrap();
|
||||
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
main.wait_with_output().unwrap().assert().success();
|
||||
main.wait_with_output().unwrap().assert().success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_poll() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo it runs",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo it runs",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(1).unwrap();
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(1).unwrap();
|
||||
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
main.wait_with_output().unwrap().assert().success();
|
||||
main.wait_with_output().unwrap().assert().success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))] // annoyingly, there’s some kind of encoding or extra bytes getting added here, needs debugging
|
||||
fn with_announce() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo with announce",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo with announce",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(2).unwrap();
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(2).unwrap();
|
||||
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
insta::assert_snapshot!("with_announce.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("with_announce.stdout", std_to_string(&mut main.stdout));
|
||||
insta::assert_snapshot!("with_announce.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("with_announce.stdout", std_to_string(&mut main.stdout));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_announce() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--quiet",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo without announce",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--quiet",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo without announce",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(3).unwrap();
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(3).unwrap();
|
||||
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
insta::assert_snapshot!("without_announce.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("without_announce.stdout", std_to_string(&mut main.stdout));
|
||||
insta::assert_snapshot!("without_announce.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("without_announce.stdout", std_to_string(&mut main.stdout));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn with_error() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo with error",
|
||||
"-s",
|
||||
"false",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&[
|
||||
"--testing-only--once",
|
||||
"--no-gitignore",
|
||||
"--poll",
|
||||
"-w",
|
||||
"./tests/touchdata/",
|
||||
"-s",
|
||||
"echo with error",
|
||||
"-s",
|
||||
"false",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(4).unwrap();
|
||||
sleep(Duration::from_secs(2));
|
||||
touch(4).unwrap();
|
||||
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main
|
||||
.wait_timeout(Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
insta::assert_snapshot!("with_error.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("with_error.stdout", std_to_string(&mut main.stdout));
|
||||
insta::assert_snapshot!("with_error.stderr", std_to_string(&mut main.stderr));
|
||||
insta::assert_snapshot!("with_error.stdout", std_to_string(&mut main.stdout));
|
||||
}
|
||||
|
|
|
@ -1,69 +1,69 @@
|
|||
use assert_cmd::prelude::*;
|
||||
use predicates::str::is_match;
|
||||
use std::{
|
||||
process::{Command, Stdio},
|
||||
time::Duration,
|
||||
process::{Command, Stdio},
|
||||
time::Duration,
|
||||
};
|
||||
use wait_timeout::ChildExt;
|
||||
|
||||
#[test]
|
||||
fn with_cargo() {
|
||||
let mut main = Command::new("cargo")
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["watch", "--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::new("cargo")
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["watch", "--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_cargo() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["watch", "--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["watch", "--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_watch() {
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let mut main = Command::cargo_bin("cargo-watch")
|
||||
.unwrap()
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.args(&["--version"])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
if main.wait_timeout(Duration::from_secs(1)).unwrap().is_none() {
|
||||
main.kill().unwrap();
|
||||
}
|
||||
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
main.wait_with_output()
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(is_match(r"cargo-watch \d+\.\d+\.\d+\n").unwrap());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue