feat: generate all archives for "any" package

concurrent-repos
Jef Roosens 2024-05-26 20:37:17 +02:00
parent 2d4cfee27a
commit 88addc7a7a
Signed by: Jef Roosens
GPG Key ID: 02D4C0997E74717B
1 changed files with 39 additions and 13 deletions

View File

@ -1,22 +1,18 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use libarchive::write::{Builder, WriteEntry}; use sea_orm::{ColumnTrait, DbConn, ModelTrait, QueryFilter, QuerySelect};
use libarchive::{Entry, WriteFilter, WriteFormat};
use sea_orm::{ColumnTrait, DbConn, EntityTrait, ModelTrait, QueryFilter, QuerySelect};
use uuid::Uuid; use uuid::Uuid;
use futures::StreamExt; use futures::StreamExt;
use tokio::io::AsyncRead; use tokio::io::AsyncRead;
use tokio::io::{AsyncSeekExt, AsyncWriteExt}; use tokio::io::AsyncWriteExt;
use super::archive; use super::archive;
use super::package; use super::package;
use crate::db; use crate::db;
use crate::error::Result; use crate::error::Result;
pub const ANY_ARCH: &str = "any"; pub const ANY_ARCH: &'static str = "any";
pub struct MetaRepoMgr { pub struct MetaRepoMgr {
repo_dir: PathBuf, 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::<String>()
.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<()> { pub async fn generate_archives(&self, conn: &DbConn, repo: &str, arch: &str) -> Result<()> {
let repo = crate::db::query::repo::by_name(conn, repo).await?; let repo = crate::db::query::repo::by_name(conn, repo).await?;
@ -40,6 +63,7 @@ impl MetaRepoMgr {
} }
let repo = repo.unwrap(); let repo = repo.unwrap();
let parent_dir = self.repo_dir.join(&repo.name).join(arch); let parent_dir = self.repo_dir.join(&repo.name).join(arch);
tokio::fs::create_dir_all(&parent_dir).await?; tokio::fs::create_dir_all(&parent_dir).await?;
@ -51,7 +75,7 @@ impl MetaRepoMgr {
// architecture // architecture
let mut pkgs = repo let mut pkgs = repo
.find_related(crate::db::Package) .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) .stream(conn)
.await?; .await?;
@ -79,6 +103,7 @@ impl MetaRepoMgr {
} }
ar_files.close().await?; ar_files.close().await?;
tokio::fs::remove_file(tmp_file_path).await?;
Ok(()) Ok(())
} }
@ -178,9 +203,10 @@ impl MetaRepoMgr {
tokio::fs::rename(path, dest_pkg_path).await?; tokio::fs::rename(path, dest_pkg_path).await?;
// Synchronize archive databases // Synchronize archive databases
// TODO account for "any" architecture here if arch == ANY_ARCH {
self.generate_archives(conn, repo, &arch).await?; self.generate_archives_all(conn, repo).await
} else {
Ok(()) self.generate_archives(conn, repo, &arch).await
}
} }
} }