-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #78658 - casey:x, r=Mark-Simulacrum
Add a tool to run `x.py` from any subdirectory This adds a binary called `x` in `src/tools/x`. All it does is check the current directory and its ancestors for a file called `x.py`, and if it finds one, runs it. By installing x, you can easily run `x.py` from any subdirectory, and only need to type `x`. It can be installed with `cargo install --path src/tools/x` This is a copy of a [binary I've been using myself when working on rust](https://github.com/casey/bootstrap), currently published to crates.io as `bootstrap`. It could be changed to avoid indirecting through `x.py`, and instead call the bootstrap module directly. However, this seemed like the simplest thing possible, and won't break if the details of how the bootstrap module is invoked change.
- Loading branch information
Showing
6 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "x" | ||
version = "0.1.0" | ||
description = "Run x.py slightly more conveniently" | ||
authors = ["Casey Rodarmor <casey@rodarmor.com>"] | ||
edition = "2018" | ||
publish = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# x | ||
|
||
`x` invokes `x.py` from any subdirectory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//! 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) { | ||
if dir.join(PYTHON).exists() { | ||
return PYTHON; | ||
} | ||
|
||
python2 |= dir.join(PYTHON2).exists(); | ||
python3 |= dir.join(PYTHON3).exists(); | ||
} | ||
|
||
if python3 { | ||
PYTHON3 | ||
} else if python2 { | ||
PYTHON2 | ||
} else { | ||
PYTHON | ||
} | ||
} | ||
|
||
#[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); | ||
} |