Skip to content

Commit ba24555

Browse files
committed
fix: envs in config can trigger rebuild by custom build script with rerun-if-env-changed.
1 parent 475f6dc commit ba24555

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

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

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ mod dirty_reason;
364364

365365
use std::collections::hash_map::{Entry, HashMap};
366366
use std::env;
367+
use std::ffi::OsString;
367368
use std::fs;
368369
use std::fs::File;
369370
use std::hash::{self, Hash, Hasher};
@@ -376,6 +377,7 @@ use anyhow::format_err;
376377
use anyhow::Context as _;
377378
use cargo_util::paths;
378379
use filetime::FileTime;
380+
use lazycell::LazyCell;
379381
use serde::de;
380382
use serde::ser;
381383
use serde::{Deserialize, Serialize};
@@ -796,14 +798,36 @@ pub enum StaleItem {
796798
impl LocalFingerprint {
797799
/// Read the environment variable of the given env `key`, and creates a new
798800
/// [`LocalFingerprint::RerunIfEnvChanged`] for it.
799-
///
800-
// TODO: This is allowed at this moment. Should figure out if it makes
801-
// sense if permitting to read env from the config system.
802801
#[allow(clippy::disallowed_methods)]
803-
fn from_env<K: AsRef<str>>(key: K) -> LocalFingerprint {
802+
fn from_env<K: AsRef<str>>(
803+
key: K,
804+
env_config: &Arc<HashMap<String, OsString>>,
805+
env_config_insensitive: &Arc<LazyCell<HashMap<String, OsString>>>,
806+
) -> LocalFingerprint {
804807
let key = key.as_ref();
805808
let var = key.to_owned();
806-
let val = env::var(key).ok();
809+
let val = if let Some(val) = env::var(key).ok() {
810+
Some(val)
811+
} else {
812+
match env_config.get(key) {
813+
Some(value) => value.to_str().map(|s| s.to_string()),
814+
None => {
815+
if cfg!(windows) {
816+
env_config_insensitive
817+
.borrow_with(|| {
818+
env_config
819+
.iter()
820+
.map(|(k, v)| (k.to_uppercase().clone(), v.clone()))
821+
.collect::<HashMap<String, OsString>>()
822+
})
823+
.get(&key.to_uppercase())
824+
.and_then(|s| s.to_str().map(|s| s.to_string()))
825+
} else {
826+
None
827+
}
828+
}
829+
}
830+
};
807831
LocalFingerprint::RerunIfEnvChanged { var, val }
808832
}
809833

@@ -1701,6 +1725,7 @@ fn build_script_local_fingerprints(
17011725
// obvious.
17021726
let pkg_root = unit.pkg.root().to_path_buf();
17031727
let target_dir = target_root(build_runner);
1728+
let env_config = Arc::clone(build_runner.bcx.gctx.env_config().unwrap());
17041729
let calculate =
17051730
move |deps: &BuildDeps, pkg_fingerprint: Option<&dyn Fn() -> CargoResult<String>>| {
17061731
if deps.rerun_if_changed.is_empty() && deps.rerun_if_env_changed.is_empty() {
@@ -1730,7 +1755,12 @@ fn build_script_local_fingerprints(
17301755
// Ok so now we're in "new mode" where we can have files listed as
17311756
// dependencies as well as env vars listed as dependencies. Process
17321757
// them all here.
1733-
Ok(Some(local_fingerprints_deps(deps, &target_dir, &pkg_root)))
1758+
Ok(Some(local_fingerprints_deps(
1759+
deps,
1760+
&target_dir,
1761+
&pkg_root,
1762+
&env_config,
1763+
)))
17341764
};
17351765

17361766
// Note that `false` == "not overridden"
@@ -1765,6 +1795,7 @@ fn local_fingerprints_deps(
17651795
deps: &BuildDeps,
17661796
target_root: &Path,
17671797
pkg_root: &Path,
1798+
env_config: &Arc<HashMap<String, OsString>>,
17681799
) -> Vec<LocalFingerprint> {
17691800
debug!("new local fingerprints deps {:?}", pkg_root);
17701801
let mut local = Vec::new();
@@ -1785,11 +1816,11 @@ fn local_fingerprints_deps(
17851816
.collect();
17861817
local.push(LocalFingerprint::RerunIfChanged { output, paths });
17871818
}
1788-
1819+
let env_config_insensitive = Arc::new(LazyCell::new());
17891820
local.extend(
17901821
deps.rerun_if_env_changed
17911822
.iter()
1792-
.map(LocalFingerprint::from_env),
1823+
.map(|s| LocalFingerprint::from_env(s, env_config, &env_config_insensitive)),
17931824
);
17941825

17951826
local

tests/testsuite/build_script_env.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ fn env_config_rerun_if_changed() {
422422
);
423423
p.cargo("check")
424424
.with_stderr_data(str![[r#"
425+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
425426
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
426427
427428
"#]])
@@ -473,6 +474,7 @@ fn insensitive_env_config_rerun_if_changed() {
473474
);
474475
p.cargo("check")
475476
.with_stderr_data(str![[r#"
477+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
476478
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
477479
478480
"#]])
@@ -516,6 +518,7 @@ fn env_config_newly_added_rerun() {
516518
);
517519
p.cargo("check")
518520
.with_stderr_data(str![[r#"
521+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
519522
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
520523
521524
"#]])

0 commit comments

Comments
 (0)