From 88addc7a7ab81f288c8c385de2cc72d932fde8a3 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 26 May 2024 20:37:17 +0200 Subject: [PATCH] feat: generate all archives for "any" package --- server/src/repo/manager_new.rs | 52 +++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/server/src/repo/manager_new.rs b/server/src/repo/manager_new.rs index 8b3a1bd..4dbea8a 100644 --- a/server/src/repo/manager_new.rs +++ b/server/src/repo/manager_new.rs @@ -1,22 +1,18 @@ use std::path::{Path, PathBuf}; -use std::sync::{Arc, Mutex}; -use libarchive::write::{Builder, WriteEntry}; -use libarchive::{Entry, WriteFilter, WriteFormat}; - -use sea_orm::{ColumnTrait, DbConn, EntityTrait, ModelTrait, QueryFilter, QuerySelect}; +use sea_orm::{ColumnTrait, DbConn, ModelTrait, QueryFilter, QuerySelect}; use uuid::Uuid; use futures::StreamExt; use tokio::io::AsyncRead; -use tokio::io::{AsyncSeekExt, AsyncWriteExt}; +use tokio::io::AsyncWriteExt; use super::archive; use super::package; use crate::db; use crate::error::Result; -pub const ANY_ARCH: &str = "any"; +pub const ANY_ARCH: &'static str = "any"; pub struct MetaRepoMgr { repo_dir: PathBuf, @@ -31,7 +27,34 @@ impl MetaRepoMgr { } } - /// Generate the `db` and `files` archive files for the given repo and architecture. + /// Generate archive databases for all known architectures in the repository, including the + /// "any" architecture. + pub async fn generate_archives_all(&self, conn: &DbConn, repo: &str) -> Result<()> { + let repo = crate::db::query::repo::by_name(conn, repo).await?; + + if repo.is_none() { + return Ok(()); + } + + let repo = repo.unwrap(); + + let mut archs = repo + .find_related(crate::db::Package) + .select_only() + .column(crate::db::package::Column::Arch) + .distinct() + .into_tuple::() + .stream(conn) + .await?; + + while let Some(arch) = archs.next().await.transpose()? { + self.generate_archives(conn, &repo.name, &arch).await?; + } + + Ok(()) + } + + /// Generate the archive databases for the given repository and architecture. pub async fn generate_archives(&self, conn: &DbConn, repo: &str, arch: &str) -> Result<()> { let repo = crate::db::query::repo::by_name(conn, repo).await?; @@ -40,6 +63,7 @@ impl MetaRepoMgr { } let repo = repo.unwrap(); + let parent_dir = self.repo_dir.join(&repo.name).join(arch); tokio::fs::create_dir_all(&parent_dir).await?; @@ -51,7 +75,7 @@ impl MetaRepoMgr { // architecture let mut pkgs = repo .find_related(crate::db::Package) - .filter(db::package::Column::Arch.eq(arch).or(ANY_ARCH.into())) + .filter(db::package::Column::Arch.is_in([arch, ANY_ARCH])) .stream(conn) .await?; @@ -79,6 +103,7 @@ impl MetaRepoMgr { } ar_files.close().await?; + tokio::fs::remove_file(tmp_file_path).await?; Ok(()) } @@ -178,9 +203,10 @@ impl MetaRepoMgr { tokio::fs::rename(path, dest_pkg_path).await?; // Synchronize archive databases - // TODO account for "any" architecture here - self.generate_archives(conn, repo, &arch).await?; - - Ok(()) + if arch == ANY_ARCH { + self.generate_archives_all(conn, repo).await + } else { + self.generate_archives(conn, repo, &arch).await + } } }