Skip to content

Commit c310aee

Browse files
committed
For toolchain binaries ue the full path found in $PATH
1 parent fe0daa7 commit c310aee

File tree

7 files changed

+63
-67
lines changed

7 files changed

+63
-67
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ide/src/expand_macro.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ fn _format(
189189
let &crate_id = db.relevant_crates(file_id).iter().next()?;
190190
let edition = db.crate_graph()[crate_id].edition;
191191

192-
let mut cmd = std::process::Command::new(toolchain::rustfmt());
192+
let mut cmd = std::process::Command::new(toolchain::Tool::Rustfmt.path());
193193
cmd.arg("--edition");
194194
cmd.arg(edition.to_string());
195195

crates/proc-macro-srv/proc-macro-test/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,3 @@ doctest = false
1111

1212
[build-dependencies]
1313
cargo_metadata = "0.18.1"
14-
15-
# local deps
16-
toolchain.workspace = true

crates/proc-macro-srv/proc-macro-test/build.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ use cargo_metadata::Message;
1818
fn main() {
1919
println!("cargo:rerun-if-changed=imp");
2020

21+
let cargo = env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
22+
2123
let has_features = env::var_os("RUSTC_BOOTSTRAP").is_some()
22-
|| String::from_utf8(
23-
Command::new(toolchain::cargo()).arg("--version").output().unwrap().stdout,
24-
)
25-
.unwrap()
26-
.contains("nightly");
24+
|| String::from_utf8(Command::new(&cargo).arg("--version").output().unwrap().stdout)
25+
.unwrap()
26+
.contains("nightly");
2727

2828
let out_dir = env::var_os("OUT_DIR").unwrap();
2929
let out_dir = Path::new(&out_dir);
@@ -66,7 +66,7 @@ fn main() {
6666

6767
let target_dir = out_dir.join("target");
6868

69-
let mut cmd = Command::new(toolchain::cargo());
69+
let mut cmd = Command::new(&cargo);
7070
cmd.current_dir(&staging_dir)
7171
.args(["build", "-p", "proc-macro-test-impl", "--message-format", "json"])
7272
// Explicit override the target directory to avoid using the same one which the parent
@@ -96,7 +96,7 @@ fn main() {
9696
let repr = format!("{name} {version}");
9797
// New Package Id Spec since rust-lang/cargo#13311
9898
let pkgid = String::from_utf8(
99-
Command::new(toolchain::cargo())
99+
Command::new(cargo)
100100
.current_dir(&staging_dir)
101101
.args(["pkgid", name])
102102
.output()

crates/project-model/src/sysroot.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use itertools::Itertools;
1212
use la_arena::{Arena, Idx};
1313
use paths::{AbsPath, AbsPathBuf};
1414
use rustc_hash::FxHashMap;
15-
use toolchain::probe_for_binary;
15+
use toolchain::{probe_for_binary, Tool};
1616

1717
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath};
1818

@@ -411,7 +411,7 @@ fn discover_sysroot_dir(
411411
current_dir: &AbsPath,
412412
extra_env: &FxHashMap<String, String>,
413413
) -> Result<AbsPathBuf> {
414-
let mut rustc = Command::new(toolchain::rustc());
414+
let mut rustc = Command::new(Tool::Rustc.path());
415415
rustc.envs(extra_env);
416416
rustc.current_dir(current_dir).args(["--print", "sysroot"]);
417417
tracing::debug!("Discovering sysroot by {:?}", rustc);
@@ -443,7 +443,7 @@ fn discover_sysroot_src_dir_or_add_component(
443443
) -> Result<AbsPathBuf> {
444444
discover_sysroot_src_dir(sysroot_path)
445445
.or_else(|| {
446-
let mut rustup = Command::new(toolchain::rustup());
446+
let mut rustup = Command::new(Tool::Rustup.prefer_proxy());
447447
rustup.envs(extra_env);
448448
rustup.current_dir(current_dir).args(["component", "add", "rust-src"]);
449449
tracing::info!("adding rust-src component by {:?}", rustup);

crates/rust-analyzer/src/handlers/request.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ fn run_rustfmt(
19371937
let mut command = match snap.config.rustfmt() {
19381938
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
19391939
// FIXME: Set RUSTUP_TOOLCHAIN
1940-
let mut cmd = process::Command::new(toolchain::rustfmt());
1940+
let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path());
19411941
cmd.envs(snap.config.extra_env());
19421942
cmd.args(extra_args);
19431943

crates/toolchain/src/lib.rs

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,42 @@ pub enum Tool {
1616
}
1717

1818
impl Tool {
19+
pub fn proxy(self) -> Option<PathBuf> {
20+
cargo_proxy(self.name())
21+
}
22+
23+
/// Return a `PathBuf` to use for the given executable.
24+
///
25+
/// The current implementation checks three places for an executable to use:
26+
/// 1) `$CARGO_HOME/bin/<executable_name>`
27+
/// where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
28+
/// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
29+
/// It seems that this is a reasonable place to try for cargo, rustc, and rustup
30+
/// 2) Appropriate environment variable (erroring if this is set but not a usable executable)
31+
/// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
32+
/// 3) $PATH/`<executable_name>`
33+
/// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the
34+
/// first that exists
35+
/// 4) If all else fails, we just try to use the executable name directly
36+
pub fn prefer_proxy(self) -> PathBuf {
37+
invoke(&[cargo_proxy, lookup_as_env_var, lookup_in_path], self.name())
38+
}
39+
40+
/// Return a `PathBuf` to use for the given executable.
41+
///
42+
/// The current implementation checks three places for an executable to use:
43+
/// 1) Appropriate environment variable (erroring if this is set but not a usable executable)
44+
/// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
45+
/// 2) $PATH/`<executable_name>`
46+
/// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the
47+
/// first that exists
48+
/// 3) `$CARGO_HOME/bin/<executable_name>`
49+
/// where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
50+
/// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
51+
/// It seems that this is a reasonable place to try for cargo, rustc, and rustup
52+
/// 4) If all else fails, we just try to use the executable name directly
1953
pub fn path(self) -> PathBuf {
20-
get_path_for_executable(self.name())
54+
invoke(&[lookup_as_env_var, lookup_in_path, cargo_proxy], self.name())
2155
}
2256

2357
pub fn path_in(self, path: &Path) -> Option<PathBuf> {
@@ -38,60 +72,21 @@ impl Tool {
3872
}
3973
}
4074

41-
pub fn cargo() -> PathBuf {
42-
get_path_for_executable("cargo")
43-
}
44-
45-
pub fn rustc() -> PathBuf {
46-
get_path_for_executable("rustc")
75+
fn invoke(list: &[fn(&str) -> Option<PathBuf>], executable: &str) -> PathBuf {
76+
list.iter().find_map(|it| it(executable)).unwrap_or_else(|| executable.into())
4777
}
4878

49-
pub fn rustup() -> PathBuf {
50-
get_path_for_executable("rustup")
79+
/// Looks up the binary as its SCREAMING upper case in the env variables.
80+
fn lookup_as_env_var(executable_name: &str) -> Option<PathBuf> {
81+
env::var_os(executable_name.to_ascii_uppercase()).map(Into::into)
5182
}
5283

53-
pub fn rustfmt() -> PathBuf {
54-
get_path_for_executable("rustfmt")
55-
}
56-
57-
/// Return a `PathBuf` to use for the given executable.
58-
///
59-
/// E.g., `get_path_for_executable("cargo")` may return just `cargo` if that
60-
/// gives a valid Cargo executable; or it may return a full path to a valid
61-
/// Cargo.
62-
fn get_path_for_executable(executable_name: &'static str) -> PathBuf {
63-
// The current implementation checks three places for an executable to use:
64-
// 1) Appropriate environment variable (erroring if this is set but not a usable executable)
65-
// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
66-
// 2) `<executable_name>`
67-
// example: for cargo, this tries just `cargo`, which will succeed if `cargo` is on the $PATH
68-
// 3) `$CARGO_HOME/bin/<executable_name>`
69-
// where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
70-
// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
71-
// It seems that this is a reasonable place to try for cargo, rustc, and rustup
72-
let env_var = executable_name.to_ascii_uppercase();
73-
if let Some(path) = env::var_os(env_var) {
74-
return path.into();
75-
}
76-
77-
if lookup_in_path(executable_name) {
78-
return executable_name.into();
79-
}
80-
81-
if let Some(mut path) = get_cargo_home() {
82-
path.push("bin");
83-
path.push(executable_name);
84-
if let Some(path) = probe_for_binary(path) {
85-
return path;
86-
}
87-
}
88-
89-
executable_name.into()
90-
}
91-
92-
fn lookup_in_path(exec: &str) -> bool {
93-
let paths = env::var_os("PATH").unwrap_or_default();
94-
env::split_paths(&paths).map(|path| path.join(exec)).find_map(probe_for_binary).is_some()
84+
/// Looks up the binary in the cargo home directory if it exists.
85+
fn cargo_proxy(executable_name: &str) -> Option<PathBuf> {
86+
let mut path = get_cargo_home()?;
87+
path.push("bin");
88+
path.push(executable_name);
89+
probe_for_binary(path)
9590
}
9691

9792
fn get_cargo_home() -> Option<PathBuf> {
@@ -107,6 +102,11 @@ fn get_cargo_home() -> Option<PathBuf> {
107102
None
108103
}
109104

105+
fn lookup_in_path(exec: &str) -> Option<PathBuf> {
106+
let paths = env::var_os("PATH").unwrap_or_default();
107+
env::split_paths(&paths).map(|path| path.join(exec)).find_map(probe_for_binary)
108+
}
109+
110110
pub fn probe_for_binary(path: PathBuf) -> Option<PathBuf> {
111111
let with_extension = match env::consts::EXE_EXTENSION {
112112
"" => None,

0 commit comments

Comments
 (0)