aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Disselkoen <[email protected]>2020-05-05 19:59:41 +0100
committerCraig Disselkoen <[email protected]>2020-05-06 00:12:56 +0100
commitffaef1b7aeb61984992e231d9af20f39486403ea (patch)
tree2ed0d69b8b96b0e8e7a474c342eb26de9a2c35e0
parent30eb458b4fa8adcecd8cbf731bd1cfa9a7a8b88b (diff)
ra_project_model: look for Cargo in more places
See #3118
-rw-r--r--Cargo.lock77
-rw-r--r--crates/ra_project_model/Cargo.toml2
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs59
3 files changed, 128 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5d50a766f..b2d4569b3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -22,6 +22,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
22checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" 22checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
23 23
24[[package]] 24[[package]]
25name = "arrayref"
26version = "0.3.6"
27source = "registry+https://github.com/rust-lang/crates.io-index"
28checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
29
30[[package]]
25name = "arrayvec" 31name = "arrayvec"
26version = "0.5.1" 32version = "0.5.1"
27source = "registry+https://github.com/rust-lang/crates.io-index" 33source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -68,6 +74,12 @@ dependencies = [
68 74
69[[package]] 75[[package]]
70name = "base64" 76name = "base64"
77version = "0.11.0"
78source = "registry+https://github.com/rust-lang/crates.io-index"
79checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
80
81[[package]]
82name = "base64"
71version = "0.12.0" 83version = "0.12.0"
72source = "registry+https://github.com/rust-lang/crates.io-index" 84source = "registry+https://github.com/rust-lang/crates.io-index"
73checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3" 85checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3"
@@ -79,6 +91,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
79checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 91checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
80 92
81[[package]] 93[[package]]
94name = "blake2b_simd"
95version = "0.5.10"
96source = "registry+https://github.com/rust-lang/crates.io-index"
97checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
98dependencies = [
99 "arrayref",
100 "arrayvec",
101 "constant_time_eq",
102]
103
104[[package]]
82name = "bstr" 105name = "bstr"
83version = "0.2.12" 106version = "0.2.12"
84source = "registry+https://github.com/rust-lang/crates.io-index" 107source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -213,6 +236,12 @@ dependencies = [
213] 236]
214 237
215[[package]] 238[[package]]
239name = "constant_time_eq"
240version = "0.1.5"
241source = "registry+https://github.com/rust-lang/crates.io-index"
242checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
243
244[[package]]
216name = "crossbeam" 245name = "crossbeam"
217version = "0.7.3" 246version = "0.7.3"
218source = "registry+https://github.com/rust-lang/crates.io-index" 247source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -290,6 +319,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
290checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 319checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
291 320
292[[package]] 321[[package]]
322name = "dirs"
323version = "2.0.2"
324source = "registry+https://github.com/rust-lang/crates.io-index"
325checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
326dependencies = [
327 "cfg-if",
328 "dirs-sys",
329]
330
331[[package]]
332name = "dirs-sys"
333version = "0.3.4"
334source = "registry+https://github.com/rust-lang/crates.io-index"
335checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
336dependencies = [
337 "cfg-if",
338 "libc",
339 "redox_users",
340 "winapi 0.3.8",
341]
342
343[[package]]
293name = "drop_bomb" 344name = "drop_bomb"
294version = "0.1.4" 345version = "0.1.4"
295source = "registry+https://github.com/rust-lang/crates.io-index" 346source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -659,7 +710,7 @@ version = "0.74.1"
659source = "registry+https://github.com/rust-lang/crates.io-index" 710source = "registry+https://github.com/rust-lang/crates.io-index"
660checksum = "57c0e6a2b8837d27b29deb3f3e6dc1c6d2f57947677f9be1024e482ec5b59525" 711checksum = "57c0e6a2b8837d27b29deb3f3e6dc1c6d2f57947677f9be1024e482ec5b59525"
661dependencies = [ 712dependencies = [
662 "base64", 713 "base64 0.12.0",
663 "bitflags", 714 "bitflags",
664 "serde", 715 "serde",
665 "serde_json", 716 "serde_json",
@@ -1158,6 +1209,7 @@ version = "0.1.0"
1158dependencies = [ 1209dependencies = [
1159 "anyhow", 1210 "anyhow",
1160 "cargo_metadata", 1211 "cargo_metadata",
1212 "dirs",
1161 "log", 1213 "log",
1162 "ra_arena", 1214 "ra_arena",
1163 "ra_cfg", 1215 "ra_cfg",
@@ -1299,6 +1351,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1299checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1351checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
1300 1352
1301[[package]] 1353[[package]]
1354name = "redox_users"
1355version = "0.3.4"
1356source = "registry+https://github.com/rust-lang/crates.io-index"
1357checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
1358dependencies = [
1359 "getrandom",
1360 "redox_syscall",
1361 "rust-argon2",
1362]
1363
1364[[package]]
1302name = "regex" 1365name = "regex"
1303version = "1.3.7" 1366version = "1.3.7"
1304source = "registry+https://github.com/rust-lang/crates.io-index" 1367source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1383,6 +1446,18 @@ dependencies = [
1383] 1446]
1384 1447
1385[[package]] 1448[[package]]
1449name = "rust-argon2"
1450version = "0.7.0"
1451source = "registry+https://github.com/rust-lang/crates.io-index"
1452checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
1453dependencies = [
1454 "base64 0.11.0",
1455 "blake2b_simd",
1456 "constant_time_eq",
1457 "crossbeam-utils",
1458]
1459
1460[[package]]
1386name = "rustc-ap-rustc_lexer" 1461name = "rustc-ap-rustc_lexer"
1387version = "656.0.0" 1462version = "656.0.0"
1388source = "registry+https://github.com/rust-lang/crates.io-index" 1463source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index 5e651fe70..91958ed94 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -22,3 +22,5 @@ serde = { version = "1.0.106", features = ["derive"] }
22serde_json = "1.0.48" 22serde_json = "1.0.48"
23 23
24anyhow = "1.0.26" 24anyhow = "1.0.26"
25
26dirs = "2.0"
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 59f46a2a0..a15a8c68e 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -8,7 +8,7 @@ use std::{
8 process::Command, 8 process::Command,
9}; 9};
10 10
11use anyhow::{Context, Result}; 11use anyhow::{Context, Error, Result};
12use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; 12use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId};
13use ra_arena::{Arena, Idx}; 13use ra_arena::{Arena, Idx};
14use ra_db::Edition; 14use ra_db::Edition;
@@ -145,12 +145,8 @@ impl CargoWorkspace {
145 cargo_toml: &Path, 145 cargo_toml: &Path,
146 cargo_features: &CargoConfig, 146 cargo_features: &CargoConfig,
147 ) -> Result<CargoWorkspace> { 147 ) -> Result<CargoWorkspace> {
148 let _ = Command::new(cargo_binary())
149 .arg("--version")
150 .output()
151 .context("failed to run `cargo --version`, is `cargo` in PATH?")?;
152
153 let mut meta = MetadataCommand::new(); 148 let mut meta = MetadataCommand::new();
149 meta.cargo_path(cargo_binary()?);
154 meta.manifest_path(cargo_toml); 150 meta.manifest_path(cargo_toml);
155 if cargo_features.all_features { 151 if cargo_features.all_features {
156 meta.features(CargoOpt::AllFeatures); 152 meta.features(CargoOpt::AllFeatures);
@@ -288,7 +284,7 @@ pub fn load_extern_resources(
288 cargo_toml: &Path, 284 cargo_toml: &Path,
289 cargo_features: &CargoConfig, 285 cargo_features: &CargoConfig,
290) -> Result<ExternResources> { 286) -> Result<ExternResources> {
291 let mut cmd = Command::new(cargo_binary()); 287 let mut cmd = Command::new(cargo_binary()?);
292 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml); 288 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml);
293 if cargo_features.all_features { 289 if cargo_features.all_features {
294 cmd.arg("--all-features"); 290 cmd.arg("--all-features");
@@ -337,6 +333,51 @@ fn is_dylib(path: &Path) -> bool {
337 } 333 }
338} 334}
339 335
340fn cargo_binary() -> String { 336/// Return a `String` to use for executable `cargo`.
341 env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()) 337///
338/// E.g., this may just be `cargo` if that gives a valid Cargo executable; or it
339/// may be a full path to a valid Cargo.
340fn cargo_binary() -> Result<String> {
341 // The current implementation checks three places for a `cargo` to use:
342 // 1) $CARGO environment variable (erroring if this is set but not a usable Cargo)
343 // 2) `cargo`
344 // 3) `~/.cargo/bin/cargo`
345 if let Ok(path) = env::var("CARGO") {
346 if is_valid_cargo(&path) {
347 Ok(path)
348 } else {
349 Err(Error::msg("`CARGO` environment variable points to something that's not a valid Cargo executable"))
350 }
351 } else {
352 let final_path: Option<String> = if is_valid_cargo("cargo") {
353 Some("cargo".to_owned())
354 } else {
355 if let Some(mut path) = dirs::home_dir() {
356 path.push(".cargo");
357 path.push("bin");
358 path.push("cargo");
359 if is_valid_cargo(&path) {
360 Some(path.into_os_string().into_string().expect("Invalid Unicode in path"))
361 } else {
362 None
363 }
364 } else {
365 None
366 }
367 };
368 final_path.ok_or(
369 // This error message may also be caused by $PATH or $CARGO not being set correctly for VSCode,
370 // even if they are set correctly in a terminal.
371 // On macOS in particular, launching VSCode from terminal with `code <dirname>` causes VSCode
372 // to inherit environment variables including $PATH and $CARGO from that terminal; but
373 // launching VSCode from Dock does not inherit environment variables from a terminal.
374 // For more discussion, see #3118.
375 Error::msg("Failed to find `cargo` executable. Make sure `cargo` is in `$PATH`, or set `$CARGO` to point to a valid Cargo executable.")
376 )
377 }
378}
379
380/// Does the given `Path` point to a usable `Cargo`?
381fn is_valid_cargo(p: impl AsRef<Path>) -> bool {
382 Command::new(p.as_ref()).arg("--version").output().is_ok()
342} 383}