From af4eb266457eb784010da28d80535f9fd38d4d1e Mon Sep 17 00:00:00 2001 From: oxalica Date: Fri, 13 Dec 2019 18:16:34 +0800 Subject: Support setting cargo features --- crates/ra_project_model/src/cargo_workspace.rs | 31 ++++++++++++++++++++++++-- crates/ra_project_model/src/lib.rs | 14 +++++++----- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'crates/ra_project_model/src') diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 351997dcd..4a0437da3 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -6,6 +6,7 @@ use cargo_metadata::{CargoOpt, MetadataCommand}; use ra_arena::{impl_arena_id, Arena, RawId}; use ra_db::Edition; use rustc_hash::FxHashMap; +use serde::Deserialize; use crate::Result; @@ -23,6 +24,20 @@ pub struct CargoWorkspace { pub(crate) workspace_root: PathBuf, } +#[derive(Deserialize, Clone, Debug, PartialEq, Eq, Default)] +#[serde(rename_all = "camelCase", default)] +pub struct CargoFeatures { + /// Do not activate the `default` feature. + pub no_default_features: bool, + + /// Activate all available features + pub all_features: bool, + + /// List of features to activate. + /// This will be ignored if `cargo_all_features` is true. + pub features: Vec, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Package(RawId); impl_arena_id!(Package); @@ -132,9 +147,21 @@ impl Target { } impl CargoWorkspace { - pub fn from_cargo_metadata(cargo_toml: &Path) -> Result { + pub fn from_cargo_metadata( + cargo_toml: &Path, + cargo_features: &CargoFeatures, + ) -> Result { let mut meta = MetadataCommand::new(); - meta.manifest_path(cargo_toml).features(CargoOpt::AllFeatures); + meta.manifest_path(cargo_toml); + if cargo_features.all_features { + meta.features(CargoOpt::AllFeatures); + } else if cargo_features.no_default_features { + // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures` + // https://github.com/oli-obk/cargo_metadata/issues/79 + meta.features(CargoOpt::NoDefaultFeatures); + } else { + meta.features(CargoOpt::SomeFeatures(cargo_features.features.clone())); + } if let Some(parent) = cargo_toml.parent() { meta.current_dir(parent); } diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 55ff4d6ef..d71b7031a 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -18,7 +18,7 @@ use rustc_hash::FxHashMap; use serde_json::from_reader; pub use crate::{ - cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, + cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, json_project::JsonProject, sysroot::Sysroot, }; @@ -60,11 +60,15 @@ impl PackageRoot { } impl ProjectWorkspace { - pub fn discover(path: &Path) -> Result { - ProjectWorkspace::discover_with_sysroot(path, true) + pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result { + ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) } - pub fn discover_with_sysroot(path: &Path, with_sysroot: bool) -> Result { + pub fn discover_with_sysroot( + path: &Path, + with_sysroot: bool, + cargo_features: &CargoFeatures, + ) -> Result { match find_rust_project_json(path) { Some(json_path) => { let file = File::open(json_path)?; @@ -73,7 +77,7 @@ impl ProjectWorkspace { } None => { let cargo_toml = find_cargo_toml(path)?; - let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; + let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?; let sysroot = if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() }; Ok(ProjectWorkspace::Cargo { cargo, sysroot }) -- cgit v1.2.3