Skip to content

Commit 4bb85f9

Browse files
authored
Merge pull request #281 from epage/cargo_bin
fix: Improve the quality of the panic message
2 parents 8ccb13f + 90a660d commit 4bb85f9

1 file changed

Lines changed: 46 additions & 17 deletions

File tree

src/cargo.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -217,21 +217,6 @@ impl fmt::Display for NotFoundError {
217217
}
218218
}
219219

220-
// Adapted from
221-
// https://github.com/rust-lang/cargo/blob/485670b3983b52289a2f353d589c57fae2f60f82/tests/testsuite/support/mod.rs#L507
222-
fn target_dir() -> path::PathBuf {
223-
env::current_exe()
224-
.ok()
225-
.map(|mut path| {
226-
path.pop();
227-
if path.ends_with("deps") {
228-
path.pop();
229-
}
230-
path
231-
})
232-
.expect("this should only be used where a `current_exe` can be set")
233-
}
234-
235220
/// Look up the path to a cargo-built binary within an integration test.
236221
///
237222
/// **NOTE:** Prefer [`cargo_bin!`] as this makes assumptions about cargo
@@ -244,10 +229,54 @@ pub fn cargo_bin<S: AsRef<str>>(name: S) -> path::PathBuf {
244229
}
245230

246231
fn cargo_bin_str(name: &str) -> path::PathBuf {
247-
let env_var = format!("CARGO_BIN_EXE_{name}");
232+
let env_var = format!("{CARGO_BIN_EXE_}{name}");
248233
env::var_os(env_var)
249234
.map(|p| p.into())
250-
.unwrap_or_else(|| target_dir().join(format!("{}{}", name, env::consts::EXE_SUFFIX)))
235+
.or_else(|| legacy_cargo_bin(name))
236+
.unwrap_or_else(|| missing_cargo_bin(name))
237+
}
238+
239+
const CARGO_BIN_EXE_: &str = "CARGO_BIN_EXE_";
240+
241+
fn missing_cargo_bin(name: &str) -> ! {
242+
let possible_names: Vec<_> = env::vars_os()
243+
.filter_map(|(k, _)| k.into_string().ok())
244+
.filter_map(|k| k.strip_prefix(CARGO_BIN_EXE_).map(|s| s.to_owned()))
245+
.collect();
246+
if possible_names.is_empty() {
247+
panic!("`CARGO_BIN_EXE_{name}` is unset
248+
help: if this is running within a unit test, move it to an integration test to gain access to `CARGO_BIN_EXE_{name}`")
249+
} else {
250+
let mut names = String::new();
251+
for (i, name) in possible_names.iter().enumerate() {
252+
use std::fmt::Write as _;
253+
if i != 0 {
254+
let _ = write!(&mut names, ", ");
255+
}
256+
let _ = write!(&mut names, "\"{name}\"");
257+
}
258+
panic!(
259+
"`CARGO_BIN_EXE_{name}` is unset
260+
help: available binary names are {names}"
261+
)
262+
}
263+
}
264+
265+
fn legacy_cargo_bin(name: &str) -> Option<path::PathBuf> {
266+
let target_dir = target_dir()?;
267+
let bin_path = target_dir.join(format!("{}{}", name, env::consts::EXE_SUFFIX));
268+
Some(bin_path)
269+
}
270+
271+
// Adapted from
272+
// https://github.com/rust-lang/cargo/blob/485670b3983b52289a2f353d589c57fae2f60f82/tests/testsuite/support/mod.rs#L507
273+
fn target_dir() -> Option<path::PathBuf> {
274+
let mut path = env::current_exe().ok()?;
275+
let _test_bin_name = path.pop();
276+
if path.ends_with("deps") {
277+
let _deps = path.pop();
278+
}
279+
Some(path)
251280
}
252281

253282
/// The current process' target triplet.

0 commit comments

Comments
 (0)