@@ -5,8 +5,66 @@ use std::{
55 str:: FromStr ,
66} ;
77
8+ #[ cfg( windows) ]
9+ use std:: { hash:: { Hash , Hasher } , fmt} ;
10+
11+ #[ cfg( windows) ]
12+ #[ derive( Clone ) ]
13+ pub struct CaseInsensitiveKey ( pub String ) ;
14+
15+ #[ cfg( windows) ]
16+ impl PartialEq for CaseInsensitiveKey {
17+ fn eq ( & self , other : & Self ) -> bool {
18+ self . 0 . eq_ignore_ascii_case ( & other. 0 )
19+ }
20+ }
21+
22+ #[ cfg( windows) ]
23+ impl fmt:: Display for CaseInsensitiveKey {
24+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
25+ write ! ( f, "{}" , self . 0 )
26+ }
27+ }
28+
29+ #[ cfg( windows) ]
30+ impl Eq for CaseInsensitiveKey { }
31+
32+ #[ cfg( windows) ]
33+ impl Hash for CaseInsensitiveKey {
34+ fn hash < H : Hasher > ( & self , state : & mut H ) {
35+ self . 0 . to_lowercase ( ) . hash ( state) ;
36+ }
37+ }
38+
39+ #[ cfg( windows) ]
40+ impl fmt:: Debug for CaseInsensitiveKey {
41+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
42+ write ! ( f, "{:?}" , self . 0 )
43+ }
44+ }
45+
46+ #[ cfg( windows) ]
47+ pub type PlatformCaseAwareEnvKey = CaseInsensitiveKey ;
48+ #[ cfg( not( windows) ) ]
49+ pub type PlatformCaseAwareEnvKey = String ;
50+
51+ #[ cfg( windows) ]
52+ pub fn construct_platform_case_aware_env_key ( key : String ) -> PlatformCaseAwareEnvKey {
53+ CaseInsensitiveKey ( key)
54+ }
55+
56+ #[ cfg( not( windows) ) ]
57+ pub fn construct_platform_case_aware_env_key ( key : String ) -> PlatformCaseAwareEnvKey {
58+ key
59+ }
60+
861use crate :: types:: Installation ;
962
63+ #[ cfg( not( windows) ) ]
64+ const SEP : & str = ":" ;
65+ #[ cfg( windows) ]
66+ const SEP : & str = ";" ;
67+
1068pub fn map ( installations : & Vec < Installation > ) -> HashMap < String , Vec < String > > {
1169 let mut vars: HashMap < EnvKey , OrderedSet < PathBuf > > = HashMap :: new ( ) ;
1270
@@ -42,7 +100,9 @@ pub fn map(installations: &Vec<Installation>) -> HashMap<String, Vec<String>> {
42100 . unwrap ( )
43101 . add ( PathBuf :: from_str ( "/usr/share/man" ) . unwrap ( ) ) ;
44102 }
103+
45104 // https://github.com/pkgxdev/libpkgx/issues/70
105+ #[ cfg( unix) ]
46106 if vars. contains_key ( & EnvKey :: XdgDataDirs ) {
47107 let set = vars. get_mut ( & EnvKey :: XdgDataDirs ) . unwrap ( ) ;
48108 set. add ( PathBuf :: from_str ( "/usr/local/share" ) . unwrap ( ) ) ;
@@ -71,17 +131,25 @@ enum EnvKey {
71131 Path ,
72132 Manpath ,
73133 PkgConfigPath ,
134+ #[ cfg( unix) ]
74135 LibraryPath ,
136+ #[ cfg( unix) ]
75137 LdLibraryPath ,
138+ #[ cfg( unix) ]
76139 Cpath ,
77140 XdgDataDirs ,
78141 CmakePrefixPath ,
79142 #[ cfg( target_os = "macos" ) ]
80143 DyldFallbackLibraryPath ,
81144 SslCertFile ,
145+ #[ cfg( unix) ]
82146 Ldflags ,
83147 PkgxDir ,
84148 AclocalPath ,
149+ #[ cfg( windows) ]
150+ Lib ,
151+ #[ cfg( windows) ]
152+ Include ,
85153}
86154
87155struct OrderedSet < T : Eq + std:: hash:: Hash + Clone > {
@@ -111,44 +179,58 @@ fn suffixes(key: &EnvKey) -> Option<Vec<&'static str>> {
111179 EnvKey :: PkgConfigPath => Some ( vec ! [ "share/pkgconfig" , "lib/pkgconfig" ] ) ,
112180 EnvKey :: XdgDataDirs => Some ( vec ! [ "share" ] ) ,
113181 EnvKey :: AclocalPath => Some ( vec ! [ "share/aclocal" ] ) ,
182+ #[ cfg( unix) ]
114183 EnvKey :: LibraryPath | EnvKey :: LdLibraryPath => Some ( vec ! [ "lib" , "lib64" ] ) ,
115184 #[ cfg( target_os = "macos" ) ]
116185 EnvKey :: DyldFallbackLibraryPath => Some ( vec ! [ "lib" , "lib64" ] ) ,
186+ #[ cfg( unix) ]
117187 EnvKey :: Cpath => Some ( vec ! [ "include" ] ) ,
118- EnvKey :: CmakePrefixPath | EnvKey :: SslCertFile | EnvKey :: Ldflags | EnvKey :: PkgxDir => None ,
188+ EnvKey :: CmakePrefixPath | EnvKey :: SslCertFile | EnvKey :: PkgxDir => None ,
189+ #[ cfg( unix) ]
190+ EnvKey :: Ldflags => None ,
191+ #[ cfg( windows) ]
192+ EnvKey :: Lib => Some ( vec ! [ "lib" ] ) ,
193+ #[ cfg( windows) ]
194+ EnvKey :: Include => Some ( vec ! [ "include" ] ) ,
119195 }
120196}
121197
122- pub fn mix ( input : HashMap < String , Vec < String > > ) -> HashMap < String , String > {
123- let mut rv = HashMap :: from_iter ( std:: env:: vars ( ) ) ;
198+ pub fn mix ( input : HashMap < String , Vec < String > > ) -> HashMap < PlatformCaseAwareEnvKey , String > {
199+ let mut rv: HashMap < PlatformCaseAwareEnvKey , String > = HashMap :: new ( ) ;
200+
201+ for ( key, value) in std:: env:: vars ( ) {
202+ rv. insert ( construct_platform_case_aware_env_key ( key) , value) ;
203+ }
124204
125205 for ( key, value) in input. iter ( ) {
206+ let key = & construct_platform_case_aware_env_key ( key. clone ( ) ) ;
126207 if let Some ( values) = rv. get ( key) {
127- rv. insert ( key. clone ( ) , format ! ( "{}:{} " , value. join( ":" ) , values) ) ;
208+ rv. insert ( key. clone ( ) , format ! ( "{}{}{} " , value. join( SEP ) , SEP , values) ) ;
128209 } else {
129- rv. insert ( key. clone ( ) , value. join ( ":" ) ) ;
210+ rv. insert ( key. clone ( ) , value. join ( SEP ) ) ;
130211 }
131212 }
132213
133214 rv
134215}
135216
136217pub fn mix_runtime (
137- input : & HashMap < String , String > ,
218+ input : & HashMap < PlatformCaseAwareEnvKey , String > ,
138219 installations : & Vec < Installation > ,
139220 conn : & Connection ,
140- ) -> Result < HashMap < String , String > , Box < dyn Error > > {
141- let mut output: HashMap < String , String > = input
221+ ) -> Result < HashMap < PlatformCaseAwareEnvKey , String > , Box < dyn Error > > {
222+ let mut output: HashMap < PlatformCaseAwareEnvKey , String > = input
142223 . iter ( )
143- . map ( |( k, v) | ( k. clone ( ) , format ! ( "{}: ${}" , v, k) ) )
224+ . map ( |( k, v) | ( k. clone ( ) , format ! ( "{}{} ${}" , v, SEP , k) ) )
144225 . collect ( ) ;
145226
146227 for installation in installations. clone ( ) {
147228 let runtime_env =
148229 crate :: pantry_db:: runtime_env_for_project ( & installation. pkg . project , conn) ?;
149230 for ( key, runtime_value) in runtime_env {
150231 let runtime_value = expand_moustaches ( & runtime_value, & installation, installations) ;
151- let new_value = if let Some ( curr_value) = output. get ( & key) {
232+ let insert_key = construct_platform_case_aware_env_key ( key. clone ( ) ) ;
233+ let new_value = if let Some ( curr_value) = output. get ( & insert_key) {
152234 if runtime_value. contains ( & format ! ( "${}" , key) ) {
153235 runtime_value. replace ( & format ! ( "${}" , key) , curr_value)
154236 } else {
@@ -161,7 +243,7 @@ pub fn mix_runtime(
161243 } else {
162244 format ! ( "${{{}:-{}}}" , key, runtime_value)
163245 } ;
164- output. insert ( key , new_value) ;
246+ output. insert ( insert_key , new_value) ;
165247 }
166248 }
167249
0 commit comments