Skip to content

Commit 76ea0eb

Browse files
committed
feat(test): Make CARGO_BIN_EXE_ available at runtime
This also makes artifact deps available for consistency purposes. I originally proposed this for when moving Cargo off of Cargo's own internals but went with a different solution. Re-visiting this because `assert_cmd` has 2300+ dependents and it seems like making `assert_cmd::cargo_bin` work would be a better use of time than migrating all of those users to `assert_cmd::cargo_bin!`. For example, within the top 130 dependents (100,000 downloads or more), I found 66 that used `assert_cmd::cargo_bin` (rust-lang/rust#149852). > The reason to make `CARGO_BIN_EXE` set only at build-time was to > address the concern of manually running the test executable. > It's not > too common for tests to look at any runtime environment variables > (that I know of), so it usually just works (like running > `gdb target/debug/.../test-xxx`). > The concern was that if it were set at > runtime it would move more down the path where directly running the test > executable doesn't "just work". See https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/cargo_bin_exe.20and.20tests/near/513638220 However, - This is user opt-in - Users can run with `-vv` to see the env variables that are set - Users can run `CARGO_TARGET_..._RUNNER=gdb` - We can notify the `cargo nextest`, the main third-party test runner, about this. It should be easy to support as they have their own version of this, see https://nexte.st/docs/configuration/env-vars/?h=nextest_bin_exe#environment-variables-nextest-sets
1 parent 0705b7e commit 76ea0eb

File tree

5 files changed

+24
-9
lines changed

5 files changed

+24
-9
lines changed

src/cargo/core/compiler/build_runner/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,17 +316,17 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
316316
if unit.mode == CompileMode::Test {
317317
self.compilation
318318
.tests
319-
.push(self.unit_output(unit, &output.path));
319+
.push(self.unit_output(unit, &output.path)?);
320320
} else if unit.target.is_executable() {
321321
self.compilation
322322
.binaries
323-
.push(self.unit_output(unit, bindst));
323+
.push(self.unit_output(unit, bindst)?);
324324
} else if unit.target.is_cdylib()
325325
&& !self.compilation.cdylibs.iter().any(|uo| uo.unit == *unit)
326326
{
327327
self.compilation
328328
.cdylibs
329-
.push(self.unit_output(unit, bindst));
329+
.push(self.unit_output(unit, bindst)?);
330330
}
331331
}
332332
Ok(())
@@ -554,13 +554,15 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
554554

555555
/// Returns a [`UnitOutput`] which represents some information about the
556556
/// output of a unit.
557-
pub fn unit_output(&self, unit: &Unit, path: &Path) -> UnitOutput {
557+
pub fn unit_output(&self, unit: &Unit, path: &Path) -> CargoResult<UnitOutput> {
558558
let script_metas = self.find_build_script_metadatas(unit);
559-
UnitOutput {
559+
let env = artifact::get_env(&self, unit, self.unit_deps(unit))?;
560+
Ok(UnitOutput {
560561
unit: unit.clone(),
561562
path: path.to_path_buf(),
562563
script_metas,
563-
}
564+
env,
565+
})
564566
}
565567

566568
/// Check if any output file name collision happens.

src/cargo/core/compiler/compilation.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ pub struct UnitOutput {
6262
///
6363
/// This is used for indexing [`Compilation::extra_env`].
6464
pub script_metas: Option<Vec<UnitHash>>,
65+
66+
/// Environment variables to set in the unit's process.
67+
pub env: HashMap<String, OsString>,
6568
}
6669

6770
/// A structure returning the result of a compilation.

src/cargo/ops/cargo_run.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub fn run(
9797
unit,
9898
path,
9999
script_metas,
100+
env: _env,
100101
} = &compile.binaries[0];
101102
let exe = match path.strip_prefix(gctx.cwd()) {
102103
Ok(path) if path.file_name() == Some(path.as_os_str()) => Path::new(".").join(path),

src/cargo/ops/cargo_test.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::util::errors::CargoResult;
88
use crate::util::{CliError, CliResult, GlobalContext, add_path_args};
99
use anyhow::format_err;
1010
use cargo_util::{ProcessBuilder, ProcessError};
11+
use std::collections::HashMap;
1112
use std::ffi::OsString;
1213
use std::fmt::Write;
1314
use std::path::{Path, PathBuf};
@@ -126,6 +127,7 @@ fn run_unit_tests(
126127
unit,
127128
path,
128129
script_metas,
130+
env,
129131
} in compilation.tests.iter()
130132
{
131133
let (exe_display, mut cmd) = cmd_builds(
@@ -134,6 +136,7 @@ fn run_unit_tests(
134136
unit,
135137
path,
136138
script_metas.as_ref(),
139+
env,
137140
test_args,
138141
compilation,
139142
"unittests",
@@ -287,6 +290,7 @@ fn display_no_run_information(
287290
unit,
288291
path,
289292
script_metas,
293+
env,
290294
} in compilation.tests.iter()
291295
{
292296
let (exe_display, cmd) = cmd_builds(
@@ -295,6 +299,7 @@ fn display_no_run_information(
295299
unit,
296300
path,
297301
script_metas.as_ref(),
302+
env,
298303
test_args,
299304
compilation,
300305
exec_type,
@@ -319,6 +324,7 @@ fn cmd_builds(
319324
unit: &Unit,
320325
path: &PathBuf,
321326
script_metas: Option<&Vec<UnitHash>>,
327+
env: &HashMap<String, OsString>,
322328
test_args: &[&str],
323329
compilation: &Compilation<'_>,
324330
exec_type: &str,
@@ -348,6 +354,9 @@ fn cmd_builds(
348354
if unit.target.harness() && gctx.shell().verbosity() == Verbosity::Quiet {
349355
cmd.arg("--quiet");
350356
}
357+
for (key, val) in env.iter() {
358+
cmd.env(key, val);
359+
}
351360

352361
Ok((exe_display, cmd))
353362
}

tests/testsuite/test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,9 +5216,9 @@ fn bin_env_for_test() {
52165216
assert_eq!(env!("CARGO_BIN_EXE_foo"), "<FOO_PATH>");
52175217
assert_eq!(env!("CARGO_BIN_EXE_with-dash"), "<WITH_DASH_PATH>");
52185218
assert_eq!(env!("CARGO_BIN_EXE_grüßen"), "<GRÜSSEN_PATH>");
5219-
assert_eq!(std::env::var("CARGO_BIN_EXE_foo").ok(), None);
5220-
assert_eq!(std::env::var("CARGO_BIN_EXE_with-dash").ok(), None);
5221-
assert_eq!(std::env::var("CARGO_BIN_EXE_grüßen").ok(), None);
5219+
assert_eq!(std::env::var("CARGO_BIN_EXE_foo").ok().as_deref(), Some("<FOO_PATH>"));
5220+
assert_eq!(std::env::var("CARGO_BIN_EXE_with-dash").ok().as_deref(), Some("<WITH_DASH_PATH>"));
5221+
assert_eq!(std::env::var("CARGO_BIN_EXE_grüßen").ok().as_deref(), Some("<GRÜSSEN_PATH>"));
52225222
}
52235223
"#
52245224
.replace("<FOO_PATH>", &bin_path("foo"))

0 commit comments

Comments
 (0)