1
1
//! Manifest a particular Lean version by installing it from a distribution server.
2
2
3
+ use std:: { thread:: sleep, time:: Duration } ;
4
+
3
5
use component:: { TarGzPackage , TarZstdPackage , ZipPackage } ;
4
6
use download:: DownloadCfg ;
5
- use elan_utils:: utils;
7
+ use elan_utils:: { raw :: read_file , utils} ;
6
8
use errors:: * ;
9
+ use fslock:: LockFile ;
7
10
use notifications:: * ;
8
11
use prefix:: InstallPrefix ;
9
12
use temp;
@@ -25,11 +28,28 @@ impl Manifestation {
25
28
temp_cfg : & temp:: Cfg ,
26
29
notify_handler : & dyn Fn ( Notification ) ,
27
30
) -> Result < ( ) > {
31
+ let prefix = self . prefix . path ( ) ;
32
+ utils:: ensure_dir_exists ( "toolchsin" , & prefix, & |n| {
33
+ ( notify_handler) ( n. into ( ) )
34
+ } ) ?;
35
+
36
+ let lockfile_path = prefix. with_extension ( "lock" ) ;
37
+ let mut lockfile = LockFile :: open ( & lockfile_path) ?;
38
+ if !lockfile. try_lock_with_pid ( ) ? {
39
+ notify_handler ( Notification :: WaitingForFileLock ( & lockfile_path, read_file ( & lockfile_path) ?. trim ( ) ) ) ;
40
+ while !lockfile. try_lock_with_pid ( ) ? {
41
+ sleep ( Duration :: from_secs ( 1 ) ) ;
42
+ }
43
+ }
28
44
let dlcfg = DownloadCfg {
29
45
temp_cfg : temp_cfg,
30
46
notify_handler : notify_handler,
31
47
} ;
32
48
49
+ if utils:: is_directory ( prefix) {
50
+ return Ok ( ( ) )
51
+ }
52
+
33
53
// find correct download on HTML page (AAAAH)
34
54
use regex:: Regex ;
35
55
use std:: fs;
@@ -70,17 +90,11 @@ impl Manifestation {
70
90
71
91
let installer_file = dlcfg. download_and_check ( & url) ?;
72
92
73
- let prefix = self . prefix . path ( ) ;
74
-
75
93
notify_handler ( Notification :: InstallingComponent ( & prefix. to_string_lossy ( ) ) ) ;
76
94
77
95
// unpack into temporary place, then move atomically to guard against aborts during unpacking
78
96
let unpack_dir = prefix. with_extension ( "tmp" ) ;
79
97
80
- if utils:: is_directory ( prefix) {
81
- return Err ( format ! ( "'{}' is already installed" , prefix. display( ) ) . into ( ) ) ;
82
- }
83
-
84
98
if utils:: is_directory ( & unpack_dir) {
85
99
utils:: remove_dir ( "temp toolchain directory" , & unpack_dir, & |n| {
86
100
( notify_handler) ( n. into ( ) )
@@ -103,6 +117,7 @@ impl Manifestation {
103
117
}
104
118
105
119
utils:: rename_dir ( "temp toolchain directory" , & unpack_dir, prefix) ?;
120
+ let _ = std:: fs:: remove_file ( & lockfile_path) ;
106
121
107
122
Ok ( ( ) )
108
123
}
0 commit comments