Skip to content

Commit eb0376a

Browse files
committed
extract cargo-metadata logic into subcrate
1 parent 7998e83 commit eb0376a

File tree

16 files changed

+114
-102
lines changed

16 files changed

+114
-102
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ tracing = "0.1.37"
4646
url = { version = "2.1.1", features = ["serde"] }
4747

4848
[dependencies]
49+
docs_rs_cargo_metadata = { path = "crates/lib/docs_rs_cargo_metadata" }
4950
docs_rs_env_vars = { path = "crates/lib/docs_rs_env_vars" }
5051
docs_rs_fastly = { path = "crates/lib/docs_rs_fastly" }
5152
docs_rs_headers = { path = "crates/lib/docs_rs_headers" }
@@ -138,6 +139,7 @@ chrono = { workspace = true }
138139
constant_time_eq = "0.4.2"
139140

140141
[dev-dependencies]
142+
docs_rs_cargo_metadata = { path = "crates/lib/docs_rs_cargo_metadata", features = ["testing"] }
141143
docs_rs_fastly = { path = "crates/lib/docs_rs_fastly", features = ["testing"] }
142144
docs_rs_headers = { path = "crates/lib/docs_rs_headers", features = ["testing"] }
143145
docs_rs_opentelemetry = { path = "crates/lib/docs_rs_opentelemetry", features = ["testing"] }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "docs_rs_cargo_metadata"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
anyhow = { workspace = true }
8+
bincode = { workspace = true }
9+
derive_more = { workspace = true }
10+
docs_rs_types = { path = "../docs_rs_types" }
11+
serde = { workspace = true }
12+
serde_json = { workspace = true }
13+
14+
[dev-dependencies]
15+
test-case = { workspace = true }
16+
17+
[features]
18+
testing = []
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod metadata;
2+
mod release_dependency;
3+
4+
pub use metadata::{CargoMetadata, Dependency, Package as MetadataPackage, Target};
5+
pub use release_dependency::{ReleaseDependency, ReleaseDependencyList};

src/utils/cargo_metadata.rs renamed to crates/lib/docs_rs_cargo_metadata/src/metadata.rs

Lines changed: 41 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,28 @@
1-
use crate::{error::Result, web::extractors::rustdoc::RustdocParams};
2-
use anyhow::{Context, bail};
3-
use docs_rs_types::{KrateName, ReqVersion, Version, VersionReq};
4-
use rustwide::{Toolchain, Workspace, cmd::Command};
1+
use anyhow::{Context, Result};
2+
use docs_rs_types::{Version, VersionReq};
53
use serde::{Deserialize, Serialize};
64
use std::collections::HashMap;
7-
use std::path::Path;
85

9-
pub(crate) struct CargoMetadata {
6+
pub struct CargoMetadata {
107
root: Package,
118
}
129

1310
impl CargoMetadata {
14-
pub(crate) fn load_from_rustwide(
15-
workspace: &Workspace,
16-
toolchain: &Toolchain,
17-
source_dir: &Path,
18-
) -> Result<Self> {
19-
let res = Command::new(workspace, toolchain.cargo())
20-
.args(&["metadata", "--format-version", "1"])
21-
.cd(source_dir)
22-
.log_output(false)
23-
.run_capture()?;
24-
let [metadata] = res.stdout_lines() else {
25-
bail!("invalid output returned by `cargo metadata`")
26-
};
27-
Self::load_from_metadata(metadata)
28-
}
29-
30-
#[cfg(test)]
31-
pub(crate) fn load_from_host_path(source_dir: &Path) -> Result<Self> {
11+
#[cfg(feature = "testing")]
12+
pub fn load_from_host_path(source_dir: &std::path::Path) -> Result<Self> {
3213
let res = std::process::Command::new("cargo")
3314
.args(["metadata", "--format-version", "1", "--offline"])
3415
.current_dir(source_dir)
3516
.output()?;
3617
let status = res.status;
3718
if !status.success() {
3819
let stderr = std::str::from_utf8(&res.stderr).unwrap_or("");
39-
bail!("error returned by `cargo metadata`: {status}\n{stderr}")
20+
anyhow::bail!("error returned by `cargo metadata`: {status}\n{stderr}")
4021
}
4122
Self::load_from_metadata(std::str::from_utf8(&res.stdout)?)
4223
}
4324

44-
pub(crate) fn load_from_metadata(metadata: &str) -> Result<Self> {
25+
pub fn load_from_metadata(metadata: &str) -> Result<Self> {
4526
let metadata = serde_json::from_str::<DeserializedMetadata>(metadata)?;
4627
let root = metadata.resolve.root;
4728
Ok(CargoMetadata {
@@ -53,26 +34,26 @@ impl CargoMetadata {
5334
})
5435
}
5536

56-
pub(crate) fn root(&self) -> &Package {
37+
pub fn root(&self) -> &Package {
5738
&self.root
5839
}
5940
}
6041

6142
#[derive(Debug, Deserialize, Serialize)]
62-
pub(crate) struct Package {
63-
pub(crate) id: String,
64-
pub(crate) name: String,
65-
pub(crate) version: Version,
66-
pub(crate) license: Option<String>,
67-
pub(crate) repository: Option<String>,
68-
pub(crate) homepage: Option<String>,
69-
pub(crate) description: Option<String>,
70-
pub(crate) documentation: Option<String>,
71-
pub(crate) dependencies: Vec<Dependency>,
72-
pub(crate) targets: Vec<Target>,
73-
pub(crate) readme: Option<String>,
74-
pub(crate) keywords: Vec<String>,
75-
pub(crate) features: HashMap<String, Vec<String>>,
43+
pub struct Package {
44+
pub id: String,
45+
pub name: String,
46+
pub version: Version,
47+
pub license: Option<String>,
48+
pub repository: Option<String>,
49+
pub homepage: Option<String>,
50+
pub description: Option<String>,
51+
pub documentation: Option<String>,
52+
pub dependencies: Vec<Dependency>,
53+
pub targets: Vec<Target>,
54+
pub readme: Option<String>,
55+
pub keywords: Vec<String>,
56+
pub features: HashMap<String, Vec<String>>,
7657
}
7758

7859
impl Package {
@@ -82,15 +63,15 @@ impl Package {
8263
.find(|target| target.crate_types.iter().any(|kind| kind != "bin"))
8364
}
8465

85-
pub(crate) fn is_library(&self) -> bool {
66+
pub fn is_library(&self) -> bool {
8667
self.library_target().is_some()
8768
}
8869

8970
fn normalize_package_name(&self, name: &str) -> String {
9071
name.replace('-', "_")
9172
}
9273

93-
pub(crate) fn package_name(&self) -> String {
74+
pub fn package_name(&self) -> String {
9475
self.library_name().unwrap_or_else(|| {
9576
self.targets
9677
.first()
@@ -99,25 +80,25 @@ impl Package {
9980
})
10081
}
10182

102-
pub(crate) fn library_name(&self) -> Option<String> {
83+
pub fn library_name(&self) -> Option<String> {
10384
self.library_target()
10485
.map(|target| self.normalize_package_name(&target.name))
10586
}
10687
}
10788

10889
#[derive(Debug, Deserialize, Serialize)]
109-
pub(crate) struct Target {
110-
pub(crate) name: String,
111-
#[cfg(not(test))]
90+
pub struct Target {
91+
pub name: String,
92+
#[cfg(not(feature = "testing"))]
11293
crate_types: Vec<String>,
113-
#[cfg(test)]
114-
pub(crate) crate_types: Vec<String>,
115-
pub(crate) src_path: Option<String>,
94+
#[cfg(feature = "testing")]
95+
pub crate_types: Vec<String>,
96+
pub src_path: Option<String>,
11697
}
11798

11899
impl Target {
119-
#[cfg(test)]
120-
pub(crate) fn dummy_lib(name: String, src_path: Option<String>) -> Self {
100+
#[cfg(feature = "testing")]
101+
pub fn dummy_lib(name: String, src_path: Option<String>) -> Self {
121102
Target {
122103
name,
123104
crate_types: vec!["lib".into()],
@@ -127,25 +108,12 @@ impl Target {
127108
}
128109

129110
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
130-
pub(crate) struct Dependency {
131-
pub(crate) name: String,
132-
pub(crate) req: VersionReq,
133-
pub(crate) kind: Option<String>,
134-
pub(crate) rename: Option<String>,
135-
pub(crate) optional: bool,
136-
}
137-
138-
impl Dependency {
139-
pub(crate) fn rustdoc_params(&self) -> RustdocParams {
140-
RustdocParams::new(
141-
// I validated in the database, which makes me assume that renames are
142-
// handled before storing the deps into the column.
143-
self.name
144-
.parse::<KrateName>()
145-
.expect("we validated that the dep name is always a valid KrateName"),
146-
)
147-
.with_req_version(ReqVersion::Semver(self.req.clone()))
148-
}
111+
pub struct Dependency {
112+
pub name: String,
113+
pub req: VersionReq,
114+
pub kind: Option<String>,
115+
pub rename: Option<String>,
116+
pub optional: bool,
149117
}
150118

151119
impl bincode::Encode for Dependency {
@@ -172,7 +140,7 @@ impl bincode::Encode for Dependency {
172140
}
173141

174142
impl Dependency {
175-
#[cfg(test)]
143+
#[cfg(feature = "testing")]
176144
pub fn new(name: String, req: VersionReq) -> Dependency {
177145
Dependency {
178146
name,
@@ -183,7 +151,7 @@ impl Dependency {
183151
}
184152
}
185153

186-
#[cfg(test)]
154+
#[cfg(feature = "testing")]
187155
pub fn set_optional(mut self, optional: bool) -> Self {
188156
self.optional = optional;
189157
self

src/db/types/dependencies.rs renamed to crates/lib/docs_rs_cargo_metadata/src/release_dependency.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::Dependency;
1+
use super::Dependency;
22
use derive_more::Deref;
33
use docs_rs_types::VersionReq;
44
use serde::{Deserialize, Serialize};
@@ -7,7 +7,7 @@ const DEFAULT_KIND: &str = "normal";
77

88
/// A crate dependency in our internal representation for releases.dependencies json.
99
#[derive(Debug, Clone, PartialEq, Deref)]
10-
pub(crate) struct ReleaseDependency(Dependency);
10+
pub struct ReleaseDependency(Dependency);
1111

1212
impl<'de> Deserialize<'de> for ReleaseDependency {
1313
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -67,7 +67,7 @@ impl From<ReleaseDependency> for Dependency {
6767
}
6868
}
6969

70-
pub(crate) type ReleaseDependencyList = Vec<ReleaseDependency>;
70+
pub type ReleaseDependencyList = Vec<ReleaseDependency>;
7171

7272
#[cfg(test)]
7373
mod tests {

src/db/add_package.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::{
2-
db::types::dependencies::ReleaseDependencyList,
32
docbuilder::DocCoverage,
43
error::Result,
54
storage::CompressionAlgorithm,
6-
utils::MetadataPackage,
75
web::crate_details::{latest_release, releases_for_crate},
86
};
97
use anyhow::{Context, anyhow};
8+
use docs_rs_cargo_metadata::{MetadataPackage, ReleaseDependencyList};
109
use docs_rs_registry_api::{CrateData, CrateOwner, ReleaseData};
1110
use docs_rs_types::{BuildId, BuildStatus, CrateId, Feature, ReleaseId, Version};
1211
use docs_rs_utils::rustc_version::parse_rustc_date;
@@ -623,8 +622,8 @@ where
623622
mod test {
624623
use super::*;
625624
use crate::test::*;
626-
use crate::utils::CargoMetadata;
627625
use chrono::NaiveDate;
626+
use docs_rs_cargo_metadata::CargoMetadata;
628627
use docs_rs_registry_api::OwnerKind;
629628
use std::slice;
630629
use test_case::test_case;

src/db/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub(crate) mod file;
2222
pub(crate) mod mimes;
2323
mod overrides;
2424
mod pool;
25-
pub mod types;
2625

2726
static MIGRATOR: Migrator = sqlx::migrate!();
2827

src/db/types/mod.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/docbuilder/rustwide_builder.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ use crate::{
1515
CompressionAlgorithm, RustdocJsonFormatVersion, compress, get_file_list,
1616
rustdoc_archive_path, rustdoc_json_path, source_archive_path,
1717
},
18-
utils::{
19-
CargoMetadata, ConfigName, MetadataPackage, copy_dir_all, get_config, report_error,
20-
set_config,
21-
},
18+
utils::{ConfigName, copy_dir_all, get_config, report_error, set_config},
2219
};
2320
use anyhow::{Context as _, Error, anyhow, bail};
21+
use docs_rs_cargo_metadata::{CargoMetadata, MetadataPackage};
2422
use docs_rs_opentelemetry::AnyMeterProvider;
2523
use docs_rs_registry_api::RegistryApi;
2624
use docs_rs_types::{BuildId, BuildStatus, CrateId, ReleaseId, Version};
@@ -110,6 +108,22 @@ fn build_workspace(context: &Context) -> Result<Workspace> {
110108
Ok(workspace)
111109
}
112110

111+
fn load_metadata_from_rustwide(
112+
workspace: &Workspace,
113+
toolchain: &Toolchain,
114+
source_dir: &Path,
115+
) -> Result<CargoMetadata> {
116+
let res = Command::new(workspace, toolchain.cargo())
117+
.args(&["metadata", "--format-version", "1"])
118+
.cd(source_dir)
119+
.log_output(false)
120+
.run_capture()?;
121+
let [metadata] = res.stdout_lines() else {
122+
bail!("invalid output returned by `cargo metadata`")
123+
};
124+
CargoMetadata::load_from_metadata(metadata)
125+
}
126+
113127
#[derive(Debug)]
114128
pub enum PackageKind<'a> {
115129
Local(&'a Path),
@@ -529,7 +543,7 @@ impl RustwideBuilder {
529543
}
530544

531545
pub fn build_local_package(&mut self, path: &Path) -> Result<BuildPackageSummary> {
532-
let metadata = CargoMetadata::load_from_rustwide(&self.workspace, &self.toolchain, path)
546+
let metadata = load_metadata_from_rustwide(&self.workspace, &self.toolchain, path)
533547
.map_err(|err| {
534548
err.context(format!("failed to load local package {}", path.display()))
535549
})?;
@@ -1146,7 +1160,7 @@ impl RustwideBuilder {
11461160
create_essential_files: bool,
11471161
collect_metrics: bool,
11481162
) -> Result<FullBuildResult> {
1149-
let cargo_metadata = CargoMetadata::load_from_rustwide(
1163+
let cargo_metadata = load_metadata_from_rustwide(
11501164
&self.workspace,
11511165
&self.toolchain,
11521166
&build.host_source_dir(),

0 commit comments

Comments
 (0)