Support setting cargo features

This commit is contained in:
oxalica 2019-12-13 18:16:34 +08:00
parent 5eb5e80de9
commit af4eb26645
No known key found for this signature in database
GPG key ID: CED392DE0C483D00
8 changed files with 118 additions and 21 deletions

View file

@ -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<String>,
}
#[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<CargoWorkspace> {
pub fn from_cargo_metadata(
cargo_toml: &Path,
cargo_features: &CargoFeatures,
) -> Result<CargoWorkspace> {
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);
}

View file

@ -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> {
ProjectWorkspace::discover_with_sysroot(path, true)
pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> {
ProjectWorkspace::discover_with_sysroot(path, true, cargo_features)
}
pub fn discover_with_sysroot(path: &Path, with_sysroot: bool) -> Result<ProjectWorkspace> {
pub fn discover_with_sysroot(
path: &Path,
with_sysroot: bool,
cargo_features: &CargoFeatures,
) -> Result<ProjectWorkspace> {
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 })