@@ -364,6 +364,7 @@ mod dirty_reason;
364364
365365use std:: collections:: hash_map:: { Entry , HashMap } ;
366366use std:: env;
367+ use std:: ffi:: OsString ;
367368use std:: fs;
368369use std:: fs:: File ;
369370use std:: hash:: { self , Hash , Hasher } ;
@@ -376,6 +377,7 @@ use anyhow::format_err;
376377use anyhow:: Context as _;
377378use cargo_util:: paths;
378379use filetime:: FileTime ;
380+ use lazycell:: LazyCell ;
379381use serde:: de;
380382use serde:: ser;
381383use serde:: { Deserialize , Serialize } ;
@@ -796,14 +798,36 @@ pub enum StaleItem {
796798impl 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
0 commit comments