aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_flycheck/src/lib.rs2
-rw-r--r--crates/ra_project_model/Cargo.toml1
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs75
4 files changed, 40 insertions, 39 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bdbb316cd..9a1a05683 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1103,7 +1103,6 @@ dependencies = [
1103 "ra_arena", 1103 "ra_arena",
1104 "ra_cfg", 1104 "ra_cfg",
1105 "ra_db", 1105 "ra_db",
1106 "ra_flycheck",
1107 "ra_proc_macro", 1106 "ra_proc_macro",
1108 "rustc-hash", 1107 "rustc-hash",
1109 "serde", 1108 "serde",
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_flycheck/src/lib.rs
index 77ede8f63..38940a77b 100644
--- a/crates/ra_flycheck/src/lib.rs
+++ b/crates/ra_flycheck/src/lib.rs
@@ -243,7 +243,7 @@ impl fmt::Display for CargoError {
243} 243}
244impl error::Error for CargoError {} 244impl error::Error for CargoError {}
245 245
246pub fn run_cargo( 246fn run_cargo(
247 args: &[String], 247 args: &[String],
248 current_dir: Option<&Path>, 248 current_dir: Option<&Path>,
249 on_message: &mut dyn FnMut(cargo_metadata::Message) -> bool, 249 on_message: &mut dyn FnMut(cargo_metadata::Message) -> bool,
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index c3b7a8f74..b10644b4b 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -16,7 +16,6 @@ cargo_metadata = "0.9.1"
16ra_arena = { path = "../ra_arena" } 16ra_arena = { path = "../ra_arena" }
17ra_db = { path = "../ra_db" } 17ra_db = { path = "../ra_db" }
18ra_cfg = { path = "../ra_cfg" } 18ra_cfg = { path = "../ra_cfg" }
19ra_flycheck = { path = "../ra_flycheck" }
20ra_proc_macro = { path = "../ra_proc_macro" } 19ra_proc_macro = { path = "../ra_proc_macro" }
21 20
22serde = { version = "1.0.104", features = ["derive"] } 21serde = { version = "1.0.104", features = ["derive"] }
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 78ea2ab58..f4fd6ad28 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,16 +1,17 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{ 3use std::{
4 env,
4 ffi::OsStr, 5 ffi::OsStr,
5 ops, 6 ops,
6 path::{Path, PathBuf}, 7 path::{Path, PathBuf},
8 process::Command,
7}; 9};
8 10
9use anyhow::{Context, Result}; 11use anyhow::{Context, Result};
10use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; 12use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId};
11use ra_arena::{Arena, Idx}; 13use ra_arena::{Arena, Idx};
12use ra_db::Edition; 14use ra_db::Edition;
13use ra_flycheck::run_cargo;
14use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
15use serde::Deserialize; 16use serde::Deserialize;
16 17
@@ -163,7 +164,7 @@ impl CargoWorkspace {
163 let mut out_dir_by_id = FxHashMap::default(); 164 let mut out_dir_by_id = FxHashMap::default();
164 let mut proc_macro_dylib_paths = FxHashMap::default(); 165 let mut proc_macro_dylib_paths = FxHashMap::default();
165 if cargo_features.load_out_dirs_from_check { 166 if cargo_features.load_out_dirs_from_check {
166 let resources = load_extern_resources(cargo_toml, cargo_features); 167 let resources = load_extern_resources(cargo_toml, cargo_features)?;
167 out_dir_by_id = resources.out_dirs; 168 out_dir_by_id = resources.out_dirs;
168 proc_macro_dylib_paths = resources.proc_dylib_paths; 169 proc_macro_dylib_paths = resources.proc_dylib_paths;
169 } 170 }
@@ -272,53 +273,51 @@ pub struct ExternResources {
272 proc_dylib_paths: FxHashMap<PackageId, PathBuf>, 273 proc_dylib_paths: FxHashMap<PackageId, PathBuf>,
273} 274}
274 275
275pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures) -> ExternResources { 276pub fn load_extern_resources(
276 let mut args: Vec<String> = vec![ 277 cargo_toml: &Path,
277 "check".to_string(), 278 cargo_features: &CargoFeatures,
278 "--message-format=json".to_string(), 279) -> Result<ExternResources> {
279 "--manifest-path".to_string(), 280 let mut cmd = Command::new(cargo_binary());
280 cargo_toml.display().to_string(), 281 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml);
281 ];
282
283 if cargo_features.all_features { 282 if cargo_features.all_features {
284 args.push("--all-features".to_string()); 283 cmd.arg("--all-features");
285 } else if cargo_features.no_default_features { 284 } else if cargo_features.no_default_features {
286 // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures` 285 // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
287 // https://github.com/oli-obk/cargo_metadata/issues/79 286 // https://github.com/oli-obk/cargo_metadata/issues/79
288 args.push("--no-default-features".to_string()); 287 cmd.arg("--no-default-features");
289 } else { 288 } else {
290 args.extend(cargo_features.features.iter().cloned()); 289 cmd.args(&cargo_features.features);
291 } 290 }
292 291
293 let mut acc = ExternResources::default(); 292 let output = cmd.output()?;
294 let res = run_cargo(&args, cargo_toml.parent(), &mut |message| { 293
295 match message { 294 let mut res = ExternResources::default();
296 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { 295
297 acc.out_dirs.insert(package_id, out_dir); 296 let stdout = String::from_utf8(output.stdout)?;
298 } 297 for line in stdout.lines() {
298 if let Ok(message) = serde_json::from_str::<cargo_metadata::Message>(&line) {
299 match message {
300 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => {
301 res.out_dirs.insert(package_id, out_dir);
302 }
299 303
300 Message::CompilerArtifact(message) => { 304 Message::CompilerArtifact(message) => {
301 if message.target.kind.contains(&"proc-macro".to_string()) { 305 if message.target.kind.contains(&"proc-macro".to_string()) {
302 let package_id = message.package_id; 306 let package_id = message.package_id;
303 // Skip rmeta file 307 // Skip rmeta file
304 if let Some(filename) = 308 if let Some(filename) =
305 message.filenames.iter().filter(|name| is_dylib(name)).next() 309 message.filenames.iter().filter(|name| is_dylib(name)).next()
306 { 310 {
307 acc.proc_dylib_paths.insert(package_id, filename.clone()); 311 res.proc_dylib_paths.insert(package_id, filename.clone());
312 }
308 } 313 }
309 } 314 }
315 Message::CompilerMessage(_) => (),
316 Message::Unknown => (),
310 } 317 }
311 Message::CompilerMessage(_) => (),
312 Message::Unknown => (),
313 } 318 }
314 true
315 });
316
317 if let Err(err) = res {
318 log::error!("Failed to load outdirs: {:?}", err);
319 } 319 }
320 320 Ok(res)
321 acc
322} 321}
323 322
324// FIXME: File a better way to know if it is a dylib 323// FIXME: File a better way to know if it is a dylib
@@ -328,3 +327,7 @@ fn is_dylib(path: &Path) -> bool {
328 Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"), 327 Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"),
329 } 328 }
330} 329}
330
331fn cargo_binary() -> String {
332 env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())
333}