Skip to content

Commit 8eb9358

Browse files
authored
Rollup merge of rust-lang#139507 - Zalathar:trim-env-name, r=jieyouxu
compiletest: Trim whitespace from environment variable names When a test contains a directive like `//@ exec-env: FOO=bar`, compiletest currently includes that leading space in the name of the environment variable, so it is defined as ` FOO` instead of `FOO`. This is an annoying footgun that is pretty much never intended, especially since most other directives *do* trim whitespace. So let's get rid of it by trimming the environment variable name. Values remain untrimmed, since there could conceivably be a use-case for values with leading space, but perhaps we'll end up trimming values too in the future. Recently observed in rust-lang#138603 (comment). Fixes rust-lang#132990. Supersedes rust-lang#133148. --- try-job: test-various
2 parents 8ec3cda + 34e9759 commit 8eb9358

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

src/tools/compiletest/src/header.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ impl TestProps {
452452
ln,
453453
UNSET_EXEC_ENV,
454454
&mut self.unset_exec_env,
455-
|r| r,
455+
|r| r.trim().to_owned(),
456456
);
457457
config.push_name_value_directive(
458458
ln,
@@ -464,7 +464,7 @@ impl TestProps {
464464
ln,
465465
UNSET_RUSTC_ENV,
466466
&mut self.unset_rustc_env,
467-
|r| r,
467+
|r| r.trim().to_owned(),
468468
);
469469
config.push_name_value_directive(
470470
ln,
@@ -997,16 +997,13 @@ impl Config {
997997

998998
fn parse_env(nv: String) -> (String, String) {
999999
// nv is either FOO or FOO=BAR
1000-
let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
1001-
1002-
match strs.len() {
1003-
1 => (strs.pop().unwrap(), String::new()),
1004-
2 => {
1005-
let end = strs.pop().unwrap();
1006-
(strs.pop().unwrap(), end)
1007-
}
1008-
n => panic!("Expected 1 or 2 strings, not {}", n),
1009-
}
1000+
// FIXME(Zalathar): The form without `=` seems to be unused; should
1001+
// we drop support for it?
1002+
let (name, value) = nv.split_once('=').unwrap_or((&nv, ""));
1003+
// Trim whitespace from the name, so that `//@ exec-env: FOO=BAR`
1004+
// sees the name as `FOO` and not ` FOO`.
1005+
let name = name.trim();
1006+
(name.to_owned(), value.to_owned())
10101007
}
10111008

10121009
fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {

src/tools/compiletest/src/runtest.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -968,16 +968,16 @@ impl<'test> TestCx<'test> {
968968
delete_after_success: bool,
969969
) -> ProcRes {
970970
let prepare_env = |cmd: &mut Command| {
971-
for key in &self.props.unset_exec_env {
972-
cmd.env_remove(key);
973-
}
974-
975971
for (key, val) in &self.props.exec_env {
976972
cmd.env(key, val);
977973
}
978974
for (key, val) in env_extra {
979975
cmd.env(key, val);
980976
}
977+
978+
for key in &self.props.unset_exec_env {
979+
cmd.env_remove(key);
980+
}
981981
};
982982

983983
let proc_res = match &*self.config.target {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ edition: 2024
2+
//@ revisions: set unset
3+
//@ run-pass
4+
//@ ignore-cross-compile (assume that non-cross targets have working env vars)
5+
//@ rustc-env: MY_RUSTC_ENV = my-rustc-value
6+
//@ exec-env: MY_EXEC_ENV = my-exec-value
7+
//@[unset] unset-rustc-env: MY_RUSTC_ENV
8+
//@[unset] unset-exec-env: MY_EXEC_ENV
9+
10+
// Check that compiletest trims whitespace from environment variable names
11+
// specified in `rustc-env` and `exec-env` directives, so that
12+
// `//@ exec-env: FOO=bar` sees the name as `FOO` and not ` FOO`.
13+
//
14+
// Values are currently not trimmed.
15+
//
16+
// Since this is a compiletest self-test, only run it on non-cross targets,
17+
// to avoid having to worry about weird targets that don't support env vars.
18+
19+
fn main() {
20+
let is_set = cfg!(set);
21+
assert_eq!(option_env!("MY_RUSTC_ENV"), is_set.then_some(" my-rustc-value"));
22+
assert_eq!(std::env::var("MY_EXEC_ENV").ok().as_deref(), is_set.then_some(" my-exec-value"));
23+
}

0 commit comments

Comments
 (0)