@@ -2,11 +2,74 @@ use std::{
22 collections:: { HashMap , HashSet } ,
33 error:: Error ,
44 path:: PathBuf ,
5- str:: FromStr ,
65} ;
76
7+ #[ cfg( unix) ]
8+ use std:: str:: FromStr ;
9+
10+ #[ cfg( windows) ]
11+ use std:: {
12+ fmt,
13+ hash:: { Hash , Hasher } ,
14+ } ;
15+
16+ #[ cfg( windows) ]
17+ #[ derive( Clone ) ]
18+ pub struct CaseInsensitiveKey ( pub String ) ;
19+
20+ #[ cfg( windows) ]
21+ impl PartialEq for CaseInsensitiveKey {
22+ fn eq ( & self , other : & Self ) -> bool {
23+ self . 0 . eq_ignore_ascii_case ( & other. 0 )
24+ }
25+ }
26+
27+ #[ cfg( windows) ]
28+ impl fmt:: Display for CaseInsensitiveKey {
29+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
30+ write ! ( f, "{}" , self . 0 )
31+ }
32+ }
33+
34+ #[ cfg( windows) ]
35+ impl Eq for CaseInsensitiveKey { }
36+
37+ #[ cfg( windows) ]
38+ impl Hash for CaseInsensitiveKey {
39+ fn hash < H : Hasher > ( & self , state : & mut H ) {
40+ self . 0 . to_lowercase ( ) . hash ( state) ;
41+ }
42+ }
43+
44+ #[ cfg( windows) ]
45+ impl fmt:: Debug for CaseInsensitiveKey {
46+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
47+ write ! ( f, "{:?}" , self . 0 )
48+ }
49+ }
50+
51+ #[ cfg( windows) ]
52+ pub type PlatformCaseAwareEnvKey = CaseInsensitiveKey ;
53+ #[ cfg( not( windows) ) ]
54+ pub type PlatformCaseAwareEnvKey = String ;
55+
56+ #[ cfg( windows) ]
57+ pub fn construct_platform_case_aware_env_key ( key : String ) -> PlatformCaseAwareEnvKey {
58+ CaseInsensitiveKey ( key)
59+ }
60+
61+ #[ cfg( not( windows) ) ]
62+ pub fn construct_platform_case_aware_env_key ( key : String ) -> PlatformCaseAwareEnvKey {
63+ key
64+ }
65+
866use crate :: types:: Installation ;
967
68+ #[ cfg( unix) ]
69+ const SEP : & str = ":" ;
70+ #[ cfg( windows) ]
71+ const SEP : & str = ";" ;
72+
1073pub fn map ( installations : & Vec < Installation > ) -> HashMap < String , Vec < String > > {
1174 let mut vars: HashMap < EnvKey , OrderedSet < PathBuf > > = HashMap :: new ( ) ;
1275
@@ -37,12 +100,15 @@ pub fn map(installations: &Vec<Installation>) -> HashMap<String, Vec<String>> {
37100 }
38101
39102 // don’t break `man`
103+ #[ cfg( unix) ]
40104 if vars. contains_key ( & EnvKey :: Manpath ) {
41105 vars. get_mut ( & EnvKey :: Manpath )
42106 . unwrap ( )
43107 . add ( PathBuf :: from_str ( "/usr/share/man" ) . unwrap ( ) ) ;
44108 }
109+
45110 // https://github.com/pkgxdev/libpkgx/issues/70
111+ #[ cfg( unix) ]
46112 if vars. contains_key ( & EnvKey :: XdgDataDirs ) {
47113 let set = vars. get_mut ( & EnvKey :: XdgDataDirs ) . unwrap ( ) ;
48114 set. add ( PathBuf :: from_str ( "/usr/local/share" ) . unwrap ( ) ) ;
@@ -71,17 +137,25 @@ enum EnvKey {
71137 Path ,
72138 Manpath ,
73139 PkgConfigPath ,
140+ #[ cfg( unix) ]
74141 LibraryPath ,
142+ #[ cfg( unix) ]
75143 LdLibraryPath ,
144+ #[ cfg( unix) ]
76145 Cpath ,
77146 XdgDataDirs ,
78147 CmakePrefixPath ,
79148 #[ cfg( target_os = "macos" ) ]
80149 DyldFallbackLibraryPath ,
81150 SslCertFile ,
151+ #[ cfg( unix) ]
82152 Ldflags ,
83153 PkgxDir ,
84154 AclocalPath ,
155+ #[ cfg( windows) ]
156+ Lib ,
157+ #[ cfg( windows) ]
158+ Include ,
85159}
86160
87161struct OrderedSet < T : Eq + std:: hash:: Hash + Clone > {
@@ -111,44 +185,58 @@ fn suffixes(key: &EnvKey) -> Option<Vec<&'static str>> {
111185 EnvKey :: PkgConfigPath => Some ( vec ! [ "share/pkgconfig" , "lib/pkgconfig" ] ) ,
112186 EnvKey :: XdgDataDirs => Some ( vec ! [ "share" ] ) ,
113187 EnvKey :: AclocalPath => Some ( vec ! [ "share/aclocal" ] ) ,
188+ #[ cfg( unix) ]
114189 EnvKey :: LibraryPath | EnvKey :: LdLibraryPath => Some ( vec ! [ "lib" , "lib64" ] ) ,
115190 #[ cfg( target_os = "macos" ) ]
116191 EnvKey :: DyldFallbackLibraryPath => Some ( vec ! [ "lib" , "lib64" ] ) ,
192+ #[ cfg( unix) ]
117193 EnvKey :: Cpath => Some ( vec ! [ "include" ] ) ,
118- EnvKey :: CmakePrefixPath | EnvKey :: SslCertFile | EnvKey :: Ldflags | EnvKey :: PkgxDir => None ,
194+ EnvKey :: CmakePrefixPath | EnvKey :: SslCertFile | EnvKey :: PkgxDir => None ,
195+ #[ cfg( unix) ]
196+ EnvKey :: Ldflags => None ,
197+ #[ cfg( windows) ]
198+ EnvKey :: Lib => Some ( vec ! [ "lib" ] ) ,
199+ #[ cfg( windows) ]
200+ EnvKey :: Include => Some ( vec ! [ "include" ] ) ,
119201 }
120202}
121203
122- pub fn mix ( input : HashMap < String , Vec < String > > ) -> HashMap < String , String > {
123- let mut rv = HashMap :: from_iter ( std:: env:: vars ( ) ) ;
204+ pub fn mix ( input : HashMap < String , Vec < String > > ) -> HashMap < PlatformCaseAwareEnvKey , String > {
205+ let mut rv: HashMap < PlatformCaseAwareEnvKey , String > = HashMap :: new ( ) ;
206+
207+ for ( key, value) in std:: env:: vars ( ) {
208+ rv. insert ( construct_platform_case_aware_env_key ( key) , value) ;
209+ }
124210
125211 for ( key, value) in input. iter ( ) {
212+ let key = & construct_platform_case_aware_env_key ( key. clone ( ) ) ;
126213 if let Some ( values) = rv. get ( key) {
127- rv. insert ( key. clone ( ) , format ! ( "{}:{} " , value. join( ":" ) , values) ) ;
214+ rv. insert ( key. clone ( ) , format ! ( "{}{}{} " , value. join( SEP ) , SEP , values) ) ;
128215 } else {
129- rv. insert ( key. clone ( ) , value. join ( ":" ) ) ;
216+ rv. insert ( key. clone ( ) , value. join ( SEP ) ) ;
130217 }
131218 }
132219
133220 rv
134221}
135222
136223pub fn mix_runtime (
137- input : & HashMap < String , String > ,
224+ input : & HashMap < PlatformCaseAwareEnvKey , String > ,
138225 installations : & Vec < Installation > ,
139226 conn : & Connection ,
140- ) -> Result < HashMap < String , String > , Box < dyn Error > > {
141- let mut output: HashMap < String , String > = input
227+ ) -> Result < HashMap < PlatformCaseAwareEnvKey , String > , Box < dyn Error > > {
228+ let mut output: HashMap < PlatformCaseAwareEnvKey , String > = input
142229 . iter ( )
143- . map ( |( k, v) | ( k. clone ( ) , format ! ( "{}: ${}" , v, k) ) )
230+ . map ( |( k, v) | ( k. clone ( ) , format ! ( "{}{} ${}" , v, SEP , k) ) )
144231 . collect ( ) ;
145232
146233 for installation in installations. clone ( ) {
147234 let runtime_env =
148235 crate :: pantry_db:: runtime_env_for_project ( & installation. pkg . project , conn) ?;
149236 for ( key, runtime_value) in runtime_env {
150237 let runtime_value = expand_moustaches ( & runtime_value, & installation, installations) ;
151- let new_value = if let Some ( curr_value) = output. get ( & key) {
238+ let insert_key = construct_platform_case_aware_env_key ( key. clone ( ) ) ;
239+ let new_value = if let Some ( curr_value) = output. get ( & insert_key) {
152240 if runtime_value. contains ( & format ! ( "${}" , key) ) {
153241 runtime_value. replace ( & format ! ( "${}" , key) , curr_value)
154242 } else {
@@ -161,7 +249,7 @@ pub fn mix_runtime(
161249 } else {
162250 format ! ( "${{{}:-{}}}" , key, runtime_value)
163251 } ;
164- output. insert ( key , new_value) ;
252+ output. insert ( insert_key , new_value) ;
165253 }
166254 }
167255
0 commit comments