Skip to content

Commit af564b2

Browse files
committed
Auto merge of #9169 - Liberatys:emit-warning-on-env-variable-case-mismatch, r=ehuss
Emit warning on env variable case mismatch When running a command like `cargo --target TRIPPLE` cargo expects to find the environment variable CARGO_TARGET_[TRIPPLE]_* with uppercase and underscores. This check emits a warning if the checked environment variable has a mismatching case and/or contains dashes rather than underscores. The warning contains the given env variable as well as an explanation for the cause of the warning. The check is skipped on windows as environment variables are treated as case insensitive on the platform. Fixes #8285
2 parents 8fa0827 + 0564466 commit af564b2

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

src/cargo/util/config/mod.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ pub struct Config {
167167
target_dir: Option<Filesystem>,
168168
/// Environment variables, separated to assist testing.
169169
env: HashMap<String, String>,
170+
/// Environment variables, converted to uppercase to check for case mismatch
171+
upper_case_env: HashMap<String, String>,
170172
/// Tracks which sources have been updated to avoid multiple updates.
171173
updated_sources: LazyCell<RefCell<HashSet<SourceId>>>,
172174
/// Lock, if held, of the global package cache along with the number of
@@ -211,6 +213,15 @@ impl Config {
211213
})
212214
.collect();
213215

216+
let upper_case_env = if cfg!(windows) {
217+
HashMap::new()
218+
} else {
219+
env.clone()
220+
.into_iter()
221+
.map(|(k, _)| (k.to_uppercase().replace("-", "_"), k))
222+
.collect()
223+
};
224+
214225
let cache_rustc_info = match env.get("CARGO_CACHE_RUSTC_INFO") {
215226
Some(cache) => cache != "0",
216227
_ => true,
@@ -244,6 +255,7 @@ impl Config {
244255
creation_time: Instant::now(),
245256
target_dir: None,
246257
env,
258+
upper_case_env,
247259
updated_sources: LazyCell::new(),
248260
package_cache_lock: RefCell::new(None),
249261
http_config: LazyCell::new(),
@@ -525,7 +537,10 @@ impl Config {
525537
definition,
526538
}))
527539
}
528-
None => Ok(None),
540+
None => {
541+
self.check_environment_key_case_mismatch(key);
542+
Ok(None)
543+
}
529544
}
530545
}
531546

@@ -545,9 +560,27 @@ impl Config {
545560
return true;
546561
}
547562
}
563+
self.check_environment_key_case_mismatch(key);
564+
548565
false
549566
}
550567

568+
fn check_environment_key_case_mismatch(&self, key: &ConfigKey) {
569+
if cfg!(windows) {
570+
// In the case of windows the check for case mismatch in keys can be skipped
571+
// as windows already converts its environment keys into the desired format.
572+
return;
573+
}
574+
575+
if let Some(env_key) = self.upper_case_env.get(key.as_env_key()) {
576+
let _ = self.shell().warn(format!(
577+
"Environment variables are expected to use uppercase letters and underscores, \
578+
the variable `{}` will be ignored and have no effect",
579+
env_key
580+
));
581+
}
582+
}
583+
551584
/// Get a string config value.
552585
///
553586
/// See `get` for more details.
@@ -640,7 +673,10 @@ impl Config {
640673
) -> CargoResult<()> {
641674
let env_val = match self.env.get(key.as_env_key()) {
642675
Some(v) => v,
643-
None => return Ok(()),
676+
None => {
677+
self.check_environment_key_case_mismatch(key);
678+
return Ok(());
679+
}
644680
};
645681

646682
let def = Definition::Environment(key.as_env_key().to_string());

tests/testsuite/tool_paths.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,31 @@ fn custom_linker_env() {
353353
.run();
354354
}
355355

356+
#[cargo_test]
357+
fn target_in_environment_contains_lower_case() {
358+
let p = project().file("src/main.rs", "fn main() {}").build();
359+
360+
let target_keys = [
361+
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_musl_LINKER",
362+
"CARGO_TARGET_x86_64_unknown_linux_musl_LINKER",
363+
];
364+
365+
for target_key in &target_keys {
366+
let mut execs = p.cargo("build -v --target x86_64-unknown-linux-musl");
367+
execs.env(target_key, "nonexistent-linker").with_status(101);
368+
if cfg!(windows) {
369+
execs.with_stderr_does_not_contain("warning:[..]");
370+
} else {
371+
execs.with_stderr_contains(format!(
372+
"warning: Environment variables are expected to use uppercase letters and underscores, \
373+
the variable `{}` will be ignored and have no effect",
374+
target_key
375+
));
376+
}
377+
execs.run();
378+
}
379+
}
380+
356381
#[cargo_test]
357382
fn cfg_ignored_fields() {
358383
// Test for some ignored fields in [target.'cfg()'] tables.

0 commit comments

Comments
 (0)