@@ -111,16 +111,20 @@ fn setup(use_local_bundle: Option<OsString>) -> Result<()> {
111
111
std:: fs:: create_dir_all ( & base_dir) ?;
112
112
113
113
if let Some ( pathstr) = use_local_bundle {
114
+ println ! ( "[2/6] Installing local Kani bundle: {}" , pathstr. to_string_lossy( ) ) ;
114
115
let path = Path :: new ( & pathstr) . canonicalize ( ) ?;
115
- println ! ( "[2/6] Installing local Kani bundle: {}" , path. display( ) ) ;
116
- Command :: new ( "tar" ) . arg ( "zxf" ) . arg ( & path) . current_dir ( base_dir) . run ( ) ?;
117
-
118
- // when given a local bundle, it's often "-latest" but we expect "-1.0" or something. Hack it up.
119
- let file = path. file_name ( ) . expect ( "has filename" ) . to_string_lossy ( ) ;
120
- let components: Vec < _ > = file. split ( '-' ) . collect ( ) ;
121
- let expected_dir = format ! ( "{}-{}" , components[ 0 ] , components[ 1 ] ) ;
122
-
123
- std:: fs:: rename ( base_dir. join ( expected_dir) , & kani_dir) ?;
116
+ // When given a local bundle, it's often "-latest" but we expect "-1.0" or something.
117
+ // tar supports "stripping" the first directory from the bundle, so do that and
118
+ // extract it directly into the expected (kani_dir) directory (instead of base_dir).
119
+ if !kani_dir. exists ( ) {
120
+ std:: fs:: create_dir ( & kani_dir) ?;
121
+ }
122
+ Command :: new ( "tar" )
123
+ . arg ( "--strip-components=1" )
124
+ . arg ( "-zxf" )
125
+ . arg ( & path)
126
+ . current_dir ( & kani_dir)
127
+ . run ( ) ?;
124
128
} else {
125
129
let filename = download_filename ( ) ;
126
130
println ! ( "[2/6] Downloading Kani release bundle: {}" , & filename) ;
@@ -145,7 +149,7 @@ fn setup(use_local_bundle: Option<OsString>) -> Result<()> {
145
149
146
150
let toolchain = home:: rustup_home ( ) ?. join ( "toolchains" ) . join ( & toolchain_version) ;
147
151
148
- Command :: new ( "ln" ) . arg ( "-s" ) . arg ( toolchain) . arg ( kani_dir. join ( "toolchain" ) ) . run ( ) ?;
152
+ symlink_rust_toolchain ( & toolchain, & kani_dir) ?;
149
153
150
154
println ! ( "[4/6] Installing Kani python dependencies..." ) ;
151
155
let pyroot = kani_dir. join ( "pyroot" ) ;
@@ -201,6 +205,17 @@ fn setup(use_local_bundle: Option<OsString>) -> Result<()> {
201
205
Ok ( ( ) )
202
206
}
203
207
208
+ /// Creates a `kani_dir/toolchain` symlink pointing to `toolchain`.
209
+ fn symlink_rust_toolchain ( toolchain : & Path , kani_dir : & Path ) -> Result < ( ) > {
210
+ let path = kani_dir. join ( "toolchain" ) ;
211
+ // We want to be idempotent, so if the symlink already exists, delete it first
212
+ if path. exists ( ) && path. is_symlink ( ) {
213
+ std:: fs:: remove_file ( & path) ?;
214
+ }
215
+ std:: os:: unix:: fs:: symlink ( toolchain, path) ?;
216
+ Ok ( ( ) )
217
+ }
218
+
204
219
/// Executes `kani-driver` in `bin` mode (kani or cargo-kani)
205
220
/// augmenting environment variables to accomodate our release environment
206
221
fn exec ( bin : & str ) -> Result < ( ) > {
0 commit comments