summaryrefslogtreecommitdiffstats
path: root/src/tools/x
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/tools/x
parentInitial commit. (diff)
downloadrustc-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.lock5
-rw-r--r--src/tools/x/Cargo.toml6
-rw-r--r--src/tools/x/README.md10
-rw-r--r--src/tools/x/src/main.rs96
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);
+}