@@ -13,6 +13,9 @@ use tokio_util::compat::FuturesAsyncReadCompatExt;
13
13
// futures::io::AsyncRead.
14
14
use futures:: stream:: TryStreamExt ;
15
15
16
+ #[ cfg( windows) ]
17
+ use std:: os:: windows:: fs:: symlink_dir;
18
+
16
19
use crate :: {
17
20
cellar,
18
21
client:: build_client,
@@ -38,14 +41,22 @@ where
38
41
{
39
42
let shelf = config. pkgx_dir . join ( & pkg. project ) ;
40
43
fs:: create_dir_all ( & shelf) ?;
41
- let shelf = OpenOptions :: new ( )
44
+
45
+ #[ cfg( windows) ]
46
+ let lockfile = OpenOptions :: new ( )
47
+ . read ( true )
48
+ . write ( true )
49
+ . create ( true )
50
+ . open ( shelf. join ( "lockfile" ) ) ?;
51
+ #[ cfg( not( windows) ) ]
52
+ let lockfile = OpenOptions :: new ( )
42
53
. read ( true ) // Open the directory in read-only mode
43
54
. open ( shelf. clone ( ) ) ?;
44
55
45
56
task:: spawn_blocking ( {
46
- let shelf = shelf . try_clone ( ) ?;
57
+ let lockfile = lockfile . try_clone ( ) ?;
47
58
move || {
48
- shelf
59
+ lockfile
49
60
. lock_exclusive ( )
50
61
. expect ( "unexpected error: install locking failed" ) ;
51
62
}
57
68
// did another instance of pkgx install us while we waited for the lock?
58
69
// if so, we’re good: eject
59
70
if dst_path. is_dir ( ) {
60
- FileExt :: unlock ( & shelf ) ?;
71
+ FileExt :: unlock ( & lockfile ) ?;
61
72
return Ok ( Installation {
62
73
path : dst_path,
63
74
pkg : pkg. clone ( ) ,
@@ -112,7 +123,7 @@ where
112
123
113
124
symlink ( & installation, config) . await ?;
114
125
115
- FileExt :: unlock ( & shelf ) ?;
126
+ FileExt :: unlock ( & lockfile ) ?;
116
127
117
128
Ok ( installation)
118
129
}
@@ -203,9 +214,10 @@ async fn make_symlink(
203
214
. file_name ( )
204
215
. ok_or_else ( || anyhow:: anyhow!( "Could not get the base name of the installation path" ) ) ?;
205
216
206
- match std:: os:: unix:: fs:: symlink ( target, & symlink_path) {
207
- Ok ( _) => Ok ( ( ) ) ,
208
- Err ( err) if err. kind ( ) == std:: io:: ErrorKind :: AlreadyExists => Ok ( ( ) ) ,
209
- Err ( err) => Err ( err. into ( ) ) ,
210
- }
217
+ #[ cfg( not( windows) ) ]
218
+ std:: os:: unix:: fs:: symlink ( target, & symlink_path) ?;
219
+ #[ cfg( windows) ]
220
+ symlink_dir ( target, symlink_path) ?;
221
+
222
+ Ok ( ( ) )
211
223
}
0 commit comments