✨ support more package compressions
This commit is contained in:
parent
788de4da7d
commit
656df96792
6 changed files with 115 additions and 36 deletions
|
@ -51,9 +51,7 @@ async fn launch() -> _ {
|
|||
..Default::default()
|
||||
})
|
||||
.mount_assets()
|
||||
.mount(
|
||||
"/",
|
||||
routes![
|
||||
.mount("/", routes![
|
||||
routes::index_page,
|
||||
routes::pkg_route,
|
||||
routes::push::upload_pkg,
|
||||
|
@ -66,8 +64,7 @@ async fn launch() -> _ {
|
|||
routes::user::end_session,
|
||||
routes::user::change_password,
|
||||
routes::user::change_password_post
|
||||
],
|
||||
)
|
||||
])
|
||||
.manage(config)
|
||||
.manage(shell)
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ impl MirrorRepository {
|
|||
}
|
||||
|
||||
// PKG
|
||||
let (name, _, _, arch) = Package::extract_pkg_name(pkg_name).unwrap();
|
||||
let (name, _, _, arch, _) = Package::extract_pkg_name(pkg_name).unwrap();
|
||||
|
||||
self.download_package(pkg_name, &name, arch, mirrorlist)
|
||||
.await;
|
||||
|
|
|
@ -23,17 +23,27 @@ pub struct Package {
|
|||
pub rel: i32,
|
||||
/// Version of the package
|
||||
pub version: Option<String>,
|
||||
/// Compression used
|
||||
pub compression: Compression,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
/// Create a new package
|
||||
pub fn new(repo: &str, arch: Architecture, pkg_name: &str, version: &str, rel: i32) -> Self {
|
||||
pub fn new(
|
||||
repo: &str,
|
||||
arch: Architecture,
|
||||
pkg_name: &str,
|
||||
version: &str,
|
||||
rel: i32,
|
||||
compression: Compression,
|
||||
) -> Self {
|
||||
let pkg = Package {
|
||||
repo: repo.to_string(),
|
||||
arch,
|
||||
name: pkg_name.to_string(),
|
||||
rel: rel,
|
||||
version: Some(version.to_string()),
|
||||
compression,
|
||||
};
|
||||
|
||||
std::fs::create_dir_all(pkg.base_path()).unwrap();
|
||||
|
@ -128,27 +138,38 @@ impl Package {
|
|||
/// ```
|
||||
/// use pacco::pkg::Package;
|
||||
///
|
||||
/// let (name, version, rel, arch) = Package::extract_pkg_name("pkg-ver-rel-x86_64.pkg.tar.zst").unwrap();
|
||||
/// let (name, version, rel, arch, compress) = Package::extract_pkg_name("pkg-ver-rel-x86_64.pkg.tar.zst").unwrap();
|
||||
/// assert_eq!(name, "pkg");
|
||||
/// assert_eq!(version, "ver");
|
||||
/// assert_eq!(rel, "rel");
|
||||
/// assert_eq!(arch, pacco::pkg::arch::Architecture::x86_64);
|
||||
/// assert_eq!(compress, pacco::pkg::package::Compression::Zstd);
|
||||
///
|
||||
/// let (name, version, rel, arch) = Package::extract_pkg_name("my-pkg-ver-rel-x86_64.pkg.tar.zst").unwrap();
|
||||
/// let (name, version, rel, arch, compress) = Package::extract_pkg_name("my-pkg-ver-rel-x86_64.pkg.tar.xz").unwrap();
|
||||
/// assert_eq!(name, "my-pkg");
|
||||
/// assert_eq!(version, "ver");
|
||||
/// assert_eq!(rel, "rel");
|
||||
/// assert_eq!(arch, pacco::pkg::arch::Architecture::x86_64);
|
||||
/// assert_eq!(compress, pacco::pkg::package::Compression::Xz);
|
||||
/// ```
|
||||
pub fn extract_pkg_name(file_name: &str) -> Option<(String, String, String, Architecture)> {
|
||||
pub fn extract_pkg_name(
|
||||
file_name: &str,
|
||||
) -> Option<(String, String, String, Architecture, Compression)> {
|
||||
// Extract (assuming the filename is "<pkg_name>-<version>-<relation>-<arch>.pkg.tar.zst")
|
||||
let file_name = file_name.trim_end_matches(".sig").to_string();
|
||||
|
||||
let mut splitted = file_name.split('-').collect::<Vec<&str>>();
|
||||
|
||||
let arch = splitted.pop()?;
|
||||
assert!(arch.ends_with(".pkg.tar.zst"), "{file_name}");
|
||||
let arch = arch.trim_end_matches(".pkg.tar.zst");
|
||||
|
||||
let compression = Compression::from_filename(arch);
|
||||
assert!(compression.is_some());
|
||||
let compression = compression.unwrap();
|
||||
|
||||
let arch = match compression {
|
||||
Compression::Zstd => arch.trim_end_matches(".pkg.tar.zst"),
|
||||
Compression::Xz => arch.trim_end_matches(".pkg.tar.xz"),
|
||||
};
|
||||
|
||||
let relation = splitted.pop()?;
|
||||
let version = splitted.pop()?;
|
||||
|
@ -160,29 +181,50 @@ impl Package {
|
|||
version.to_string(),
|
||||
relation.to_string(),
|
||||
Architecture::parse(arch)?,
|
||||
compression,
|
||||
))
|
||||
}
|
||||
|
||||
/// Parse a pkg filename
|
||||
pub fn from_filename(repo: &str, file_name: &str) -> Package {
|
||||
let (pkg_name, version, rel, arch) = Package::extract_pkg_name(file_name).unwrap();
|
||||
let (pkg_name, version, rel, arch, compression) =
|
||||
Package::extract_pkg_name(file_name).unwrap();
|
||||
Self {
|
||||
repo: repo.to_string(),
|
||||
arch,
|
||||
name: pkg_name,
|
||||
rel: rel.parse().unwrap(),
|
||||
version: Some(version.to_string()),
|
||||
compression,
|
||||
}
|
||||
}
|
||||
|
||||
/// Find a package with latest version
|
||||
pub fn find(repo: &str, arch: Architecture, pkg_name: &str) -> Option<Self> {
|
||||
if let Some(pkg) = Self::find_compressed(repo, arch.clone(), pkg_name, Compression::Zstd) {
|
||||
return Some(pkg);
|
||||
}
|
||||
if let Some(pkg) = Self::find_compressed(repo, arch, pkg_name, Compression::Xz) {
|
||||
return Some(pkg);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Find a package with latest version
|
||||
fn find_compressed(
|
||||
repo: &str,
|
||||
arch: Architecture,
|
||||
pkg_name: &str,
|
||||
compression: Compression,
|
||||
) -> Option<Self> {
|
||||
let mut base = Package {
|
||||
repo: repo.to_string(),
|
||||
arch,
|
||||
name: pkg_name.to_string(),
|
||||
rel: 1,
|
||||
version: None,
|
||||
compression,
|
||||
};
|
||||
|
||||
let versions = base.versions();
|
||||
|
@ -397,7 +439,7 @@ impl Package {
|
|||
/// Build a pkg filename from the packages values
|
||||
pub fn file_name(&self) -> String {
|
||||
format!(
|
||||
"{}-{}-{}-{}.pkg.tar.zst",
|
||||
"{}-{}-{}-{}.pkg.tar.{}",
|
||||
self.name,
|
||||
if let Some(ver) = &self.version {
|
||||
ver.to_string()
|
||||
|
@ -407,9 +449,14 @@ impl Package {
|
|||
},
|
||||
self.rel,
|
||||
self.arch.to_string(),
|
||||
self.compression.extension()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn has_pkg_ext(filename: &str) -> bool {
|
||||
filename.ends_with(".pkg.tar.zst") || filename.ends_with(".pkg.tar.xz")
|
||||
}
|
||||
|
||||
/// Get all versions of the package
|
||||
pub fn versions(&self) -> Vec<String> {
|
||||
let dir_path = self.base_path();
|
||||
|
@ -418,8 +465,8 @@ impl Package {
|
|||
if let Ok(entries) = std::fs::read_dir(dir_path) {
|
||||
for entry in entries.filter_map(Result::ok) {
|
||||
let file_name = entry.file_name().into_string().unwrap_or_default();
|
||||
if file_name.starts_with(&self.name) && file_name.ends_with(".pkg.tar.zst") {
|
||||
let (_, version, rel, _) = Package::extract_pkg_name(&file_name).unwrap();
|
||||
if file_name.starts_with(&self.name) && Package::has_pkg_ext(&file_name) {
|
||||
let (_, version, rel, _, _) = Package::extract_pkg_name(&file_name).unwrap();
|
||||
versions.push(format!("{version}-{rel}"));
|
||||
}
|
||||
}
|
||||
|
@ -562,3 +609,28 @@ impl PackageMetaInfo for Package {
|
|||
.execute(get_pg!()).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Compression {
|
||||
Zstd,
|
||||
Xz,
|
||||
}
|
||||
|
||||
impl Compression {
|
||||
pub fn from_filename(name: &str) -> Option<Self> {
|
||||
if name.ends_with("zst") {
|
||||
Some(Self::Zstd)
|
||||
} else if name.ends_with("xz") {
|
||||
Some(Self::Xz)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extension(&self) -> &str {
|
||||
match self {
|
||||
Compression::Zstd => "zst",
|
||||
Compression::Xz => "xz",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,8 +140,15 @@ impl Repository {
|
|||
|
||||
pub fn get_pkg(&self, pkg_name: &str) -> Option<Package> {
|
||||
// Find package
|
||||
let (name, version, rel, arch) = Package::extract_pkg_name(pkg_name).unwrap();
|
||||
let pkg = Package::new(&self.name, arch, &name, &version, rel.parse().unwrap());
|
||||
let (name, version, rel, arch, compress) = Package::extract_pkg_name(pkg_name).unwrap();
|
||||
let pkg = Package::new(
|
||||
&self.name,
|
||||
arch,
|
||||
&name,
|
||||
&version,
|
||||
rel.parse().unwrap(),
|
||||
compress,
|
||||
);
|
||||
|
||||
// Return if exists
|
||||
if pkg.exists() { Some(pkg) } else { None }
|
||||
|
|
|
@ -9,8 +9,8 @@ use pacco::pkg::package::PackageMetaInfo;
|
|||
use rocket::http::{ContentType, Status};
|
||||
use rocket::{State, get};
|
||||
|
||||
use pacco::pkg::Repository;
|
||||
use pacco::pkg::arch::Architecture;
|
||||
use pacco::pkg::{Package, Repository};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
|
@ -103,14 +103,14 @@ pub async fn pkg_route(
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
if pkg_name.ends_with("pkg.tar.zst") {
|
||||
if Package::has_pkg_ext(&pkg_name) {
|
||||
pkg.increase_download_count().await;
|
||||
return DataResponse::new_file(
|
||||
&pkg.pkg_content_path().unwrap(),
|
||||
"application/tar".to_string(),
|
||||
cache_duration,
|
||||
);
|
||||
} else if pkg_name.ends_with("pkg.tar.zst.sig") {
|
||||
} else if pkg_name.ends_with("sig") {
|
||||
return DataResponse::new(
|
||||
pkg.sig_content().unwrap(),
|
||||
"application/pgp-signature".to_string(),
|
||||
|
@ -144,13 +144,13 @@ pub async fn pkg_route(
|
|||
|
||||
let pkg = repo.get_pkg(pkg_name).unwrap();
|
||||
|
||||
if pkg_name.ends_with("pkg.tar.zst") {
|
||||
if Package::has_pkg_ext(&pkg_name) {
|
||||
return DataResponse::new_file(
|
||||
&pkg.pkg_content_path().unwrap(),
|
||||
"application/tar".to_string(),
|
||||
cache_duration,
|
||||
);
|
||||
} else if pkg_name.ends_with("pkg.tar.zst.sig") {
|
||||
} else if pkg_name.ends_with("sig") {
|
||||
return DataResponse::new(
|
||||
pkg.sig_content().unwrap(),
|
||||
"application/pgp-signature".to_string(),
|
||||
|
|
|
@ -77,7 +77,10 @@ pub async fn upload_pkg(
|
|||
|
||||
let arch = Architecture::parse(&arch).ok_or_else(|| api_error("Invalid architecture"))?;
|
||||
|
||||
let pkg = Package::new(repo, arch, pkg_name, &version, rel);
|
||||
let (_, _, _, _, compression) = Package::extract_pkg_name(upload.pkg.name().unwrap())
|
||||
.ok_or_else(|| api_error("Package has weird filename"))?;
|
||||
|
||||
let pkg = Package::new(repo, arch, pkg_name, &version, rel, compression);
|
||||
|
||||
pkg.save(
|
||||
pkg_file,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue