Skip to content

Commit 7bd71a8

Browse files
committed
fix(cargo): Define a CargoError
Fixed #7
1 parent 8d273e6 commit 7bd71a8

File tree

3 files changed

+79
-22
lines changed

3 files changed

+79
-22
lines changed

Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ keywords = ["cli", "test", "assert", "command", "duct"]
1515
name = "bin_fixture"
1616

1717
[dependencies]
18-
failure = "0.1"
19-
failure_derive = "0.1"
2018
predicates = "0.5.1"
21-
escargot = "0.1"
19+
escargot = "0.2"
2220
serde = { version = "1.0", features = ["derive"] }
2321

2422
[dev-dependencies]

src/cargo.rs

+78-15
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
//! .unwrap();
1313
//! ```
1414
15+
use std::error::Error;
1516
use std::ffi;
17+
use std::fmt;
1618
use std::path;
1719
use std::process;
1820

1921
use escargot;
20-
use failure;
2122

2223
/// Create a `Command` for a `bin` in the Cargo project.
2324
pub trait CommandCargoExt
@@ -39,7 +40,7 @@ where
3940
/// .unwrap()
4041
/// .unwrap();
4142
/// ```
42-
fn main_binary() -> Result<Self, failure::Error>;
43+
fn main_binary() -> Result<Self, CargoError>;
4344

4445
/// Create a `Command` to run a specific binary of the current crate.
4546
///
@@ -54,7 +55,7 @@ where
5455
/// .unwrap()
5556
/// .unwrap();
5657
/// ```
57-
fn cargo_bin<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, failure::Error>;
58+
fn cargo_bin<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError>;
5859

5960
/// Create a `Command` to run a specific example of the current crate.
6061
///
@@ -69,21 +70,21 @@ where
6970
/// .unwrap()
7071
/// .unwrap();
7172
/// ```
72-
fn cargo_example<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, failure::Error>;
73+
fn cargo_example<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError>;
7374
}
7475

7576
impl CommandCargoExt for process::Command {
76-
fn main_binary() -> Result<Self, failure::Error> {
77+
fn main_binary() -> Result<Self, CargoError> {
7778
let cmd = main_binary_path()?;
7879
Ok(process::Command::new(&cmd))
7980
}
8081

81-
fn cargo_bin<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, failure::Error> {
82+
fn cargo_bin<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError> {
8283
let cmd = cargo_bin_path(name)?;
8384
Ok(process::Command::new(&cmd))
8485
}
8586

86-
fn cargo_example<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, failure::Error> {
87+
fn cargo_example<S: AsRef<ffi::OsStr>>(name: S) -> Result<Self, CargoError> {
8788
let cmd = cargo_example_path(name)?;
8889
Ok(process::Command::new(&cmd))
8990
}
@@ -126,41 +127,103 @@ fn extract_filenames(msg: &escargot::Message, kind: &str) -> Option<path::PathBu
126127
/// Get the path to the crate's main binary.
127128
///
128129
/// Note: only works if there one bin in the crate.
129-
pub fn main_binary_path() -> Result<path::PathBuf, failure::Error> {
130+
pub fn main_binary_path() -> Result<path::PathBuf, CargoError> {
130131
let cargo = escargot::Cargo::new().build().current_release();
131132
let bins: Vec<_> = cargo
132-
.exec()?
133+
.exec()
134+
.map_err(|e| CargoError::with_cause(e))?
133135
.filter_map(|m| extract_filenames(&m, "bin"))
134136
.collect();
135137
if bins.is_empty() {
136-
bail!("No binaries in crate");
138+
return Err(CargoError::with_context("No binaries in crate"));
137139
} else if bins.len() != 1 {
138-
bail!("Ambiguous which binary is intended: {:?}", bins);
140+
return Err(CargoError::with_context(format!(
141+
"Ambiguous which binary is intended: {:?}",
142+
bins
143+
)));
139144
}
140145
Ok(bins.into_iter().next().expect("already validated"))
141146
}
142147

143148
/// Get the path to the specified binary of the current crate.
144-
pub fn cargo_bin_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, failure::Error> {
149+
pub fn cargo_bin_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, CargoError> {
145150
let cargo = escargot::Cargo::new().build().bin(name).current_release();
146151
let bins: Vec<_> = cargo
147-
.exec()?
152+
.exec()
153+
.map_err(|e| CargoError::with_cause(e))?
148154
.filter_map(|m| extract_filenames(&m, "bin"))
149155
.collect();
150156
assert_eq!(bins.len(), 1);
151157
Ok(bins.into_iter().next().expect("already validated"))
152158
}
153159

154160
/// Get the path to the specified example of the current crate.
155-
pub fn cargo_example_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, failure::Error> {
161+
pub fn cargo_example_path<S: AsRef<ffi::OsStr>>(name: S) -> Result<path::PathBuf, CargoError> {
156162
let cargo = escargot::Cargo::new()
157163
.build()
158164
.example(name)
159165
.current_release();
160166
let bins: Vec<_> = cargo
161-
.exec()?
167+
.exec()
168+
.map_err(|e| CargoError::with_cause(e))?
162169
.filter_map(|m| extract_filenames(&m, "example"))
163170
.collect();
164171
assert_eq!(bins.len(), 1);
165172
Ok(bins.into_iter().next().expect("already validated"))
166173
}
174+
175+
/// Error when finding crate binary.
176+
#[derive(Debug)]
177+
pub struct CargoError {
178+
context: Option<String>,
179+
cause: Option<Box<Error + Send + Sync + 'static>>,
180+
}
181+
182+
impl CargoError {
183+
fn with_context<S>(context: S) -> Self
184+
where
185+
S: Into<String>,
186+
{
187+
let context = context.into();
188+
Self {
189+
context: Some(context),
190+
cause: None,
191+
}
192+
}
193+
194+
fn with_cause<E>(cause: E) -> Self
195+
where
196+
E: Error + Send + Sync + 'static,
197+
{
198+
let cause = Box::new(cause);
199+
Self {
200+
context: None,
201+
cause: Some(cause),
202+
}
203+
}
204+
}
205+
206+
impl Error for CargoError {
207+
fn description(&self) -> &str {
208+
"Cargo command failed."
209+
}
210+
211+
fn cause(&self) -> Option<&Error> {
212+
self.cause.as_ref().map(|c| {
213+
let c: &Error = c.as_ref();
214+
c
215+
})
216+
}
217+
}
218+
219+
impl fmt::Display for CargoError {
220+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
221+
if let Some(ref context) = self.context {
222+
writeln!(f, "{}", context)?;
223+
}
224+
if let Some(ref cause) = self.cause {
225+
writeln!(f, "Cause: {}", cause)?;
226+
}
227+
Ok(())
228+
}
229+
}

src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@
3737
#![warn(missing_docs)]
3838

3939
extern crate escargot;
40-
#[macro_use]
41-
extern crate failure;
42-
#[macro_use]
43-
extern crate failure_derive;
4440
extern crate predicates;
4541
#[macro_use]
4642
extern crate serde;

0 commit comments

Comments
 (0)