Skip to content

Commit a795913

Browse files
committed
Implement zip/tar.gz sdist metadata parsing
1 parent 0a8223c commit a795913

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ repository = "https://github.com/messense/python-pkginfo-rs"
1212
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1313

1414
[dependencies]
15+
flate2 = "1.0.20"
1516
fs-err = "2.6.0"
1617
mailparse = "0.13.4"
18+
tar = "0.4.35"
1719
zip = "0.5.12"

src/distribution.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::io::{BufReader, Read};
22
use std::path::Path;
33

4+
use flate2::read::GzDecoder;
45
use zip::ZipArchive;
56

67
use crate::{Error, Metadata};
@@ -66,7 +67,32 @@ impl Distribution {
6667
}
6768

6869
fn parse_sdist(path: &Path, sdist_type: SDistType) -> Result<Metadata, Error> {
69-
todo!()
70+
match sdist_type {
71+
SDistType::Zip => Self::parse_zip(path, "PKG-INFO"),
72+
SDistType::TarGz => {
73+
let mut reader =
74+
tar::Archive::new(GzDecoder::new(BufReader::new(fs_err::File::open(path)?)));
75+
let metadata_file = reader
76+
.entries()?
77+
.map(|entry| -> Result<_, Error> {
78+
let entry = entry?;
79+
if entry.path()?.ends_with("PKG-INFO") {
80+
Ok(Some(entry))
81+
} else {
82+
Ok(None)
83+
}
84+
})
85+
.find_map(|x| x.transpose());
86+
if let Some(metadata_file) = metadata_file {
87+
let mut entry = metadata_file?;
88+
let mut buf = Vec::new();
89+
entry.read_to_end(&mut buf)?;
90+
Metadata::parse(&buf)
91+
} else {
92+
Err(Error::MetadataNotFound)
93+
}
94+
}
95+
}
7096
}
7197

7298
fn parse_egg(path: &Path) -> Result<Metadata, Error> {
@@ -92,6 +118,14 @@ impl Distribution {
92118
archive.by_name(metadata_file)?.read_to_end(&mut buf)?;
93119
Metadata::parse(&buf)
94120
}
121+
[file1, file2]
122+
if file1.ends_with(".egg-info/PKG-INFO")
123+
|| file2.ends_with(".egg-info/PKG-INFO") =>
124+
{
125+
let mut buf = Vec::new();
126+
archive.by_name(file1)?.read_to_end(&mut buf)?;
127+
Metadata::parse(&buf)
128+
}
95129
_ => Err(Error::MultipleMetadataFiles(metadata_files)),
96130
}
97131
}

tests/fixtures/build-0.4.0.tar.gz

13.8 KB
Binary file not shown.

tests/fixtures/build-0.4.0.zip

17.8 KB
Binary file not shown.

tests/test_distribution.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,25 @@ fn test_parse_egg() {
2121
assert!(metadata.home_page.is_none());
2222
assert!(metadata.download_url.is_none());
2323
}
24+
25+
#[test]
26+
fn test_parse_sdist_zip() {
27+
let dist = Distribution::new("tests/fixtures/build-0.4.0.zip").unwrap();
28+
assert_eq!(dist.r#type(), DistributionType::SDist);
29+
let metadata = dist.metadata();
30+
assert_eq!(metadata.metadata_version, "2.1");
31+
assert_eq!(metadata.name, "build");
32+
assert!(metadata.home_page.is_none());
33+
assert!(metadata.download_url.is_none());
34+
}
35+
36+
#[test]
37+
fn test_parse_sdist_tar_gz() {
38+
let dist = Distribution::new("tests/fixtures/build-0.4.0.tar.gz").unwrap();
39+
assert_eq!(dist.r#type(), DistributionType::SDist);
40+
let metadata = dist.metadata();
41+
assert_eq!(metadata.metadata_version, "2.1");
42+
assert_eq!(metadata.name, "build");
43+
assert!(metadata.home_page.is_none());
44+
assert!(metadata.download_url.is_none());
45+
}

0 commit comments

Comments
 (0)