about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-02-15 21:30:57 +0100
committerGitHub <noreply@github.com>2023-02-15 21:30:57 +0100
commit32891e1121f40e90719975cba485e14181129b5c (patch)
tree1488a9d27192e919fe0a024dcac995ba64681cca
parent8f65e25aec6d42e049346aae52f8fec2fa508c38 (diff)
parent54cfc10fa593b512315f17a7df5235c5595dac9e (diff)
downloadrust-32891e1121f40e90719975cba485e14181129b5c.tar.gz
rust-32891e1121f40e90719975cba485e14181129b5c.zip
Rollup merge of #108021 - zephaniahong:oldx, r=albertlarsan68
make x look for x.py if shell script does not exist

Fixes #107907

Manually tested by doing the following after changes were made:
1. `cargo install --path src/tools/x`
2. checked out old version:  commit hash `775c3c0` from https://github.com/rust-lang/rust/pull/99992
3. Ran `x --help` and it works. Previously, it was giving the error `x.py not found`
-rw-r--r--src/tools/x/Cargo.toml2
-rw-r--r--src/tools/x/src/main.rs74
2 files changed, 60 insertions, 16 deletions
diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml
index 31502727962..84a42ca36ef 100644
--- a/src/tools/x/Cargo.toml
+++ b/src/tools/x/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "x"
-version = "0.1.0"
+version = "0.1.1"
 description = "Run x.py slightly more conveniently"
 edition = "2021"
 publish = false
diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs
index 01f7187851e..5da8a2888ec 100644
--- a/src/tools/x/src/main.rs
+++ b/src/tools/x/src/main.rs
@@ -9,11 +9,47 @@
 //! We also don't use `pwsh` on Windows, because it is not installed by default;
 
 use std::{
-    env, io,
+    env::{self, consts::EXE_EXTENSION},
+    io,
     path::Path,
     process::{self, Command, ExitStatus},
 };
 
+const PYTHON: &str = "python";
+const PYTHON2: &str = "python2";
+const PYTHON3: &str = "python3";
+
+fn python() -> &'static str {
+    let val = match env::var_os("PATH") {
+        Some(val) => val,
+        None => return PYTHON,
+    };
+
+    let mut python2 = false;
+    let mut python3 = false;
+
+    for dir in env::split_paths(&val) {
+        // `python` should always take precedence over python2 / python3 if it exists
+        if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() {
+            return PYTHON;
+        }
+
+        python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
+        python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
+    }
+
+    // try 3 before 2
+    if python3 {
+        PYTHON3
+    } else if python2 {
+        PYTHON2
+    } else {
+        // Python was not found on path, so exit
+        eprintln!("Unable to find python in your PATH. Please check it is installed.");
+        process::exit(1);
+    }
+}
+
 #[cfg(windows)]
 fn x_command(dir: &Path) -> Command {
     let mut cmd = Command::new("powershell.exe");
@@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
     command.status()
 }
 
+fn handle_result(result: io::Result<ExitStatus>, cmd: Command) {
+    match result {
+        Err(error) => {
+            eprintln!("Failed to invoke `{:?}`: {}", cmd, error);
+        }
+        Ok(status) => {
+            process::exit(status.code().unwrap_or(1));
+        }
+    }
+}
+
 fn main() {
     match env::args().skip(1).next().as_deref() {
         Some("--wrapper-version") => {
@@ -70,22 +117,19 @@ fn main() {
 
     for dir in current.ancestors() {
         let candidate = dir.join("x.py");
-
         if candidate.exists() {
-            let mut cmd = x_command(dir);
-
-            cmd.args(env::args().skip(1)).current_dir(dir);
-
-            let result = exec_or_status(&mut cmd);
-
-            match result {
-                Err(error) => {
-                    eprintln!("Failed to invoke `{:?}`: {}", cmd, error);
-                }
-                Ok(status) => {
-                    process::exit(status.code().unwrap_or(1));
-                }
+            let shell_script_candidate = dir.join("x");
+            let mut cmd: Command;
+            if shell_script_candidate.exists() {
+                cmd = x_command(dir);
+                cmd.args(env::args().skip(1)).current_dir(dir);
+            } else {
+                // For older checkouts that do not have the x shell script, default to python
+                cmd = Command::new(python());
+                cmd.arg(&candidate).args(env::args().skip(1)).current_dir(dir);
             }
+            let result = exec_or_status(&mut cmd);
+            handle_result(result, cmd);
         }
     }