9
9
//! We also don't use `pwsh` on Windows, because it is not installed by default;
10
10
11
11
use std:: {
12
- env, io,
12
+ env:: { self , consts:: EXE_EXTENSION } ,
13
+ io,
13
14
path:: Path ,
14
15
process:: { self , Command , ExitStatus } ,
15
16
} ;
16
17
18
+ const PYTHON : & str = "python" ;
19
+ const PYTHON2 : & str = "python2" ;
20
+ const PYTHON3 : & str = "python3" ;
21
+
22
+ fn python ( ) -> & ' static str {
23
+ let val = match env:: var_os ( "PATH" ) {
24
+ Some ( val) => val,
25
+ None => return PYTHON ,
26
+ } ;
27
+
28
+ let mut python2 = false ;
29
+ let mut python3 = false ;
30
+
31
+ for dir in env:: split_paths ( & val) {
32
+ // `python` should always take precedence over python2 / python3 if it exists
33
+ if dir. join ( PYTHON ) . with_extension ( EXE_EXTENSION ) . exists ( ) {
34
+ return PYTHON ;
35
+ }
36
+
37
+ python2 |= dir. join ( PYTHON2 ) . with_extension ( EXE_EXTENSION ) . exists ( ) ;
38
+ python3 |= dir. join ( PYTHON3 ) . with_extension ( EXE_EXTENSION ) . exists ( ) ;
39
+ }
40
+
41
+ // try 3 before 2
42
+ if python3 {
43
+ PYTHON3
44
+ } else if python2 {
45
+ PYTHON2
46
+ } else {
47
+ // Python was not found on path, so exit
48
+ eprintln ! ( "Unable to find python in your PATH. Please check it is installed." ) ;
49
+ process:: exit ( 1 ) ;
50
+ }
51
+ }
52
+
17
53
#[ cfg( windows) ]
18
54
fn x_command ( dir : & Path ) -> Command {
19
55
let mut cmd = Command :: new ( "powershell.exe" ) ;
@@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
51
87
command. status ( )
52
88
}
53
89
90
+ fn handle_result ( result : io:: Result < ExitStatus > , cmd : Command ) {
91
+ match result {
92
+ Err ( error) => {
93
+ eprintln ! ( "Failed to invoke `{:?}`: {}" , cmd, error) ;
94
+ }
95
+ Ok ( status) => {
96
+ process:: exit ( status. code ( ) . unwrap_or ( 1 ) ) ;
97
+ }
98
+ }
99
+ }
100
+
54
101
fn main ( ) {
55
102
match env:: args ( ) . skip ( 1 ) . next ( ) . as_deref ( ) {
56
103
Some ( "--wrapper-version" ) => {
@@ -70,22 +117,19 @@ fn main() {
70
117
71
118
for dir in current. ancestors ( ) {
72
119
let candidate = dir. join ( "x.py" ) ;
73
-
74
120
if candidate. exists ( ) {
75
- let mut cmd = x_command ( dir) ;
76
-
77
- cmd. args ( env:: args ( ) . skip ( 1 ) ) . current_dir ( dir) ;
78
-
79
- let result = exec_or_status ( & mut cmd) ;
80
-
81
- match result {
82
- Err ( error) => {
83
- eprintln ! ( "Failed to invoke `{:?}`: {}" , cmd, error) ;
84
- }
85
- Ok ( status) => {
86
- process:: exit ( status. code ( ) . unwrap_or ( 1 ) ) ;
87
- }
121
+ let shell_script_candidate = dir. join ( "x" ) ;
122
+ let mut cmd: Command ;
123
+ if shell_script_candidate. exists ( ) {
124
+ cmd = x_command ( dir) ;
125
+ cmd. args ( env:: args ( ) . skip ( 1 ) ) . current_dir ( dir) ;
126
+ } else {
127
+ // For older checkouts that do not have the x shell script, default to python
128
+ cmd = Command :: new ( python ( ) ) ;
129
+ cmd. arg ( & candidate) . args ( env:: args ( ) . skip ( 1 ) ) . current_dir ( dir) ;
88
130
}
131
+ let result = exec_or_status ( & mut cmd) ;
132
+ handle_result ( result, cmd) ;
89
133
}
90
134
}
91
135
0 commit comments