aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-03-31 17:43:22 +0100
committerAleksey Kladov <[email protected]>2020-03-31 18:29:11 +0100
commit8d278297815e9034cc52670b468732e7d7ff7d55 (patch)
tree5d0ae6e3e1184b00cdfc293c12525fa90cb79f4d /crates/ra_project_model/src
parent37a01de42c1bd435710741a2e15ceee1efaccf39 (diff)
Reduce deps
Diffstat (limited to 'crates/ra_project_model/src')
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs75
1 files changed, 39 insertions, 36 deletions
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}