feat: working package archive parsing

main
Jef Roosens 2023-07-13 11:31:31 +02:00
parent 70b6b326f1
commit f5de535313
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
2 changed files with 33 additions and 31 deletions

View File

@ -53,27 +53,9 @@ async fn post_package_archive(
.await?; .await?;
} }
let mut builder = Builder::new(); let pkg = tokio::task::spawn_blocking(move || package::Package::open(&path)).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR).await?;
builder
.support_format(libarchive::archive::ReadFormat::Tar)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
builder
.support_filter(libarchive::archive::ReadFilter::All)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let mut ar = builder
.open_file(&path)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
for entry in ar.entries() { println!("{:?}", pkg);
let mut entry = entry.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
if entry.pathname() == ".PKGINFO" {
let mut buffer = String::new();
entry.read_to_string(&mut buffer);
println!("{}", buffer);
}
}
Ok(()) Ok(())
} }

View File

@ -3,9 +3,11 @@ use libarchive::{Entry, ReadFilter};
use std::fmt; use std::fmt;
use std::io::{self, BufRead, BufReader, Read}; use std::io::{self, BufRead, BufReader, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::fs;
const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"]; const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"];
#[derive(Debug)]
pub struct Package { pub struct Package {
path: PathBuf, path: PathBuf,
info: PkgInfo, info: PkgInfo,
@ -13,14 +15,15 @@ pub struct Package {
compression: ReadFilter, compression: ReadFilter,
} }
#[derive(Debug)]
#[derive(Default)] #[derive(Default)]
pub struct PkgInfo { pub struct PkgInfo {
name: String, name: String,
base: String, base: String,
version: String, version: String,
description: String, description: String,
size: i64, size: u64,
csize: i64, csize: u64,
url: String, url: String,
arch: String, arch: String,
build_date: i64, build_date: i64,
@ -62,7 +65,7 @@ impl PkgInfo {
let line = line.as_ref(); let line = line.as_ref();
if !line.starts_with('#') { if !line.starts_with('#') {
if let Some((key, value)) = line.split_once(',').map(|(k, v)| (k.trim(), v.trim())) { if let Some((key, value)) = line.split_once('=').map(|(k, v)| (k.trim(), v.trim())) {
match key { match key {
"pkgname" => self.name = value.to_string(), "pkgname" => self.name = value.to_string(),
"pkgbase" => self.base = value.to_string(), "pkgbase" => self.base = value.to_string(),
@ -83,7 +86,7 @@ impl PkgInfo {
"pgpsigsize" => { "pgpsigsize" => {
self.pgpsigsize = value self.pgpsigsize = value
.parse() .parse()
.map_err(|_| ParsePkgInfoError::InvalidBuildDate)? .map_err(|_| ParsePkgInfoError::InvalidPgpSigSize)?
} }
"group" => self.groups.push(value.to_string()), "group" => self.groups.push(value.to_string()),
"license" => self.licenses.push(value.to_string()), "license" => self.licenses.push(value.to_string()),
@ -120,11 +123,19 @@ impl Package {
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> { pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
let mut builder = Builder::new(); let mut builder = Builder::new();
builder.support_format(libarchive::ReadFormat::Tar)?; builder.support_format(libarchive::ReadFormat::Tar)?;
builder.support_filter(libarchive::ReadFilter::All)?;
let mut ar = builder.open_file(path)?; // There are chosen kind of arbitrarily, most likely only zstd, gzip and xz will ever be
// used
builder.support_filter(libarchive::ReadFilter::Zstd)?;
builder.support_filter(libarchive::ReadFilter::Gzip)?;
builder.support_filter(libarchive::ReadFilter::Xz)?;
builder.support_filter(libarchive::ReadFilter::Bzip2)?;
builder.support_filter(libarchive::ReadFilter::Lzma)?;
let mut info: PkgInfo; let mut ar = builder.open_file(path.as_ref())?;
let compression = ar.filter(0).ok_or(io::Error::new(io::ErrorKind::Other, "Unknown compression type."))?;
let mut info: Option<PkgInfo> = None;
let mut files: Vec<PathBuf> = Vec::new(); let mut files: Vec<PathBuf> = Vec::new();
for entry in ar.entries() { for entry in ar.entries() {
@ -136,12 +147,21 @@ impl Package {
} }
if path_name == ".PKGINFO" { if path_name == ".PKGINFO" {
let size = entry.size(); info = Some(PkgInfo::parse(entry)?);
info = PkgInfo::parse(entry)?;
info.size = size;
} }
} }
todo!() if let Some(mut info) = info {
info.csize = fs::metadata(path.as_ref())?.len();
Ok(Package{
path: path.as_ref().to_path_buf(),
info,
compression,
files
})
} else {
Err(io::Error::new(io::ErrorKind::Other, "No .PKGINFO file found."))
}
} }
} }