aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_toolchain/src/lib.rs55
1 files changed, 28 insertions, 27 deletions
diff --git a/crates/ra_toolchain/src/lib.rs b/crates/ra_toolchain/src/lib.rs
index 110c92c88..afa76619d 100644
--- a/crates/ra_toolchain/src/lib.rs
+++ b/crates/ra_toolchain/src/lib.rs
@@ -14,7 +14,8 @@ use anyhow::{bail, Result};
14/// E.g., `get_path_for_executable("cargo")` may return just `cargo` if that 14/// E.g., `get_path_for_executable("cargo")` may return just `cargo` if that
15/// gives a valid Cargo executable; or it may return a full path to a valid 15/// gives a valid Cargo executable; or it may return a full path to a valid
16/// Cargo. 16/// Cargo.
17pub fn get_path_for_executable(executable_name: impl AsRef<str>) -> Result<PathBuf> { 17pub fn get_path_for_executable(executable_name: &'static str) -> Result<PathBuf> {
18 assert!(executable_name == "rustc" || executable_name == "cargo");
18 // The current implementation checks three places for an executable to use: 19 // The current implementation checks three places for an executable to use:
19 // 1) Appropriate environment variable (erroring if this is set but not a usable executable) 20 // 1) Appropriate environment variable (erroring if this is set but not a usable executable)
20 // example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc 21 // example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
@@ -23,46 +24,46 @@ pub fn get_path_for_executable(executable_name: impl AsRef<str>) -> Result<PathB
23 // 3) `~/.cargo/bin/<executable_name>` 24 // 3) `~/.cargo/bin/<executable_name>`
24 // example: for cargo, this tries ~/.cargo/bin/cargo 25 // example: for cargo, this tries ~/.cargo/bin/cargo
25 // It seems that this is a reasonable place to try for cargo, rustc, and rustup 26 // It seems that this is a reasonable place to try for cargo, rustc, and rustup
26 let executable_name = executable_name.as_ref();
27 let env_var = executable_name.to_ascii_uppercase(); 27 let env_var = executable_name.to_ascii_uppercase();
28 if let Ok(path) = env::var(&env_var) { 28 if let Ok(path) = env::var(&env_var) {
29 if is_valid_executable(&path) { 29 return if is_valid_executable(&path) {
30 Ok(path.into()) 30 Ok(path.into())
31 } else { 31 } else {
32 bail!( 32 bail!(
33 "`{}` environment variable points to something that's not a valid executable", 33 "`{}` environment variable points to something that's not a valid executable",
34 env_var 34 env_var
35 ) 35 )
36 };
37 }
38
39 if is_valid_executable(executable_name) {
40 return Ok(executable_name.into());
41 }
42
43 if let Some(mut path) = home::home_dir() {
44 path.push(".cargo");
45 path.push("bin");
46 path.push(executable_name);
47 if is_valid_executable(&path) {
48 return Ok(path);
36 } 49 }
37 } else {
38 if is_valid_executable(executable_name) {
39 return Ok(executable_name.into());
40 }
41 if let Some(mut path) = ::home::home_dir() {
42 path.push(".cargo");
43 path.push("bin");
44 path.push(executable_name);
45 if is_valid_executable(&path) {
46 return Ok(path);
47 }
48 }
49 // This error message may also be caused by $PATH or $CARGO/$RUSTC/etc not being set correctly
50 // for VSCode, even if they are set correctly in a terminal.
51 // On macOS in particular, launching VSCode from terminal with `code <dirname>` causes VSCode
52 // to inherit environment variables including $PATH, $CARGO, $RUSTC, etc from that terminal;
53 // but launching VSCode from Dock does not inherit environment variables from a terminal.
54 // For more discussion, see #3118.
55 bail!(
56 "Failed to find `{}` executable. Make sure `{}` is in `$PATH`, or set `${}` to point to a valid executable.",
57 executable_name, executable_name, env_var
58 )
59 } 50 }
51 // This error message may also be caused by $PATH or $CARGO/$RUSTC/etc not being set correctly
52 // for VSCode, even if they are set correctly in a terminal.
53 // On macOS in particular, launching VSCode from terminal with `code <dirname>` causes VSCode
54 // to inherit environment variables including $PATH, $CARGO, $RUSTC, etc from that terminal;
55 // but launching VSCode from Dock does not inherit environment variables from a terminal.
56 // For more discussion, see #3118.
57 bail!(
58 "Failed to find `{}` executable. Make sure `{}` is in `$PATH`, or set `${}` to point to a valid executable.",
59 executable_name, executable_name, env_var
60 )
60} 61}
61 62
62/// Does the given `Path` point to a usable executable? 63/// Does the given `Path` point to a usable executable?
63/// 64///
64/// (assumes the executable takes a `--version` switch and writes to stdout, 65/// (assumes the executable takes a `--version` switch and writes to stdout,
65/// which is true for `cargo`, `rustc`, and `rustup`) 66/// which is true for `cargo`, `rustc`, and `rustup`)
66fn is_valid_executable(p: impl AsRef<Path>) -> bool { 67fn is_valid_executable(p: &'static str) -> bool {
67 Command::new(p.as_ref()).arg("--version").output().is_ok() 68 Command::new(p).arg("--version").output().is_ok()
68} 69}