aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model/src/cargo_workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/project_model/src/cargo_workspace.rs')
-rw-r--r--crates/project_model/src/cargo_workspace.rs30
1 files changed, 22 insertions, 8 deletions
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index 0e6679542..c0ed37fc1 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -3,18 +3,20 @@
3use std::{ 3use std::{
4 convert::TryInto, 4 convert::TryInto,
5 ffi::OsStr, 5 ffi::OsStr,
6 io::BufReader,
6 ops, 7 ops,
7 path::{Path, PathBuf}, 8 path::{Path, PathBuf},
8 process::Command, 9 process::{Command, Stdio},
9}; 10};
10 11
11use anyhow::{Context, Result}; 12use anyhow::{Context, Result};
12use arena::{Arena, Idx};
13use base_db::Edition; 13use base_db::Edition;
14use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; 14use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId};
15use itertools::Itertools; 15use itertools::Itertools;
16use la_arena::{Arena, Idx};
16use paths::{AbsPath, AbsPathBuf}; 17use paths::{AbsPath, AbsPathBuf};
17use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19use stdx::JodChild;
18 20
19use crate::cfg_flag::CfgFlag; 21use crate::cfg_flag::CfgFlag;
20use crate::utf8_stdout; 22use crate::utf8_stdout;
@@ -171,6 +173,7 @@ impl CargoWorkspace {
171 pub fn from_cargo_metadata( 173 pub fn from_cargo_metadata(
172 cargo_toml: &AbsPath, 174 cargo_toml: &AbsPath,
173 config: &CargoConfig, 175 config: &CargoConfig,
176 progress: &dyn Fn(String),
174 ) -> Result<CargoWorkspace> { 177 ) -> Result<CargoWorkspace> {
175 let mut meta = MetadataCommand::new(); 178 let mut meta = MetadataCommand::new();
176 meta.cargo_path(toolchain::cargo()); 179 meta.cargo_path(toolchain::cargo());
@@ -220,6 +223,9 @@ impl CargoWorkspace {
220 meta.other_options(vec![String::from("--filter-platform"), target]); 223 meta.other_options(vec![String::from("--filter-platform"), target]);
221 } 224 }
222 225
226 // FIXME: Currently MetadataCommand is not based on parse_stream,
227 // So we just report it as a whole
228 progress("metadata".to_string());
223 let mut meta = meta.exec().with_context(|| { 229 let mut meta = meta.exec().with_context(|| {
224 let cwd: Option<AbsPathBuf> = 230 let cwd: Option<AbsPathBuf> =
225 std::env::current_dir().ok().and_then(|p| p.try_into().ok()); 231 std::env::current_dir().ok().and_then(|p| p.try_into().ok());
@@ -243,7 +249,7 @@ impl CargoWorkspace {
243 let mut envs = FxHashMap::default(); 249 let mut envs = FxHashMap::default();
244 let mut proc_macro_dylib_paths = FxHashMap::default(); 250 let mut proc_macro_dylib_paths = FxHashMap::default();
245 if config.load_out_dirs_from_check { 251 if config.load_out_dirs_from_check {
246 let resources = load_extern_resources(cargo_toml, config)?; 252 let resources = load_extern_resources(cargo_toml, config, progress)?;
247 out_dir_by_id = resources.out_dirs; 253 out_dir_by_id = resources.out_dirs;
248 cfgs = resources.cfgs; 254 cfgs = resources.cfgs;
249 envs = resources.env; 255 envs = resources.env;
@@ -368,9 +374,10 @@ pub(crate) struct ExternResources {
368pub(crate) fn load_extern_resources( 374pub(crate) fn load_extern_resources(
369 cargo_toml: &Path, 375 cargo_toml: &Path,
370 cargo_features: &CargoConfig, 376 cargo_features: &CargoConfig,
377 progress: &dyn Fn(String),
371) -> Result<ExternResources> { 378) -> Result<ExternResources> {
372 let mut cmd = Command::new(toolchain::cargo()); 379 let mut cmd = Command::new(toolchain::cargo());
373 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml); 380 cmd.args(&["check", "--workspace", "--message-format=json", "--manifest-path"]).arg(cargo_toml);
374 381
375 // --all-targets includes tests, benches and examples in addition to the 382 // --all-targets includes tests, benches and examples in addition to the
376 // default lib and bins. This is an independent concept from the --targets 383 // default lib and bins. This is an independent concept from the --targets
@@ -395,11 +402,14 @@ pub(crate) fn load_extern_resources(
395 } 402 }
396 } 403 }
397 404
398 let output = cmd.output()?; 405 cmd.stdout(Stdio::piped()).stderr(Stdio::null()).stdin(Stdio::null());
399 406
400 let mut res = ExternResources::default(); 407 let mut child = cmd.spawn().map(JodChild)?;
408 let child_stdout = child.stdout.take().unwrap();
409 let stdout = BufReader::new(child_stdout);
401 410
402 for message in cargo_metadata::Message::parse_stream(output.stdout.as_slice()) { 411 let mut res = ExternResources::default();
412 for message in cargo_metadata::Message::parse_stream(stdout) {
403 if let Ok(message) = message { 413 if let Ok(message) = message {
404 match message { 414 match message {
405 Message::BuildScriptExecuted(BuildScript { 415 Message::BuildScriptExecuted(BuildScript {
@@ -432,6 +442,8 @@ pub(crate) fn load_extern_resources(
432 res.env.insert(package_id, env); 442 res.env.insert(package_id, env);
433 } 443 }
434 Message::CompilerArtifact(message) => { 444 Message::CompilerArtifact(message) => {
445 progress(format!("metadata {}", message.target.name));
446
435 if message.target.kind.contains(&"proc-macro".to_string()) { 447 if message.target.kind.contains(&"proc-macro".to_string()) {
436 let package_id = message.package_id; 448 let package_id = message.package_id;
437 // Skip rmeta file 449 // Skip rmeta file
@@ -442,7 +454,9 @@ pub(crate) fn load_extern_resources(
442 } 454 }
443 } 455 }
444 } 456 }
445 Message::CompilerMessage(_) => (), 457 Message::CompilerMessage(message) => {
458 progress(message.target.name.clone());
459 }
446 Message::Unknown => (), 460 Message::Unknown => (),
447 Message::BuildFinished(_) => {} 461 Message::BuildFinished(_) => {}
448 Message::TextLine(_) => {} 462 Message::TextLine(_) => {}