diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/tools/x | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/x')
-rw-r--r-- | src/tools/x/Cargo.lock | 5 | ||||
-rw-r--r-- | src/tools/x/Cargo.toml | 6 | ||||
-rw-r--r-- | src/tools/x/README.md | 10 | ||||
-rw-r--r-- | src/tools/x/src/main.rs | 96 |
4 files changed, 117 insertions, 0 deletions
diff --git a/src/tools/x/Cargo.lock b/src/tools/x/Cargo.lock new file mode 100644 index 000000000..723d6cb25 --- /dev/null +++ b/src/tools/x/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "x" +version = "0.1.0" diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml new file mode 100644 index 000000000..315027279 --- /dev/null +++ b/src/tools/x/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "x" +version = "0.1.0" +description = "Run x.py slightly more conveniently" +edition = "2021" +publish = false diff --git a/src/tools/x/README.md b/src/tools/x/README.md new file mode 100644 index 000000000..80bf02e8a --- /dev/null +++ b/src/tools/x/README.md @@ -0,0 +1,10 @@ +# x + +`x` invokes `x.py` from any subdirectory. + +To install, run the following commands: + +``` +$ cd rust/src/tools/x/ +$ cargo install --path . +``` diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs new file mode 100644 index 000000000..9187c3551 --- /dev/null +++ b/src/tools/x/src/main.rs @@ -0,0 +1,96 @@ +//! Run `x.py` from any subdirectory of a rust compiler checkout. +//! +//! We prefer `exec`, to avoid adding an extra process in the process tree. +//! However, since `exec` isn't available on Windows, we indirect through +//! `exec_or_status`, which will call `exec` on unix and `status` on Windows. +//! +//! We use `python`, `python3`, or `python2` as the python interpreter to run +//! `x.py`, in that order of preference. + +use std::{ + env, io, + 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).exists() { + return PYTHON; + } + + python2 |= dir.join(PYTHON2).exists(); + python3 |= dir.join(PYTHON3).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(unix)] +fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> { + use std::os::unix::process::CommandExt; + Err(command.exec()) +} + +#[cfg(not(unix))] +fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> { + command.status() +} + +fn main() { + let current = match env::current_dir() { + Ok(dir) => dir, + Err(err) => { + eprintln!("Failed to get current directory: {err}"); + process::exit(1); + } + }; + + for dir in current.ancestors() { + let candidate = dir.join("x.py"); + + if candidate.exists() { + let mut python = Command::new(python()); + + python.arg(&candidate).args(env::args().skip(1)).current_dir(dir); + + let result = exec_or_status(&mut python); + + match result { + Err(error) => { + eprintln!("Failed to invoke `{}`: {}", candidate.display(), error); + } + Ok(status) => { + process::exit(status.code().unwrap_or(1)); + } + } + } + } + + eprintln!( + "x.py not found. Please run inside of a checkout of `https://github.com/rust-lang/rust`." + ); + + process::exit(1); +} |