99//! We also don't use `pwsh` on Windows, because it is not installed by default;
1010
1111use std:: {
12- env, io,
12+ env:: { self , consts:: EXE_EXTENSION } ,
13+ io,
1314 path:: Path ,
1415 process:: { self , Command , ExitStatus } ,
1516} ;
1617
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+
1753#[ cfg( windows) ]
1854fn x_command ( dir : & Path ) -> Command {
1955 let mut cmd = Command :: new ( "powershell.exe" ) ;
@@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
5187 command. status ( )
5288}
5389
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+
54101fn main ( ) {
55102 match env:: args ( ) . skip ( 1 ) . next ( ) . as_deref ( ) {
56103 Some ( "--wrapper-version" ) => {
@@ -70,22 +117,19 @@ fn main() {
70117
71118 for dir in current. ancestors ( ) {
72119 let candidate = dir. join ( "x.py" ) ;
73-
74120 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) ;
88130 }
131+ let result = exec_or_status ( & mut cmd) ;
132+ handle_result ( result, cmd) ;
89133 }
90134 }
91135
0 commit comments