summaryrefslogtreecommitdiffstats
path: root/src/tools/x
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/x')
-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 315027279..84a42ca36 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 01f718785..5da8a2888 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);
}
}