Skip to content

Commit 0ce1d7d

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

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

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

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ use std::time::SystemTime;
376376
use anyhow::{bail, format_err, Context as _};
377377
use cargo_util::{paths, ProcessBuilder, Sha256};
378378
use filetime::FileTime;
379+
use lazycell::LazyCell;
379380
use serde::de;
380381
use serde::ser;
381382
use serde::{Deserialize, Serialize};
@@ -792,14 +793,36 @@ pub enum StaleItem {
792793
impl LocalFingerprint {
793794
/// Read the environment variable of the given env `key`, and creates a new
794795
/// [`LocalFingerprint::RerunIfEnvChanged`] for it.
795-
///
796-
// TODO: This is allowed at this moment. Should figure out if it makes
797-
// sense if permitting to read env from the config system.
798796
#[allow(clippy::disallowed_methods)]
799-
fn from_env<K: AsRef<str>>(key: K) -> LocalFingerprint {
797+
fn from_env<K: AsRef<str>>(
798+
key: K,
799+
env_config: &Arc<HashMap<String, OsString>>,
800+
env_config_insensitive: &Arc<LazyCell<HashMap<String, OsString>>>,
801+
) -> LocalFingerprint {
800802
let key = key.as_ref();
801803
let var = key.to_owned();
802-
let val = env::var(key).ok();
804+
let val = if let Some(val) = env::var(key).ok() {
805+
Some(val)
806+
} else {
807+
match env_config.get(key) {
808+
Some(value) => value.to_str().map(|s| s.to_string()),
809+
None => {
810+
if cfg!(windows) {
811+
env_config_insensitive
812+
.borrow_with(|| {
813+
env_config
814+
.iter()
815+
.map(|(k, v)| (k.to_uppercase().clone(), v.clone()))
816+
.collect::<HashMap<String, OsString>>()
817+
})
818+
.get(&key.to_uppercase())
819+
.and_then(|s| s.to_str().map(|s| s.to_string()))
820+
} else {
821+
None
822+
}
823+
}
824+
}
825+
};
803826
LocalFingerprint::RerunIfEnvChanged { var, val }
804827
}
805828

@@ -1697,6 +1720,7 @@ fn build_script_local_fingerprints(
16971720
// obvious.
16981721
let pkg_root = unit.pkg.root().to_path_buf();
16991722
let target_dir = target_root(build_runner);
1723+
let env_config = Arc::clone(build_runner.bcx.gctx.env_config().unwrap());
17001724
let calculate =
17011725
move |deps: &BuildDeps, pkg_fingerprint: Option<&dyn Fn() -> CargoResult<String>>| {
17021726
if deps.rerun_if_changed.is_empty() && deps.rerun_if_env_changed.is_empty() {
@@ -1726,7 +1750,12 @@ fn build_script_local_fingerprints(
17261750
// Ok so now we're in "new mode" where we can have files listed as
17271751
// dependencies as well as env vars listed as dependencies. Process
17281752
// them all here.
1729-
Ok(Some(local_fingerprints_deps(deps, &target_dir, &pkg_root)))
1753+
Ok(Some(local_fingerprints_deps(
1754+
deps,
1755+
&target_dir,
1756+
&pkg_root,
1757+
&env_config,
1758+
)))
17301759
};
17311760

17321761
// Note that `false` == "not overridden"
@@ -1761,6 +1790,7 @@ fn local_fingerprints_deps(
17611790
deps: &BuildDeps,
17621791
target_root: &Path,
17631792
pkg_root: &Path,
1793+
env_config: &Arc<HashMap<String, OsString>>,
17641794
) -> Vec<LocalFingerprint> {
17651795
debug!("new local fingerprints deps {:?}", pkg_root);
17661796
let mut local = Vec::new();
@@ -1781,11 +1811,11 @@ fn local_fingerprints_deps(
17811811
.collect();
17821812
local.push(LocalFingerprint::RerunIfChanged { output, paths });
17831813
}
1784-
1814+
let env_config_insensitive = Arc::new(LazyCell::new());
17851815
local.extend(
17861816
deps.rerun_if_env_changed
17871817
.iter()
1788-
.map(LocalFingerprint::from_env),
1818+
.map(|s| LocalFingerprint::from_env(s, env_config, &env_config_insensitive)),
17891819
);
17901820

17911821
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)