Skip to content

Commit f91dc78

Browse files
committed
fix(env):Get environment variables from the latest environment config
1 parent e0f523a commit f91dc78

File tree

3 files changed

+75
-51
lines changed

3 files changed

+75
-51
lines changed

src/cargo/core/compiler/build_context/target_info.rs

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use cargo_util::{paths, ProcessBuilder};
2121
use serde::{Deserialize, Serialize};
2222
use std::cell::RefCell;
2323
use std::collections::hash_map::{Entry, HashMap};
24+
use std::collections::BTreeMap;
25+
use std::ffi::OsString;
2426
use std::path::{Path, PathBuf};
2527
use std::str::{self, FromStr};
2628

@@ -588,6 +590,10 @@ impl TargetInfo {
588590
.iter()
589591
.any(|sup| sup.as_str() == split.as_str())
590592
}
593+
594+
pub fn get_target_envs(&self) -> &BTreeMap<String, Option<OsString>> {
595+
return self.crate_type_process.get_envs();
596+
}
591597
}
592598

593599
/// Takes rustc output (using specialized command line args), and calculates the file prefix and

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

+43-8
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ mod dirty_reason;
357357

358358
use std::collections::hash_map::{Entry, HashMap};
359359

360+
use std::collections::BTreeMap;
360361
use std::env;
362+
use std::ffi::OsString;
361363
use std::hash::{self, Hash, Hasher};
362364
use std::io;
363365
use std::path::{Path, PathBuf};
@@ -768,14 +770,35 @@ pub enum StaleItem {
768770
impl LocalFingerprint {
769771
/// Read the environment variable of the given env `key`, and creates a new
770772
/// [`LocalFingerprint::RerunIfEnvChanged`] for it.
771-
///
772-
// TODO: This is allowed at this moment. Should figure out if it makes
773-
// sense if permitting to read env from the config system.
774773
#[allow(clippy::disallowed_methods)]
775-
fn from_env<K: AsRef<str>>(key: K) -> LocalFingerprint {
776-
let key = key.as_ref();
774+
fn from_env<K: AsRef<str>>(
775+
key: K,
776+
envs: &BTreeMap<String, Option<OsString>>,
777+
) -> LocalFingerprint {
778+
fn get_envs_case_insensitive(
779+
key: &str,
780+
envs: &BTreeMap<String, Option<OsString>>,
781+
) -> Option<OsString> {
782+
let upper_case_key: String = key.to_uppercase();
783+
for (k, v) in envs {
784+
if k.to_uppercase().eq(&upper_case_key) {
785+
return v.to_owned();
786+
}
787+
}
788+
None
789+
}
790+
791+
let key: &str = key.as_ref();
777792
let var = key.to_owned();
778-
let val = env::var(key).ok();
793+
794+
let val: Option<String> = if cfg!(windows) {
795+
get_envs_case_insensitive(key, envs)
796+
} else {
797+
envs.get(key).and_then(|v| v.to_owned())
798+
}
799+
.or(env::var_os(key))
800+
.and_then(|os_str| os_str.into_string().ok());
801+
779802
LocalFingerprint::RerunIfEnvChanged { var, val }
780803
}
781804

@@ -1608,6 +1631,12 @@ fn build_script_local_fingerprints(
16081631
bool,
16091632
) {
16101633
assert!(unit.mode.is_run_custom_build());
1634+
let envs = build_runner
1635+
.bcx
1636+
.target_data
1637+
.info(unit.kind)
1638+
.get_target_envs()
1639+
.clone();
16111640
// First up, if this build script is entirely overridden, then we just
16121641
// return the hash of what we overrode it with. This is the easy case!
16131642
if let Some(fingerprint) = build_script_override_fingerprint(build_runner, unit) {
@@ -1660,7 +1689,12 @@ fn build_script_local_fingerprints(
16601689
// Ok so now we're in "new mode" where we can have files listed as
16611690
// dependencies as well as env vars listed as dependencies. Process
16621691
// them all here.
1663-
Ok(Some(local_fingerprints_deps(deps, &target_dir, &pkg_root)))
1692+
Ok(Some(local_fingerprints_deps(
1693+
deps,
1694+
&target_dir,
1695+
&pkg_root,
1696+
&envs,
1697+
)))
16641698
};
16651699

16661700
// Note that `false` == "not overridden"
@@ -1695,6 +1729,7 @@ fn local_fingerprints_deps(
16951729
deps: &BuildDeps,
16961730
target_root: &Path,
16971731
pkg_root: &Path,
1732+
envs: &BTreeMap<String, Option<OsString>>,
16981733
) -> Vec<LocalFingerprint> {
16991734
debug!("new local fingerprints deps {:?}", pkg_root);
17001735
let mut local = Vec::new();
@@ -1719,7 +1754,7 @@ fn local_fingerprints_deps(
17191754
local.extend(
17201755
deps.rerun_if_env_changed
17211756
.iter()
1722-
.map(LocalFingerprint::from_env),
1757+
.map(|v| LocalFingerprint::from_env(v, &envs)),
17231758
);
17241759

17251760
local

tests/testsuite/build_script_env.rs

+26-43
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ fn rerun_if_env_changes_config() {
2020
.file(
2121
"build.rs",
2222
r#"
23-
fn main() {
24-
println!("cargo:rerun-if-env-changed=FOO");
25-
if let Ok(foo) = std::env::var("FOO") {
26-
assert!(&foo != "bad");
27-
}
28-
}
29-
"#,
23+
fn main() {
24+
println!("cargo:rerun-if-env-changed=FOO");
25+
if let Ok(foo) = std::env::var("FOO") {
26+
assert!(&foo != "bad");
27+
}
28+
}
29+
"#,
3030
)
3131
.build();
3232

@@ -47,47 +47,38 @@ fn rerun_if_env_changes_config() {
4747
);
4848

4949
p.cargo("check")
50+
.with_status(101)
5051
.with_stderr_data(str![[r#"
51-
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
52-
52+
[COMPILING] foo v0.1.0 ([ROOT]/foo)
53+
[ERROR] failed to run custom build command for `foo v0.1.0 ([ROOT]/foo)`
54+
...
5355
"#]])
5456
.run();
55-
56-
p.cargo("clean").run();
57-
p.cargo("check")
58-
.with_status(101)
59-
.with_stderr_data(
60-
"\
61-
[COMPILING] foo v0.1.0 ([ROOT]/foo)
62-
[ERROR] failed to run custom build command for `foo v0.1.0 ([..])`
63-
...",
64-
)
65-
.run();
6657
}
6758

6859
#[cfg(windows)]
6960
#[cargo_test]
70-
fn rerun_if_env_changes_config_windows() {
61+
fn rerun_if_env_changes_config_in_windows() {
7162
let p = project()
7263
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
7364
.file("src/main.rs", "fn main() {}")
7465
.file(
7566
".cargo/config.toml",
7667
r#"
7768
[env]
78-
FOO = "good"
69+
Foo = "good"
7970
"#,
8071
)
8172
.file(
8273
"build.rs",
8374
r#"
84-
fn main() {
85-
println!("cargo:rerun-if-env-changed=Foo");
86-
if let Ok(foo) = std::env::var("Foo") {
87-
assert!(&foo != "bad");
88-
}
89-
}
90-
"#,
75+
fn main() {
76+
println!("cargo:rerun-if-env-changed=foo");
77+
if let Ok(foo) = std::env::var("FOo") {
78+
assert!(&foo != "bad");
79+
}
80+
}
81+
"#,
9182
)
9283
.build();
9384

@@ -103,26 +94,17 @@ fn rerun_if_env_changes_config_windows() {
10394
".cargo/config.toml",
10495
r#"
10596
[env]
106-
FOO = "bad"
97+
FoO = "bad"
10798
"#,
10899
);
109100

110-
p.cargo("check")
111-
.with_stderr_data(str![[r#"
112-
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
113-
114-
"#]])
115-
.run();
116-
117-
p.cargo("clean").run();
118101
p.cargo("check")
119102
.with_status(101)
120-
.with_stderr_data(
121-
"\
103+
.with_stderr_data(str![[r#"
122104
[COMPILING] foo v0.1.0 ([ROOT]/foo)
123-
[ERROR] failed to run custom build command for `foo v0.1.0 ([..])`
124-
...",
125-
)
105+
[ERROR] failed to run custom build command for `foo v0.1.0 ([ROOT]/foo)`
106+
...
107+
"#]])
126108
.run();
127109
}
128110

@@ -158,6 +140,7 @@ fn rerun_if_env_changes_cargo_set_env_variable() {
158140

159141
p.cargo("check")
160142
.with_stderr_data(str![[r#"
143+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
161144
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
162145
163146
"#]])

0 commit comments

Comments
 (0)