feat: almost full desc file writer

concurrent-repos
Jef Roosens 2024-05-26 23:06:59 +02:00
parent 88addc7a7a
commit ce7b5159e8
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 142 additions and 19 deletions

View File

@ -38,10 +38,11 @@ impl RepoArchiveWriter {
}
/// Set the current entry to be a new "files" list
pub async fn add_files_entry<P: AsRef<Path>>(
pub async fn add_entry<P: AsRef<Path>>(
&self,
full_name: &str,
path: P,
desc: bool,
) -> io::Result<()> {
let metadata = tokio::fs::metadata(&path).await?;
let file_size = metadata.len();
@ -53,7 +54,10 @@ impl RepoArchiveWriter {
Ok(tokio::task::spawn_blocking(move || {
let mut ar_entry = WriteEntry::new();
ar_entry.set_filetype(libarchive::archive::FileType::RegularFile);
ar_entry.set_pathname(PathBuf::from(full_name).join("files"));
let name = if desc { "desc" } else { "files" };
ar_entry.set_pathname(PathBuf::from(full_name).join(name));
ar_entry.set_mode(0o100644);
ar_entry.set_size(file_size.try_into().unwrap());

View File

@ -80,30 +80,29 @@ impl MetaRepoMgr {
.await?;
let uuid: uuid::fmt::Simple = Uuid::new_v4().into();
let tmp_file_path = self.pkg_dir.join(uuid.to_string());
let files_tmp_file_path = self.pkg_dir.join(uuid.to_string());
let uuid: uuid::fmt::Simple = Uuid::new_v4().into();
let desc_tmp_file_path = self.pkg_dir.join(uuid.to_string());
while let Some(pkg) = pkgs.next().await.transpose()? {
let mut tmp_file = tokio::fs::File::create(&tmp_file_path).await?;
let mut files_tmp_file = tokio::fs::File::create(&files_tmp_file_path).await?;
let mut desc_tmp_file = tokio::fs::File::create(&desc_tmp_file_path).await?;
let line = "%FILES%\n";
tmp_file.write_all(line.as_bytes()).await?;
// Generate the files list for the package
let mut files = pkg.find_related(db::PackageFile).stream(conn).await?;
while let Some(file) = files.next().await.transpose()? {
tmp_file
.write_all(format!("{}\n", file.path).as_bytes())
.await?;
}
package::write_files(conn, &mut files_tmp_file, &pkg).await?;
package::write_desc(conn, &mut desc_tmp_file, &pkg).await?;
let full_name = format!("{}-{}", pkg.name, pkg.version);
ar_files
.add_files_entry(&format!("{}-{}", pkg.name, pkg.version), &tmp_file_path)
.add_entry(&full_name, &desc_tmp_file_path, true)
.await?;
ar_files
.add_entry(&full_name, &files_tmp_file_path, false)
.await?;
}
ar_files.close().await?;
tokio::fs::remove_file(tmp_file_path).await?;
tokio::fs::remove_file(files_tmp_file_path).await?;
Ok(())
}

View File

@ -1,13 +1,15 @@
use chrono::NaiveDateTime;
use futures::StreamExt;
use libarchive::read::{Archive, Builder};
use libarchive::{Entry, ReadFilter};
use sea_orm::ActiveValue::Set;
use sea_orm::{ActiveValue::Set, ColumnTrait, DbConn, ModelTrait, QueryFilter, QuerySelect};
use std::fmt;
use std::fs;
use std::io::{self, BufRead, BufReader, BufWriter, Read, Write};
use std::path::{Path, PathBuf};
use tokio::io::{AsyncWrite, AsyncWriteExt};
use crate::db::entities::package;
use crate::db::{self, entities::package, PackageRelatedEnum};
const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"];
@ -290,3 +292,121 @@ impl From<Package> for package::ActiveModel {
}
}
}
pub fn filename(pkg: &package::Model) -> String {
format!(
"{}-{}-{}.pkg.tar.{}",
pkg.name, pkg.version, pkg.arch, pkg.compression
)
}
async fn write_attribute<W: AsyncWrite + std::marker::Unpin>(
writer: &mut W,
key: &str,
value: &str,
) -> io::Result<()> {
if !value.is_empty() {
let s = format!("\n%{}%\n{}\n", key, value);
writer.write_all(s.as_bytes()).await?;
}
Ok(())
}
pub async fn write_desc<W: AsyncWrite + std::marker::Unpin>(
conn: &DbConn,
writer: &mut W,
pkg: &package::Model,
) -> crate::Result<()> {
writer
.write_all(format!("%FILENAME%\n{}\n", filename(pkg)).as_bytes())
.await?;
write_attribute(writer, "NAME", &pkg.name).await?;
write_attribute(writer, "BASE", &pkg.base).await?;
write_attribute(writer, "VERSION", &pkg.version).await?;
if let Some(ref description) = pkg.description {
write_attribute(writer, "DESC", description).await?;
}
let groups: Vec<String> = pkg
.find_related(db::PackageGroup)
.select_only()
.column(db::package_group::Column::Name)
.into_tuple()
.all(conn)
.await?;
write_attribute(writer, "GROUPS", &groups.join("\n")).await?;
write_attribute(writer, "CSIZE", &pkg.c_size.to_string()).await?;
write_attribute(writer, "ISIZE", &pkg.size.to_string()).await?;
write_attribute(writer, "SHA256SUM", &pkg.sha256_sum).await?;
if let Some(ref url) = pkg.url {
write_attribute(writer, "URL", url).await?;
}
let licenses: Vec<String> = pkg
.find_related(db::PackageLicense)
.select_only()
.column(db::package_license::Column::Name)
.into_tuple()
.all(conn)
.await?;
write_attribute(writer, "LICENSE", &licenses.join("\n")).await?;
write_attribute(writer, "ARCH", &pkg.arch).await?;
// TODO build date
//write_attribute(writer, "BUILDDATE", &pkg.build_)
if let Some(ref packager) = pkg.packager {
write_attribute(writer, "PACKAGER", packager).await?;
}
let related = [
("REPLACES", PackageRelatedEnum::Replaces),
("CONFLICTS", PackageRelatedEnum::Conflicts),
("PROVIDES", PackageRelatedEnum::Provides),
("DEPENDS", PackageRelatedEnum::Depend),
("OPTDEPENDS", PackageRelatedEnum::Optdepend),
("MAKEDEPENDS", PackageRelatedEnum::Makedepend),
("CHECKDEPENDS", PackageRelatedEnum::Checkdepend),
];
for (key, attr) in related.into_iter() {
let items: Vec<String> = pkg
.find_related(db::PackageRelated)
.filter(db::package_related::Column::Type.eq(attr))
.select_only()
.column(db::package_related::Column::Name)
.into_tuple()
.all(conn)
.await?;
write_attribute(writer, key, &items.join("\n")).await?;
}
Ok(())
}
pub async fn write_files<W: AsyncWrite + std::marker::Unpin>(
conn: &DbConn,
writer: &mut W,
pkg: &package::Model,
) -> crate::Result<()> {
let line = "%FILES%\n";
writer.write_all(line.as_bytes()).await?;
// Generate the files list for the package
let mut files = pkg.find_related(db::PackageFile).stream(conn).await?;
while let Some(file) = files.next().await.transpose()? {
writer
.write_all(format!("{}\n", file.path).as_bytes())
.await?;
}
Ok(())
}