4
4
5
5
use std:: env:: { args_os, var_os} ;
6
6
use std:: ffi:: { CString , OsStr , OsString } ;
7
+ #[ cfg( unix) ]
7
8
use std:: os:: unix:: ffi:: { OsStrExt , OsStringExt } ;
9
+ #[ cfg( unix) ]
8
10
use std:: os:: unix:: fs:: symlink;
11
+ #[ cfg( windows) ]
12
+ use std:: os:: windows:: fs:: { symlink_dir, symlink_file} ;
9
13
use std:: path:: { Path , PathBuf } ;
10
14
use std:: sync:: Arc ;
11
15
12
16
use miette:: { bail, miette, Context , IntoDiagnostic , Result } ;
17
+ #[ cfg( unix) ]
13
18
use nix:: unistd:: execv;
14
19
use spfs:: encoding:: Digest ;
15
20
use spfs:: prelude:: * ;
@@ -188,9 +193,19 @@ impl<'a> Dynamic<'a> {
188
193
Err ( miette ! ( "symlink target exists" ) )
189
194
}
190
195
. and_then ( |_| {
191
- symlink ( & digest_string, & symlink_name)
192
- . into_diagnostic ( )
193
- . wrap_err ( "create symlink" )
196
+ #[ cfg( unix) ]
197
+ {
198
+ symlink ( & digest_string, & symlink_name)
199
+ . into_diagnostic ( )
200
+ . wrap_err ( "create symlink" )
201
+ }
202
+ #[ cfg( windows) ]
203
+ {
204
+ symlink_file ( & digest_string, & symlink_name)
205
+ . or_else ( |_| symlink_dir ( & digest_string, & symlink_name) )
206
+ . into_diagnostic ( )
207
+ . wrap_err ( "create symlink" )
208
+ }
194
209
} ) ;
195
210
}
196
211
}
@@ -200,18 +215,38 @@ impl<'a> Dynamic<'a> {
200
215
201
216
async fn execute ( & self ) -> Result < ( ) > {
202
217
let bin_tag = var_os ( self . tag_env_var ( ) ) . unwrap_or_else ( || RPM_TAG . into ( ) ) ;
218
+ #[ cfg( unix) ]
203
219
let args = args_os ( )
204
220
. map ( |os_string| CString :: new ( os_string. as_bytes ( ) ) )
205
221
. collect :: < Result < Vec < _ > , _ > > ( )
206
222
. into_diagnostic ( )
207
223
. wrap_err ( "valid CStrings" ) ?;
224
+ #[ cfg( windows) ]
225
+ let args = args_os ( ) . collect :: < Vec < _ > > ( ) ;
208
226
if bin_tag == RPM_TAG {
227
+ #[ cfg( unix) ]
209
228
let bin = CString :: new ( AsRef :: < OsStr > :: as_ref ( & self . rpm_bin_path ( ) ) . as_bytes ( ) )
210
229
. expect ( "valid CString" ) ;
230
+ #[ cfg( windows) ]
231
+ let bin = self . rpm_bin_path ( ) ;
232
+ #[ cfg( unix) ]
211
233
execv ( & bin, args. as_slice ( ) )
212
234
. into_diagnostic ( )
213
235
. wrap_err_with ( || format ! ( "execv({}, ...)" , bin. to_string_lossy( ) ) ) ?;
214
- unreachable ! ( ) ;
236
+ #[ cfg( windows) ]
237
+ {
238
+ let bin = bin. to_string_lossy ( ) ;
239
+ let args = args
240
+ . iter ( )
241
+ . map ( |arg| arg. to_string_lossy ( ) )
242
+ . collect :: < Vec < _ > > ( ) ;
243
+ let args = args. join ( " " ) ;
244
+ std:: process:: Command :: new ( bin. to_string ( ) )
245
+ . args ( args. split_whitespace ( ) )
246
+ . spawn ( )
247
+ . into_diagnostic ( )
248
+ . wrap_err_with ( || format ! ( "spawn({}, {})" , bin, args) ) ?;
249
+ }
215
250
}
216
251
217
252
let config = spfs:: get_config ( ) . expect ( "loaded spfs config" ) ;
@@ -264,7 +299,7 @@ impl<'a> Dynamic<'a> {
264
299
} ) ?;
265
300
266
301
std:: env:: set_var ( self . bin_var ( ) , & bin_path) ;
267
-
302
+ # [ cfg ( unix ) ]
268
303
execv (
269
304
& CString :: new ( bin_path. into_vec ( ) )
270
305
. into_diagnostic ( )
@@ -278,6 +313,20 @@ impl<'a> Dynamic<'a> {
278
313
)
279
314
. into_diagnostic ( )
280
315
. wrap_err ( "process replaced" ) ?;
316
+ #[ cfg( windows) ]
317
+ {
318
+ let bin = bin_path. to_string_lossy ( ) ;
319
+ let args = args
320
+ . iter ( )
321
+ . map ( |arg| arg. to_string_lossy ( ) )
322
+ . collect :: < Vec < _ > > ( ) ;
323
+ let args = args. join ( " " ) ;
324
+ std:: process:: Command :: new ( bin. to_string ( ) )
325
+ . args ( args. split_whitespace ( ) )
326
+ . spawn ( )
327
+ . into_diagnostic ( )
328
+ . wrap_err_with ( || format ! ( "spawn({}, {})" , bin, args) ) ?;
329
+ }
281
330
unreachable ! ( ) ;
282
331
}
283
332
Ok ( None ) => bail ! ( "Expected platform object from spfs" ) ,
0 commit comments