From 17d7c83d94c9c61fdd33940618c22d913516192b Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 11:59:28 -0500 Subject: [PATCH 1/6] feat: Default `cargo_bin!` to the package name --- src/macros.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/macros.rs b/src/macros.rs index 9b1c511..9f23a1e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -37,13 +37,16 @@ macro_rules! crate_name { /// #[test] /// fn cli_tests() { /// trycmd::TestCases::new() -/// .default_bin_path(trycmd::cargo_bin!("bin-fixture")) +/// .default_bin_path(trycmd::cargo_bin!()) /// .case("tests/cmd/*.trycmd"); /// } /// ``` #[macro_export] #[doc(hidden)] macro_rules! cargo_bin { + () => { + $crate::cargo::cargo_bin!($crate::crate_name!()) + }; ($bin_target_name:expr) => { ::std::path::Path::new(env!(concat!("CARGO_BIN_EXE_", $bin_target_name))) }; From 375e14701252f93a1a50eb156146e9937feb83b9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 12:00:55 -0500 Subject: [PATCH 2/6] fix: Rename crate_name to pkg_name --- src/macros.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 9f23a1e..920eb3c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,7 +5,7 @@ /// ```should_panic /// use assert_cmd::Command; /// -/// let mut cmd = Command::cargo_bin(assert_cmd::crate_name!()).unwrap(); +/// let mut cmd = Command::cargo_bin(assert_cmd::pkg_name!()).unwrap(); /// let assert = cmd /// .arg("-A") /// .env("stdout", "hello") @@ -18,6 +18,15 @@ /// .stdout("hello\n"); /// ``` #[macro_export] +macro_rules! pkg_name { + () => { + env!("CARGO_PKG_NAME") + }; +} + +/// Deprecated, replaced with [`pkg_name`] +#[deprecated(since = "2.1.0", note = "replaced with `pkg_name!`")] +#[macro_export] macro_rules! crate_name { () => { env!("CARGO_PKG_NAME") @@ -45,7 +54,7 @@ macro_rules! crate_name { #[doc(hidden)] macro_rules! cargo_bin { () => { - $crate::cargo::cargo_bin!($crate::crate_name!()) + $crate::cargo::cargo_bin!($crate::pkg_name!()) }; ($bin_target_name:expr) => { ::std::path::Path::new(env!(concat!("CARGO_BIN_EXE_", $bin_target_name))) From 069482bb325d223c1d5524c43f8026c6e4f1a07d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 12:05:51 -0500 Subject: [PATCH 3/6] docs: Use a local example for `cargo_bin!` --- src/macros.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 920eb3c..1637447 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -42,13 +42,15 @@ macro_rules! crate_name { /// /// ## Example /// -/// ```rust,no_run -/// #[test] -/// fn cli_tests() { -/// trycmd::TestCases::new() -/// .default_bin_path(trycmd::cargo_bin!()) -/// .case("tests/cmd/*.trycmd"); -/// } +/// ```rust,ignore +/// use assert_cmd::prelude::*; +/// use assert_cmd::cargo::cargo_bin; +/// +/// use std::process::Command; +/// +/// let mut cmd = Command::new(cargo_bin!()) +/// .unwrap(); +/// let output = cmd.unwrap(); /// ``` #[macro_export] #[doc(hidden)] From e60035f5dacc4d03688532078477a4d13e320e3c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 12:08:10 -0500 Subject: [PATCH 4/6] docs: Prefer pkg_name over CARGO_PKG_NAME --- src/cargo.rs | 9 ++++++--- src/cmd.rs | 3 ++- tests/cargo.rs | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/cargo.rs b/src/cargo.rs index ce9bfe4..281961b 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -9,10 +9,11 @@ //! //! ```rust,no_run //! use assert_cmd::prelude::*; +//! use assert_cmd::pkg_name; //! //! use std::process::Command; //! -//! let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) +//! let mut cmd = Command::cargo_bin(pkg_name!()) //! .unwrap(); //! let output = cmd.unwrap(); //! ``` @@ -74,10 +75,11 @@ pub use crate::cargo_bin; /// /// ```rust,no_run /// use assert_cmd::prelude::*; +/// use assert_cmd::pkg_name; /// /// use std::process::Command; /// -/// let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) +/// let mut cmd = Command::cargo_bin(pkg_name!()) /// .unwrap(); /// let output = cmd.unwrap(); /// println!("{:?}", output); @@ -104,10 +106,11 @@ where /// /// ```rust,no_run /// use assert_cmd::prelude::*; + /// use assert_cmd::pkg_name; /// /// use std::process::Command; /// - /// let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) + /// let mut cmd = Command::cargo_bin(pkg_name!()) /// .unwrap(); /// let output = cmd.unwrap(); /// println!("{:?}", output); diff --git a/src/cmd.rs b/src/cmd.rs index ff023c6..e5a4058 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -43,8 +43,9 @@ impl Command { /// /// ```rust,no_run /// use assert_cmd::Command; + /// use assert_cmd::pkg_name; /// - /// let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) + /// let mut cmd = Command::cargo_bin(pkg_name!()) /// .unwrap(); /// let output = cmd.unwrap(); /// println!("{:?}", output); diff --git a/tests/cargo.rs b/tests/cargo.rs index b7a244a..4861ad3 100644 --- a/tests/cargo.rs +++ b/tests/cargo.rs @@ -1,5 +1,6 @@ use std::process::Command; +use assert_cmd::pkg_name; use assert_cmd::prelude::*; use escargot::CURRENT_TARGET; @@ -41,7 +42,7 @@ fn mod_example() { #[test] #[should_panic] // No bin named `assert_cmd fn trait_example() { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); + let mut cmd = Command::cargo_bin(pkg_name!()).unwrap(); let output = cmd.unwrap(); println!("{output:?}"); } @@ -49,7 +50,7 @@ fn trait_example() { #[test] #[should_panic] // No bin named `assert_cmd fn cargo_bin_example_1() { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); + let mut cmd = Command::cargo_bin(pkg_name!()).unwrap(); let output = cmd.unwrap(); println!("{output:?}"); } From b8f7ded59ce06a6b77f61a67e139567367d189d7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 12:35:16 -0500 Subject: [PATCH 5/6] feat: Provide `cargo_bin_cmd!` --- src/cargo.rs | 2 ++ src/macros.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/cargo.rs b/src/cargo.rs index 281961b..049b217 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -63,6 +63,8 @@ use std::process; #[doc(inline)] pub use crate::cargo_bin; +#[doc(inline)] +pub use crate::cargo_bin_cmd; /// Create a [`Command`] for a `bin` in the Cargo project. /// diff --git a/src/macros.rs b/src/macros.rs index 1637447..0afa8a5 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -62,3 +62,33 @@ macro_rules! cargo_bin { ::std::path::Path::new(env!(concat!("CARGO_BIN_EXE_", $bin_target_name))) }; } + +/// The absolute path to a binary target's executable. +/// +/// The `bin_target_name` is the name of the binary +/// target, exactly as-is. +/// +/// **NOTE:** This is only set when building an integration test or benchmark. +/// +/// ## Example +/// +/// ```rust,ignore +/// use assert_cmd::prelude::*; +/// use assert_cmd::cargo::cargo_bin_cmd; +/// +/// use std::process::Command; +/// +/// let mut cmd = cargo_bin_cmd!() +/// .unwrap(); +/// let output = cmd.unwrap(); +/// ``` +#[macro_export] +#[doc(hidden)] +macro_rules! cargo_bin_cmd { + () => { + $crate::cargo::cargo_bin_cmd!($crate::pkg_name!()) + }; + ($bin_target_name:expr) => { + $crate::Command::new($crate::cargo::cargo_bin!($bin_target_name)) + }; +} From b744e271b74fb70109cdff6b2c0567e03e69f68e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 28 Oct 2025 12:39:35 -0500 Subject: [PATCH 6/6] fix: Deprecate cargo_bin (runtime version) --- src/cargo.rs | 10 ++++++++ src/cmd.rs | 4 ++++ tests/assert.rs | 60 +++++++++++++++++------------------------------ tests/cargo.rs | 24 ++++--------------- tests/examples.rs | 11 ++++----- 5 files changed, 43 insertions(+), 66 deletions(-) diff --git a/src/cargo.rs b/src/cargo.rs index 049b217..0e64334 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -130,11 +130,16 @@ where /// ``` /// /// [`Command`]: std::process::Command + #[deprecated( + since = "2.1.0", + note = "incompatible with a custom cargo build-dir, see instead `cargo::cargo_bin!`" + )] fn cargo_bin>(name: S) -> Result; } impl CommandCargoExt for crate::cmd::Command { fn cargo_bin>(name: S) -> Result { + #[allow(deprecated)] crate::cmd::Command::cargo_bin(name) } } @@ -146,6 +151,7 @@ impl CommandCargoExt for process::Command { } pub(crate) fn cargo_bin_cmd>(name: S) -> Result { + #[allow(deprecated)] let path = cargo_bin(name); if path.is_file() { if let Some(runner) = cargo_runner() { @@ -229,6 +235,10 @@ fn target_dir() -> path::PathBuf { /// Look up the path to a cargo-built binary within an integration test. /// /// **NOTE:** Prefer [`cargo_bin!`] as this makes assumptions about cargo +#[deprecated( + since = "2.1.0", + note = "incompatible with a custom cargo build-dir, see instead `cargo::cargo_bin!`" +)] pub fn cargo_bin>(name: S) -> path::PathBuf { cargo_bin_str(name.as_ref()) } diff --git a/src/cmd.rs b/src/cmd.rs index e5a4058..3329543 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -60,6 +60,10 @@ impl Command { /// println!("{:?}", output); /// ``` /// + #[deprecated( + since = "2.1.0", + note = "incompatible with a custom cargo build-dir, see instead `cargo::cargo_bin_cmd!`" + )] pub fn cargo_bin>(name: S) -> Result { let cmd = crate::cargo::cargo_bin_cmd(name)?; Ok(Self::from_std(cmd)) diff --git a/tests/assert.rs b/tests/assert.rs index ec852f5..477370c 100644 --- a/tests/assert.rs +++ b/tests/assert.rs @@ -1,13 +1,13 @@ use std::process::Command; +use assert_cmd::cargo_bin; use assert_cmd::prelude::*; use predicates::prelude::*; #[test] fn stdout_string() { let expected = "hello\n".to_owned(); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() @@ -16,26 +16,25 @@ fn stdout_string() { #[test] fn trait_example() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); cmd.assert().success(); } #[test] fn trait_assert_example() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); cmd.assert().success(); } #[test] fn struct_example() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); cmd.assert().success(); } #[test] fn append_context_example() { - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .assert() .append_context("main", "no args") .success(); @@ -43,16 +42,12 @@ fn append_context_example() { #[test] fn success_example() { - Command::cargo_bin("bin_fixture") - .unwrap() - .assert() - .success(); + Command::new(cargo_bin!("bin_fixture")).assert().success(); } #[test] fn failure_example() { - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("exit", "1") .assert() .failure(); @@ -60,20 +55,17 @@ fn failure_example() { #[test] fn code_example() { - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("exit", "42") .assert() .code(predicate::eq(42)); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("exit", "42") .assert() .code(42); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("exit", "42") .assert() .code(&[2, 42] as &[i32]); @@ -81,36 +73,31 @@ fn code_example() { #[test] fn stdout_example() { - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stdout(predicate::eq(b"hello\n" as &[u8])); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stdout(predicate::str::diff("hello\n")); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stdout(b"hello\n" as &[u8]); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stdout(vec![b'h', b'e', b'l', b'l', b'o', b'\n']); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() @@ -119,36 +106,31 @@ fn stdout_example() { #[test] fn stderr_example() { - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stderr(predicate::eq(b"world\n" as &[u8])); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stderr(predicate::str::diff("world\n")); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stderr(b"world\n" as &[u8]); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() .stderr(vec![b'w', b'o', b'r', b'l', b'd', b'\n']); - Command::cargo_bin("bin_fixture") - .unwrap() + Command::new(cargo_bin!("bin_fixture")) .env("stdout", "hello") .env("stderr", "world") .assert() diff --git a/tests/cargo.rs b/tests/cargo.rs index 4861ad3..bf6d5c4 100644 --- a/tests/cargo.rs +++ b/tests/cargo.rs @@ -1,19 +1,19 @@ use std::process::Command; -use assert_cmd::pkg_name; +use assert_cmd::cargo_bin; use assert_cmd::prelude::*; use escargot::CURRENT_TARGET; #[test] fn cargo_binary() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); cmd.env("stdout", "42"); cmd.assert().success().stdout("42\n"); } #[test] fn cargo_binary_with_empty_env() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); cmd.env_clear().env("stdout", "42"); cmd.assert().success().stdout("42\n"); } @@ -39,25 +39,9 @@ fn mod_example() { } } -#[test] -#[should_panic] // No bin named `assert_cmd -fn trait_example() { - let mut cmd = Command::cargo_bin(pkg_name!()).unwrap(); - let output = cmd.unwrap(); - println!("{output:?}"); -} - -#[test] -#[should_panic] // No bin named `assert_cmd -fn cargo_bin_example_1() { - let mut cmd = Command::cargo_bin(pkg_name!()).unwrap(); - let output = cmd.unwrap(); - println!("{output:?}"); -} - #[test] fn cargo_bin_example_2() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = Command::new(cargo_bin!("bin_fixture")); let output = cmd.unwrap(); println!("{output:?}"); } diff --git a/tests/examples.rs b/tests/examples.rs index eca5df3..fadedca 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -1,11 +1,11 @@ -use assert_cmd::Command; +use assert_cmd::cargo::cargo_bin_cmd; #[test] fn lib_example() { - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = cargo_bin_cmd!("bin_fixture"); cmd.assert().success(); - let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let mut cmd = cargo_bin_cmd!("bin_fixture"); let assert = cmd .arg("-A") .env("stdout", "hello") @@ -17,10 +17,7 @@ fn lib_example() { #[test] fn timeout_example() { - use assert_cmd::Command; - - let assert = Command::cargo_bin("bin_fixture") - .unwrap() + let assert = cargo_bin_cmd!("bin_fixture") .timeout(std::time::Duration::from_secs(1)) .env("sleep", "100") .assert();