1
1
use core:: fmt;
2
- use fs_err as fs;
3
- use itertools:: Itertools ;
4
2
use std:: cmp:: Reverse ;
5
3
use std:: ffi:: OsStr ;
6
4
use std:: io:: { self , Write } ;
7
5
use std:: path:: { Path , PathBuf } ;
8
6
use std:: str:: FromStr ;
7
+
8
+ use fs_err:: { self as fs, File } ;
9
+ use itertools:: Itertools ;
9
10
use thiserror:: Error ;
10
11
use tracing:: { debug, warn} ;
11
12
13
+ use uv_fs:: { LockedFile , Simplified } ;
12
14
use uv_state:: { StateBucket , StateStore } ;
15
+ use uv_static:: EnvVars ;
16
+ use uv_trampoline_builder:: windows_python_launcher;
13
17
14
18
use crate :: downloads:: Error as DownloadError ;
15
19
use crate :: implementation:: {
@@ -21,9 +25,6 @@ use crate::platform::Error as PlatformError;
21
25
use crate :: platform:: { Arch , Libc , Os } ;
22
26
use crate :: python_version:: PythonVersion ;
23
27
use crate :: { PythonRequest , PythonVariant } ;
24
- use uv_fs:: { LockedFile , Simplified } ;
25
- use uv_static:: EnvVars ;
26
-
27
28
#[ derive( Error , Debug ) ]
28
29
pub enum Error {
29
30
#[ error( transparent) ]
@@ -74,6 +75,8 @@ pub enum Error {
74
75
} ,
75
76
#[ error( "Failed to find a directory to install executables into" ) ]
76
77
NoExecutableDirectory ,
78
+ #[ error( transparent) ]
79
+ LauncherError ( #[ from] uv_trampoline_builder:: Error ) ,
77
80
#[ error( "Failed to read managed Python directory name: {0}" ) ]
78
81
NameError ( String ) ,
79
82
#[ error( "Failed to construct absolute path to managed Python directory: {}" , _0. user_display( ) ) ]
@@ -485,16 +488,34 @@ impl ManagedPythonInstallation {
485
488
err,
486
489
} ) ?;
487
490
488
- match uv_fs:: symlink_copy_fallback_file ( & python, target) {
489
- Ok ( ( ) ) => Ok ( ( ) ) ,
490
- Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => {
491
- Err ( Error :: MissingExecutable ( python. clone ( ) ) )
491
+ if cfg ! ( unix) {
492
+ match uv_fs:: symlink_copy_fallback_file ( & python, target) {
493
+ Ok ( ( ) ) => Ok ( ( ) ) ,
494
+ Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => {
495
+ Err ( Error :: MissingExecutable ( python. clone ( ) ) )
496
+ }
497
+ Err ( err) => Err ( Error :: LinkExecutable {
498
+ from : python,
499
+ to : target. to_path_buf ( ) ,
500
+ err,
501
+ } ) ,
492
502
}
493
- Err ( err) => Err ( Error :: LinkExecutable {
494
- from : python,
495
- to : target. to_path_buf ( ) ,
496
- err,
497
- } ) ,
503
+ } else if cfg ! ( windows) {
504
+ // TODO(zanieb): Install GUI launchers as well
505
+ let launcher = windows_python_launcher ( & python, false ) ?;
506
+ match File :: create ( target) ?. write_all ( launcher. as_ref ( ) ) {
507
+ Ok ( ( ) ) => Ok ( ( ) ) ,
508
+ Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => {
509
+ Err ( Error :: MissingExecutable ( python. clone ( ) ) )
510
+ }
511
+ Err ( err) => Err ( Error :: LinkExecutable {
512
+ from : python,
513
+ to : target. to_path_buf ( ) ,
514
+ err,
515
+ } ) ,
516
+ }
517
+ } else {
518
+ unimplemented ! ( "Only Windows and Unix systems are supported." )
498
519
}
499
520
}
500
521
}
0 commit comments