feat: start of pkg info parsing code
parent
2e118d0283
commit
7be4d83ca3
|
@ -2,4 +2,8 @@ pub mod archive;
|
|||
pub mod error;
|
||||
pub mod read;
|
||||
|
||||
pub use archive::{
|
||||
Entry, ExtractOption, ExtractOptions, Handle, ReadCompression, ReadFilter, ReadFormat,
|
||||
WriteFilter, WriteFormat,
|
||||
};
|
||||
pub use error::Result;
|
||||
|
|
|
@ -5,6 +5,7 @@ mod file;
|
|||
pub use builder::Builder;
|
||||
|
||||
use crate::archive::Handle;
|
||||
use crate::ReadFilter;
|
||||
use entries::Entries;
|
||||
use libarchive3_sys::ffi;
|
||||
use std::path::Path;
|
||||
|
@ -18,4 +19,13 @@ pub trait Archive: Handle + Sized {
|
|||
fn entries<'a>(&'a mut self) -> Entries<'a, Self> {
|
||||
Entries::new(self)
|
||||
}
|
||||
|
||||
fn filter(&mut self, index: i32) -> ReadFilter {
|
||||
let res = unsafe { ffi::archive_filter_code(self.handle_mut(), index) };
|
||||
|
||||
match res {
|
||||
0 => ReadFilter::None,
|
||||
_ => panic!("Unknown filter type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Overarching abstraction that orchestrates updating the repositories stored on the server
|
||||
pub struct RepoGroupManager {
|
||||
repo_dir: PathBuf,
|
||||
pkg_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl RepoGroupManager {
|
||||
fn new<P1: AsRef<Path>, P2: AsRef<Path>>(repo_dir: P1, pkg_dir: P2) -> Self {
|
||||
RepoGroupManager {
|
||||
repo_dir: repo_dir.as_ref().to_path_buf(),
|
||||
pkg_dir: pkg_dir.as_ref().to_path_buf(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
mod manager;
|
||||
mod package;
|
||||
|
||||
use axum::extract::{BodyStream, Path, State};
|
||||
use axum::http::StatusCode;
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
use libarchive::read::{Archive, Builder};
|
||||
use libarchive::{Entry, ReadFilter};
|
||||
use std::fmt;
|
||||
use std::io::{self, BufRead, BufReader, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"];
|
||||
|
||||
pub struct Package {
|
||||
path: PathBuf,
|
||||
info: PkgInfo,
|
||||
files: Vec<PathBuf>,
|
||||
compression: ReadFilter,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PkgInfo {
|
||||
name: String,
|
||||
base: String,
|
||||
version: String,
|
||||
description: String,
|
||||
size: i64,
|
||||
csize: i64,
|
||||
url: String,
|
||||
arch: String,
|
||||
build_date: i64,
|
||||
packager: String,
|
||||
pgpsig: String,
|
||||
pgpsigsize: i64,
|
||||
groups: Vec<String>,
|
||||
licenses: Vec<String>,
|
||||
replaces: Vec<String>,
|
||||
depends: Vec<String>,
|
||||
conflicts: Vec<String>,
|
||||
provides: Vec<String>,
|
||||
optdepends: Vec<String>,
|
||||
makedepends: Vec<String>,
|
||||
checkdepends: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum ParsePkgInfoError {
|
||||
InvalidSize,
|
||||
InvalidBuildDate,
|
||||
InvalidPgpSigSize,
|
||||
}
|
||||
|
||||
impl fmt::Display for ParsePkgInfoError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
Self::InvalidSize => "invalid size",
|
||||
Self::InvalidBuildDate => "invalid build date",
|
||||
Self::InvalidPgpSigSize => "invalid pgp sig size",
|
||||
};
|
||||
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl PkgInfo {
|
||||
pub fn extend<S: AsRef<str>>(&mut self, line: S) -> Result<(), ParsePkgInfoError> {
|
||||
let line = line.as_ref();
|
||||
|
||||
if !line.starts_with('#') {
|
||||
if let Some((key, value)) = line.split_once(',').map(|(k, v)| (k.trim(), v.trim())) {
|
||||
match key {
|
||||
"pkgname" => self.name = value.to_string(),
|
||||
"pkgbase" => self.base = value.to_string(),
|
||||
"pkgver" => self.version = value.to_string(),
|
||||
"pkgdesc" => self.description = value.to_string(),
|
||||
"size" => {
|
||||
self.size = value.parse().map_err(|_| ParsePkgInfoError::InvalidSize)?
|
||||
}
|
||||
"url" => self.url = value.to_string(),
|
||||
"arch" => self.arch = value.to_string(),
|
||||
"builddate" => {
|
||||
self.build_date = value
|
||||
.parse()
|
||||
.map_err(|_| ParsePkgInfoError::InvalidBuildDate)?
|
||||
}
|
||||
"packager" => self.packager = value.to_string(),
|
||||
"pgpsig" => self.pgpsig = value.to_string(),
|
||||
"pgpsigsize" => {
|
||||
self.pgpsigsize = value
|
||||
.parse()
|
||||
.map_err(|_| ParsePkgInfoError::InvalidBuildDate)?
|
||||
}
|
||||
"group" => self.groups.push(value.to_string()),
|
||||
"license" => self.licenses.push(value.to_string()),
|
||||
"replaces" => self.replaces.push(value.to_string()),
|
||||
"depend" => self.depends.push(value.to_string()),
|
||||
"conflict" => self.conflicts.push(value.to_string()),
|
||||
"provides" => self.provides.push(value.to_string()),
|
||||
"optdepend" => self.optdepends.push(value.to_string()),
|
||||
"makedepend" => self.makedepends.push(value.to_string()),
|
||||
"checkdepend" => self.checkdepends.push(value.to_string()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse<R: Read>(reader: R) -> io::Result<Self> {
|
||||
let mut info = Self::default();
|
||||
let buf_reader = BufReader::new(reader);
|
||||
|
||||
for line in buf_reader.lines() {
|
||||
info.extend(line?).map_err(|e| {
|
||||
io::Error::new(io::ErrorKind::Other, format!("pkg info parse error: {}", e))
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(info)
|
||||
}
|
||||
}
|
||||
|
||||
impl Package {
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
let mut builder = Builder::new();
|
||||
builder.support_format(libarchive::ReadFormat::Tar)?;
|
||||
builder.support_filter(libarchive::ReadFilter::All)?;
|
||||
|
||||
let mut ar = builder.open_file(path)?;
|
||||
|
||||
let mut info: PkgInfo;
|
||||
let mut files: Vec<PathBuf> = Vec::new();
|
||||
|
||||
for entry in ar.entries() {
|
||||
let entry = entry?;
|
||||
let path_name = entry.pathname();
|
||||
|
||||
if !IGNORED_FILES.iter().any(|p| p == &path_name) {
|
||||
files.push(PathBuf::from(path_name));
|
||||
}
|
||||
|
||||
if path_name == ".PKGINFO" {
|
||||
let size = entry.size();
|
||||
info = PkgInfo::parse(entry)?;
|
||||
info.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue