diff --git a/crates/puffin-client/tests/remote_metadata.rs b/crates/puffin-client/tests/remote_metadata.rs
index 1bbf1b1db..1610f2374 100644
--- a/crates/puffin-client/tests/remote_metadata.rs
+++ b/crates/puffin-client/tests/remote_metadata.rs
@@ -10,22 +10,19 @@ use puffin_client::RegistryClientBuilder;
#[tokio::test]
async fn remote_metadata_with_and_without_cache() -> Result<()> {
- let temp_cache = tempdir().unwrap();
+ let temp_cache = tempdir()?;
let client = RegistryClientBuilder::new(temp_cache.path().to_path_buf()).build();
+
// The first run is without cache (the tempdir is empty), the second has the cache from the
- // first run
+ // first run.
for _ in 0..2 {
let url = "https://files.pythonhosted.org/packages/00/e5/f12a80907d0884e6dff9c16d0c0114d81b8cd07dc3ae54c5e962cc83037e/tqdm-4.66.1-py3-none-any.whl";
- let filename = WheelFilename::from_str(url.rsplit_once('/').unwrap().1).unwrap();
+ let filename = WheelFilename::from_str(url.rsplit_once('/').unwrap().1)?;
let metadata = client
- .wheel_metadata_no_pep658(
- &filename,
- &Url::parse(url).unwrap(),
- WheelMetadataCache::Url,
- )
- .await
- .unwrap();
- assert_eq!(metadata.summary.unwrap(), "Fast, Extensible Progress Meter");
+ .wheel_metadata_no_pep658(&filename, &Url::parse(url)?, WheelMetadataCache::Url)
+ .await?;
+ assert_eq!(metadata.version.to_string(), "4.66.1");
}
+
Ok(())
}
diff --git a/crates/pypi-types/src/metadata.rs b/crates/pypi-types/src/metadata.rs
index 0423623b9..99fb2d4da 100644
--- a/crates/pypi-types/src/metadata.rs
+++ b/crates/pypi-types/src/metadata.rs
@@ -1,6 +1,5 @@
//! Derived from `pypi_types_crate`.
-use std::collections::HashMap;
use std::io;
use std::str::FromStr;
@@ -12,13 +11,14 @@ use pep440_rs::{Pep440Error, Version, VersionSpecifiers};
use pep508_rs::{Pep508Error, Requirement};
use puffin_normalize::{ExtraName, InvalidNameError, PackageName};
-use crate::lenient_requirement::{LenientRequirement, LenientVersionSpecifiers};
+use crate::lenient_requirement::LenientRequirement;
+use crate::LenientVersionSpecifiers;
/// Python Package Metadata 2.1 as specified in
-///
+/// .
///
-/// One addition is the requirements fixup which insert missing commas e.g. in
-/// `elasticsearch-dsl (>=7.2.0<8.0.0)`
+/// This is a subset of the full metadata specification, and only includes the
+/// fields that are relevant to dependency resolution.
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub struct Metadata21 {
@@ -27,26 +27,8 @@ pub struct Metadata21 {
pub name: PackageName,
pub version: Version,
// Optional fields
- pub platforms: Vec,
- pub supported_platforms: Vec,
- pub summary: Option,
- pub description: Option,
- pub description_content_type: Option,
- pub keywords: Option,
- pub home_page: Option,
- pub download_url: Option,
- pub author: Option,
- pub author_email: Option,
- pub maintainer: Option,
- pub maintainer_email: Option,
- pub license: Option,
- pub classifiers: Vec,
pub requires_dist: Vec,
- pub provides_dist: Vec,
- pub obsoletes_dist: Vec,
pub requires_python: Option,
- pub requires_external: Vec,
- pub project_urls: HashMap,
pub provides_extras: Vec,
}
@@ -99,6 +81,7 @@ impl Metadata21 {
let msg = mailparse::parse_mail(&mail)?;
let headers = msg.get_headers();
+
let get_first_value = |name| {
headers.get_first_header(name).and_then(|header| {
match rfc2047_decoder::decode(header.get_value_raw()) {
@@ -114,13 +97,12 @@ impl Metadata21 {
})
};
let get_all_values = |name| {
- let values: Vec = headers
+ headers
.get_all_values(name)
.into_iter()
.filter(|value| value != "UNKNOWN")
- .collect();
- values
};
+
let metadata_version = headers
.get_first_value("Metadata-Version")
.ok_or(Error::FieldNotFound("Metadata-Version"))?;
@@ -135,75 +117,26 @@ impl Metadata21 {
.ok_or(Error::FieldNotFound("Version"))?,
)
.map_err(Error::Pep440VersionError)?;
- let platforms = get_all_values("Platform");
- let supported_platforms = get_all_values("Supported-Platform");
- let summary = get_first_value("Summary");
- let body = msg.get_body()?;
- let description = if body.trim().is_empty() {
- get_first_value("Description")
- } else {
- Some(body)
- };
- let keywords = get_first_value("Keywords");
- let home_page = get_first_value("Home-Page");
- let download_url = get_first_value("Download-URL");
- let author = get_first_value("Author");
- let author_email = get_first_value("Author-email");
- let license = get_first_value("License");
- let classifiers = get_all_values("Classifier");
let requires_dist = get_all_values("Requires-Dist")
- .iter()
- .map(|requires_dist| LenientRequirement::from_str(requires_dist).map(Requirement::from))
+ .map(|requires_dist| {
+ LenientRequirement::from_str(&requires_dist).map(Requirement::from)
+ })
.collect::, _>>()?;
- let provides_dist = get_all_values("Provides-Dist")
- .into_iter()
- .map(PackageName::new)
- .collect::, _>>()?;
- let obsoletes_dist = get_all_values("Obsoletes-Dist");
- let maintainer = get_first_value("Maintainer");
- let maintainer_email = get_first_value("Maintainer-email");
let requires_python = get_first_value("Requires-Python")
.map(|requires_python| {
LenientVersionSpecifiers::from_str(&requires_python).map(VersionSpecifiers::from)
})
.transpose()?;
- let requires_external = get_all_values("Requires-External");
- let project_urls = get_all_values("Project-URL")
- .iter()
- .map(|name_value| match name_value.split_once(',') {
- None => Err(Error::InvalidProjectUrl(name_value.clone())),
- Some((name, value)) => Ok((name.to_string(), value.trim().to_string())),
- })
- .collect::>()?;
let provides_extras = get_all_values("Provides-Extra")
- .into_iter()
.map(ExtraName::new)
.collect::, _>>()?;
- let description_content_type = get_first_value("Description-Content-Type");
+
Ok(Metadata21 {
metadata_version,
name,
version,
- platforms,
- supported_platforms,
- summary,
- description,
- description_content_type,
- keywords,
- home_page,
- download_url,
- author,
- author_email,
- maintainer,
- maintainer_email,
- license,
- classifiers,
requires_dist,
- provides_dist,
- obsoletes_dist,
requires_python,
- requires_external,
- project_urls,
provides_extras,
})
}