Skip to content

Commit 85a429c

Browse files
committed
fix(cmd): Panic on non-existent cargo_bin
Pulls in - assert-rs/assert_cmd#281 - assert-rs/assert_cmd#282 - assert-rs/assert_cmd#283
1 parent 8b196b9 commit 85a429c

2 files changed

Lines changed: 69 additions & 15 deletions

File tree

crates/snapbox/src/cmd.rs

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -849,29 +849,68 @@ fn wait(
849849
#[doc(inline)]
850850
pub use crate::cargo_bin;
851851

852-
/// Look up the path to a cargo-built binary within an integration test.
852+
/// Look up the path to a cargo-built binary within an integration test
853853
///
854-
/// **NOTE:** Prefer [`cargo_bin!`] as this makes assumptions about cargo
854+
/// Cargo support:
855+
/// - `>1.94`: works
856+
/// - `>=1.91,<=1.93`: works with default `build-dir`
857+
/// - `<=1.92`: works
858+
///
859+
/// # Panic
860+
///
861+
/// Panics if no binary is found
855862
pub fn cargo_bin(name: &str) -> std::path::PathBuf {
856-
let env_var = format!("CARGO_BIN_EXE_{name}");
863+
let env_var = format!("{CARGO_BIN_EXE_}{name}");
857864
std::env::var_os(env_var)
858865
.map(|p| p.into())
859-
.unwrap_or_else(|| target_dir().join(format!("{}{}", name, std::env::consts::EXE_SUFFIX)))
866+
.or_else(|| legacy_cargo_bin(name))
867+
.unwrap_or_else(|| missing_cargo_bin(name))
868+
}
869+
870+
const CARGO_BIN_EXE_: &str = "CARGO_BIN_EXE_";
871+
872+
fn missing_cargo_bin(name: &str) -> ! {
873+
let possible_names: Vec<_> = std::env::vars_os()
874+
.filter_map(|(k, _)| k.into_string().ok())
875+
.filter_map(|k| k.strip_prefix(CARGO_BIN_EXE_).map(|s| s.to_owned()))
876+
.collect();
877+
if possible_names.is_empty() {
878+
panic!("`CARGO_BIN_EXE_{name}` is unset
879+
help: if this is running within a unit test, move it to an integration test to gain access to `CARGO_BIN_EXE_{name}`")
880+
} else {
881+
let mut names = String::new();
882+
for (i, name) in possible_names.iter().enumerate() {
883+
use std::fmt::Write as _;
884+
if i != 0 {
885+
let _ = write!(&mut names, ", ");
886+
}
887+
let _ = write!(&mut names, "\"{name}\"");
888+
}
889+
panic!(
890+
"`CARGO_BIN_EXE_{name}` is unset
891+
help: available binary names are {names}"
892+
)
893+
}
894+
}
895+
896+
fn legacy_cargo_bin(name: &str) -> Option<std::path::PathBuf> {
897+
let target_dir = target_dir()?;
898+
let bin_path = target_dir.join(format!("{}{}", name, std::env::consts::EXE_SUFFIX));
899+
if !bin_path.exists() {
900+
return None;
901+
}
902+
Some(bin_path)
860903
}
861904

862905
// Adapted from
863906
// https://github.com/rust-lang/cargo/blob/485670b3983b52289a2f353d589c57fae2f60f82/tests/testsuite/support/mod.rs#L507
864-
fn target_dir() -> std::path::PathBuf {
865-
std::env::current_exe()
866-
.ok()
867-
.map(|mut path| {
868-
path.pop();
869-
if path.ends_with("deps") {
870-
path.pop();
871-
}
872-
path
873-
})
874-
.unwrap()
907+
fn target_dir() -> Option<std::path::PathBuf> {
908+
let mut path = std::env::current_exe().ok()?;
909+
let _test_bin_name = path.pop();
910+
if path.ends_with("deps") {
911+
let _deps = path.pop();
912+
}
913+
Some(path)
875914
}
876915

877916
#[cfg(feature = "examples")]
@@ -1009,3 +1048,10 @@ pub(crate) mod examples {
10091048
target.crate_types == ["bin"] && target.kind == ["example"]
10101049
}
10111050
}
1051+
1052+
#[test]
1053+
#[should_panic = "`CARGO_BIN_EXE_non-existent` is unset
1054+
help: if this is running within a unit test, move it to an integration test to gain access to `CARGO_BIN_EXE_non-existent`"]
1055+
fn cargo_bin_in_unit_test() {
1056+
cargo_bin("non-existent");
1057+
}

crates/snapbox/tests/testsuite/cmd.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,11 @@ fn large_stdout_single() {
3333
.assert()
3434
.success();
3535
}
36+
37+
#[test]
38+
#[cfg(feature = "cmd")]
39+
#[should_panic = "`CARGO_BIN_EXE_non-existent` is unset
40+
help: available binary names are \"bin_fixture\""]
41+
fn cargo_bin_non_existent() {
42+
let _ = snapbox::cmd::cargo_bin("non-existent");
43+
}

0 commit comments

Comments
 (0)