Skip to content

Commit 05ca269

Browse files
Nemo157syphar
authored andcommitted
Add in unit test of getting features from cargo metadata
1 parent 9a92f4d commit 05ca269

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

src/db/add_package.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,8 @@ where
434434
mod test {
435435
use super::*;
436436
use crate::test::*;
437-
use crate::utils::MetadataPackage;
437+
use crate::utils::{CargoMetadata, MetadataPackage};
438+
use test_case::test_case;
438439

439440
#[test]
440441
fn new_keywords() {
@@ -691,4 +692,48 @@ mod test {
691692
Ok(())
692693
})
693694
}
695+
696+
#[test_case("", [])]
697+
#[test_case(
698+
r#"
699+
[features]
700+
foo = []
701+
"#,
702+
[Feature::new("foo".into(), vec![])]
703+
)]
704+
#[test_case(
705+
r#"
706+
[dependencies]
707+
base64 = { optional = true, version = "=0.13.1" }
708+
"#,
709+
[Feature::new("base64".into(), vec!["dep:base64".into()])]
710+
)]
711+
#[test_case(
712+
r#"
713+
[dependencies]
714+
base64 = { optional = true, version = "=0.13.1" }
715+
[features]
716+
not-base64 = ["dep:base64"]
717+
"#,
718+
[Feature::new("not-base64".into(), vec!["dep:base64".into()])]
719+
)]
720+
fn test_get_features(extra: &str, expected: impl AsRef<[Feature]>) -> Result<()> {
721+
let dir = tempfile::tempdir()?;
722+
723+
std::fs::create_dir(dir.path().join("src"))?;
724+
std::fs::write(dir.path().join("src/lib.rs"), "")?;
725+
726+
let base = r#"
727+
[package]
728+
name = "test"
729+
version = "0.0.0"
730+
"#;
731+
732+
std::fs::write(dir.path().join("Cargo.toml"), [base, extra].concat())?;
733+
let metadata = CargoMetadata::load_from_host_path(dir.path())?;
734+
let features = super::get_features(metadata.root());
735+
assert_eq!(features, expected.as_ref());
736+
737+
Ok(())
738+
}
694739
}

src/docbuilder/rustwide_builder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ impl RustwideBuilder {
311311

312312
pub fn build_local_package(&mut self, path: &Path) -> Result<bool> {
313313
self.update_toolchain()?;
314-
let metadata =
315-
CargoMetadata::load(&self.workspace, &self.toolchain, path).map_err(|err| {
314+
let metadata = CargoMetadata::load_from_rustwide(&self.workspace, &self.toolchain, path)
315+
.map_err(|err| {
316316
err.context(format!("failed to load local package {}", path.display()))
317317
})?;
318318
let package = metadata.root();
@@ -646,8 +646,11 @@ impl RustwideBuilder {
646646
metadata: &Metadata,
647647
create_essential_files: bool,
648648
) -> Result<FullBuildResult> {
649-
let cargo_metadata =
650-
CargoMetadata::load(&self.workspace, &self.toolchain, &build.host_source_dir())?;
649+
let cargo_metadata = CargoMetadata::load_from_rustwide(
650+
&self.workspace,
651+
&self.toolchain,
652+
&build.host_source_dir(),
653+
)?;
651654

652655
let mut rustdoc_flags = vec![if create_essential_files {
653656
"--emit=unversioned-shared-resources,toolchain-shared-resources"

src/utils/cargo_metadata.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::error::Result;
2-
use anyhow::bail;
2+
use anyhow::{bail, Context};
33
use rustwide::{cmd::Command, Toolchain, Workspace};
44
use serde::{Deserialize, Serialize};
55
use std::collections::HashMap;
@@ -10,7 +10,7 @@ pub(crate) struct CargoMetadata {
1010
}
1111

1212
impl CargoMetadata {
13-
pub(crate) fn load(
13+
pub(crate) fn load_from_rustwide(
1414
workspace: &Workspace,
1515
toolchain: &Toolchain,
1616
source_dir: &Path,
@@ -20,21 +20,34 @@ impl CargoMetadata {
2020
.cd(source_dir)
2121
.log_output(false)
2222
.run_capture()?;
23-
24-
let mut iter = res.stdout_lines().iter();
25-
let metadata = if let (Some(serialized), None) = (iter.next(), iter.next()) {
26-
serde_json::from_str::<DeserializedMetadata>(serialized)?
27-
} else {
28-
bail!("invalid output returned by `cargo metadata`");
23+
let [metadata] = res.stdout_lines() else {
24+
bail!("invalid output returned by `cargo metadata`")
2925
};
26+
Self::load_from_metadata(metadata)
27+
}
28+
29+
#[cfg(test)]
30+
pub(crate) fn load_from_host_path(source_dir: &Path) -> Result<Self> {
31+
let res = std::process::Command::new("cargo")
32+
.args(["metadata", "--format-version", "1", "--offline"])
33+
.current_dir(source_dir)
34+
.output()?;
35+
let status = res.status;
36+
if !status.success() {
37+
bail!("error returned by `cargo metadata`: {status}")
38+
}
39+
Self::load_from_metadata(std::str::from_utf8(&res.stdout)?)
40+
}
3041

42+
pub(crate) fn load_from_metadata(metadata: &str) -> Result<Self> {
43+
let metadata = serde_json::from_str::<DeserializedMetadata>(metadata)?;
3144
let root = metadata.resolve.root;
3245
Ok(CargoMetadata {
3346
root: metadata
3447
.packages
3548
.into_iter()
3649
.find(|pkg| pkg.id == root)
37-
.unwrap(),
50+
.context("metadata.packages missing root package")?,
3851
})
3952
}
4053

0 commit comments

Comments
 (0)