Skip to content

Commit

Permalink
fix: now check metadata version (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdejager authored Nov 14, 2023
1 parent 3138999 commit 6e6b6b8
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 235 deletions.
27 changes: 25 additions & 2 deletions crates/rattler_installs_packages/src/core_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,30 @@ use thiserror::Error;
pub struct WheelCoreMetadata {
pub name: PackageName,
pub version: Version,
pub metadata_version: MetadataVersion,
pub requires_dist: Vec<Requirement>,
pub requires_python: Option<VersionSpecifiers>,
pub extras: HashSet<Extra>,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MetadataVersion(pub Version);

impl MetadataVersion {
/// We consider that this implements PEP643
/// if the version is 2.3 or higher.
pub fn implements_pep643(&self) -> bool {
static VERSION_2_2: Lazy<MetadataVersion> = Lazy::new(|| {
MetadataVersion(Version::from_str("2.2").expect("cannot parse 2.2 version string"))
});

if self < &VERSION_2_2 {
return false;
}
true
}
}

#[derive(Debug, Error)]
pub enum WheelCoreMetaDataError {
#[error(transparent)]
Expand Down Expand Up @@ -58,7 +77,7 @@ impl TryFrom<&[u8]> for WheelCoreMetadata {
type Error = WheelCoreMetaDataError;

fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let (name, version, mut parsed) = parse_common(value)?;
let (name, version, metadata_version, mut parsed) = parse_common(value)?;

let mut requires_dist = Vec::new();
for req_str in parsed.take_all("Requires-Dist").into_iter() {
Expand Down Expand Up @@ -90,14 +109,17 @@ impl TryFrom<&[u8]> for WheelCoreMetadata {
Ok(WheelCoreMetadata {
name,
version,
metadata_version,
requires_dist,
requires_python,
extras,
})
}
}

fn parse_common(input: &[u8]) -> Result<(PackageName, Version, RFC822ish), WheelCoreMetaDataError> {
fn parse_common(
input: &[u8],
) -> Result<(PackageName, Version, MetadataVersion, RFC822ish), WheelCoreMetaDataError> {
let input = String::from_utf8_lossy(input);
let mut parsed = RFC822ish::from_str(&input)?;

Expand Down Expand Up @@ -143,6 +165,7 @@ fn parse_common(input: &[u8]) -> Result<(PackageName, Version, RFC822ish), Wheel
version_str
.parse()
.map_err(WheelCoreMetaDataError::InvalidVersion)?,
MetadataVersion(metadata_version),
parsed,
))
}
2 changes: 2 additions & 0 deletions crates/rattler_installs_packages/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ impl<'p> DependencyProvider<PypiVersionSet, PypiPackageName>
.block_on(self.package_db.get_metadata::<SDist, _>(artifacts))
.unwrap()
.expect("no metadata found for sdist or wheels");

tracing::info!("found metadata for sdist: {:?}", metadata);
metadata
}
Some((_, metadata)) => metadata,
Expand Down
34 changes: 28 additions & 6 deletions crates/rattler_installs_packages/src/sdist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl SDist {
pub fn read_package_info(&self) -> miette::Result<(Vec<u8>, WheelCoreMetadata)> {
if let Some(bytes) = self.find_entry("PKG-INFO")? {
let metadata = Self::parse_metadata(&bytes)?;

Ok((bytes, metadata))
} else {
Err(miette!("no PKG-INFO found in archive"))
Expand Down Expand Up @@ -115,27 +116,48 @@ impl MetadataArtifact for SDist {

fn metadata(&self) -> miette::Result<(Vec<u8>, Self::Metadata)> {
// Assume we have a PKG-INFO
self.read_package_info()
let (bytes, metadata) = self.read_package_info()?;

// Only SDIST metadata from version 2.2 and up is considered reliable
// Filter out older versions
// TODO: when we have wheel building, build the wheel instead relying on this
if !metadata.metadata_version.implements_pep643() {
return Err(miette!("only consider SDist Metadata higher than 2.2"));
}
Ok((bytes, metadata))
}
}

#[cfg(test)]
mod tests {
use crate::sdist::SDist;
use crate::MetadataArtifact;
use insta::{assert_debug_snapshot, assert_ron_snapshot};
use insta::assert_ron_snapshot;
use std::path::Path;

#[test]
pub fn read_rich_metadata() {
pub fn reject_rich_metadata() {
// Read path
let path =
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../test-data/sdists/rich-13.6.0.tar.gz");

// Load sdist
let sdist = super::SDist::from_path(&path).unwrap();
let sdist = SDist::from_path(&path).unwrap();

let metadata = sdist.metadata().unwrap().1;
assert_debug_snapshot!(metadata);
// Rich has an old metadata version
let metadata = sdist.metadata();
assert!(metadata.is_err());
}

#[test]
pub fn correct_metadata_fake_flask() {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../test-data/sdists/fake-flask-3.0.0.tar.gz");

let sdist = SDist::from_path(&path).unwrap();
// Should not fail as it is a valid PKG-INFO
// and considered reliable
sdist.metadata().unwrap();
}

#[test]
Expand Down

This file was deleted.

Binary file added test-data/sdists/fake-flask-3.0.0.tar.gz
Binary file not shown.

0 comments on commit 6e6b6b8

Please sign in to comment.