diff --git a/.editorconfig b/.editorconfig index 69fbfa8..68447e9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..218e203 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +hard_tabs = true diff --git a/src/args.rs b/src/args.rs index f4de3da..0abed5c 100644 --- a/src/args.rs +++ b/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 = 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 = 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 } diff --git a/src/main.rs b/src/main.rs index 7e8d0b9..49ca34c 100644 --- a/src/main.rs +++ b/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) } diff --git a/src/options.rs b/src/options.rs index 1b20c8a..871658b 100644 --- a/src/options.rs +++ b/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 = Vec::new(); + let mut commands: Vec = 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::>() - .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::>() + .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 { - 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) } diff --git a/src/root.rs b/src/root.rs index 2630ed7..811bd43 100644 --- a/src/root.rs +++ b/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()) } diff --git a/src/watch.rs b/src/watch.rs index 4f12b77..7a62831 100644 --- a/src/watch.rs +++ b/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 { - if self.once { - Ok(true) - } else { - self.start(); - self.inner.on_manual() - } - } + fn on_manual(&self) -> Result { + if self.once { + Ok(true) + } else { + self.start(); + self.inner.on_manual() + } + } - fn on_update(&self, ops: &[PathOp]) -> Result { - 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 { + 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 { - 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 { + 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); + } + } } diff --git a/tests/echo.rs b/tests/echo.rs index dbc3d5b..05f51c7 100644 --- a/tests/echo.rs +++ b/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(handle: &mut Option) -> 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)); } diff --git a/tests/exec.rs b/tests/exec.rs index cea5472..46de03f 100644 --- a/tests/exec.rs +++ b/tests/exec.rs @@ -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()); }