diff --git a/Cargo.toml b/Cargo.toml index 5af5441..b159ee6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,7 @@ name = "bin_fixture" predicates = "0.9.0" predicates-core = "0.9.0" predicates-tree = "0.9.0" -escargot = "0.2" -serde = { version = "1.0", features = ["derive"] } +escargot = "0.3" [dev-dependencies] docmatic = "0.1" diff --git a/src/cargo.rs b/src/cargo.rs index 062e65c..a00a23a 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -20,15 +20,21 @@ //! .unwrap(); //! ``` //! -//! Caching the binary's location: +//! For caching to minimize cargo overhead or customize the build process, see [`escargot`]. //! -//! ```rust +//! ```rust,ignore //! use assert_cmd::prelude::*; +//! use escargot; //! //! use std::process::Command; //! -//! let bin_under_test = assert_cmd::cargo::main_binary_path().unwrap(); -//! Command::new(&bin_under_test) +//! let bin_under_test = escargot::CargoBuild::new() +//! .bin("bin_fixture") +//! .current_release() +//! .current_target() +//! .run() +//! .unwrap(); +//! bin_under_test.command() //! .unwrap(); //! ``` //! @@ -37,6 +43,7 @@ //! [`lazy_static`]: https://crates.io/crates/lazy_static //! [`CommandCargoExt`]: trait.CommandCargoExt.html //! [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html +//! [`escargot`]: https://docs.rs/escargot/ use std::error::Error; use std::ffi; @@ -128,52 +135,29 @@ where impl CommandCargoExt for process::Command { fn main_binary() -> Result { - let cmd = main_binary_path()?; - Ok(process::Command::new(&cmd)) + let runner = escargot::CargoBuild::new() + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.command()) } fn cargo_bin>(name: S) -> Result { - let cmd = cargo_bin_path(name)?; - Ok(process::Command::new(&cmd)) + let runner = escargot::CargoBuild::new() + .bin(name) + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.command()) } fn cargo_example>(name: S) -> Result { - let cmd = cargo_example_path(name)?; - Ok(process::Command::new(&cmd)) - } -} - -#[derive(Deserialize)] -struct MessageTarget<'a> { - #[serde(borrow)] - crate_types: Vec<&'a str>, - #[serde(borrow)] - kind: Vec<&'a str>, -} - -#[derive(Deserialize)] -struct MessageFilter<'a> { - #[serde(borrow)] - reason: &'a str, - target: MessageTarget<'a>, - filenames: Vec, -} - -fn extract_filenames(msg: &escargot::Message, kind: &str) -> Option { - let filter: MessageFilter = msg.convert().ok()?; - if filter.reason != "compiler-artifact" - || filter.target.crate_types != ["bin"] - || filter.target.kind != [kind] - { - None - } else { - Some( - filter - .filenames - .into_iter() - .next() - .expect("files must exist"), - ) + let runner = escargot::CargoBuild::new() + .example(name) + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.command()) } } @@ -194,22 +178,13 @@ fn extract_filenames(msg: &escargot::Message, kind: &str) -> Option Result { - let cargo = escargot::Cargo::new().build().current_release(); - let bins: Vec<_> = cargo - .exec() - .map_err(CargoError::with_cause)? - .filter_map(|m| extract_filenames(&m, "bin")) - .collect(); - if bins.is_empty() { - return Err(CargoError::with_context("No binaries in crate")); - } else if bins.len() != 1 { - return Err(CargoError::with_context(format!( - "Ambiguous which binary is intended: {:?}", - bins - ))); - } - Ok(bins.into_iter().next().expect("already validated")) + let runner = escargot::CargoBuild::new() + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.path().to_owned()) } /// Get the path to the specified binary of the current crate. @@ -227,15 +202,14 @@ pub fn main_binary_path() -> Result { /// Command::new(&bin_under_test) /// .unwrap(); /// ``` +#[deprecated(since = "0.9.1", note = "For caching, using escargot directly.")] pub fn cargo_bin_path>(name: S) -> Result { - let cargo = escargot::Cargo::new().build().bin(name).current_release(); - let bins: Vec<_> = cargo - .exec() - .map_err(CargoError::with_cause)? - .filter_map(|m| extract_filenames(&m, "bin")) - .collect(); - assert_eq!(bins.len(), 1); - Ok(bins.into_iter().next().expect("already validated")) + let runner = escargot::CargoBuild::new() + .bin(name) + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.path().to_owned()) } /// Get the path to the specified example of the current crate. @@ -253,48 +227,29 @@ pub fn cargo_bin_path>(name: S) -> Result>(name: S) -> Result { - let cargo = escargot::Cargo::new() - .build() + let runner = escargot::CargoBuild::new() .example(name) - .current_release(); - let bins: Vec<_> = cargo - .exec() - .map_err(CargoError::with_cause)? - .filter_map(|m| extract_filenames(&m, "example")) - .collect(); - assert_eq!(bins.len(), 1); - Ok(bins.into_iter().next().expect("already validated")) + .current_release() + .run() + .map_err(CargoError::with_cause)?; + Ok(runner.path().to_owned()) } /// Error when finding crate binary. #[derive(Debug)] pub struct CargoError { - context: Option, cause: Option>, } impl CargoError { - fn with_context(context: S) -> Self - where - S: Into, - { - let context = context.into(); - Self { - context: Some(context), - cause: None, - } - } - fn with_cause(cause: E) -> Self where E: Error + Send + Sync + 'static, { let cause = Box::new(cause); - Self { - context: None, - cause: Some(cause), - } + Self { cause: Some(cause) } } } @@ -313,9 +268,6 @@ impl Error for CargoError { impl fmt::Display for CargoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(ref context) = self.context { - writeln!(f, "{}", context)?; - } if let Some(ref cause) = self.cause { writeln!(f, "Cause: {}", cause)?; } diff --git a/src/lib.rs b/src/lib.rs index 8b30c40..440dd49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,8 +64,6 @@ extern crate escargot; extern crate predicates; extern crate predicates_core; extern crate predicates_tree; -#[macro_use] -extern crate serde; pub mod assert; pub use assert::Assert; diff --git a/tests/cargo.rs b/tests/cargo.rs index 79a6725..61a435f 100644 --- a/tests/cargo.rs +++ b/tests/cargo.rs @@ -1,4 +1,5 @@ extern crate assert_cmd; +extern crate escargot; extern crate predicates; use std::process; @@ -46,3 +47,14 @@ fn cargo_example_with_empty_env() { cmd.env_clear().env("stdout", "42"); cmd.assert().success().stdout("42\n"); } + +#[test] +fn cargo_example_cache() { + let bin_under_test = escargot::CargoBuild::new() + .bin("bin_fixture") + .current_release() + .current_target() + .run() + .unwrap(); + bin_under_test.command().unwrap(); +}