Skip to content

fix(cargo): Point people to escargot #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 9, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
144 changes: 48 additions & 96 deletions src/cargo.rs
Original file line number Diff line number Diff line change
@@ -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<Self, CargoError> {
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<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError> {
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<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError> {
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<path::PathBuf>,
}

fn extract_filenames(msg: &escargot::Message, kind: &str) -> Option<path::PathBuf> {
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<path::PathBu
/// Command::new(&bin_under_test)
/// .unwrap();
/// ```
#[deprecated(since = "0.9.1", note = "For caching, using escargot directly.")]
pub fn main_binary_path() -> Result<path::PathBuf, CargoError> {
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<path::PathBuf, CargoError> {
/// Command::new(&bin_under_test)
/// .unwrap();
/// ```
#[deprecated(since = "0.9.1", note = "For caching, using escargot directly.")]
pub fn cargo_bin_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, CargoError> {
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<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, Ca
/// Command::new(&bin_under_test)
/// .unwrap();
/// ```
#[deprecated(since = "0.9.1", note = "For caching, using escargot directly.")]
pub fn cargo_example_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, CargoError> {
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<String>,
cause: Option<Box<Error + Send + Sync + 'static>>,
}

impl CargoError {
fn with_context<S>(context: S) -> Self
where
S: Into<String>,
{
let context = context.into();
Self {
context: Some(context),
cause: None,
}
}

fn with_cause<E>(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)?;
}
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
12 changes: 12 additions & 0 deletions tests/cargo.rs
Original file line number Diff line number Diff line change
@@ -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();
}