typed PKGINFO

This commit is contained in:
JMARyA 2025-06-26 13:00:24 +02:00
parent 6dcbc7321d
commit c53c11dbfe
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
4 changed files with 222 additions and 17 deletions

View file

@ -83,8 +83,12 @@ pub struct PackageInitCommand {
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "info")] #[argh(subcommand, name = "info")]
/// Print package info from PKGBUILD /// Print package info from PKGBUILD or package file
pub struct PackageInfoCommand {} pub struct PackageInfoCommand {
#[argh(positional)]
/// package file
pub pkg: Option<String>,
}
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "push")] #[argh(subcommand, name = "push")]

View file

@ -10,7 +10,7 @@ use cli::PaccoCLI;
use cmd_lib::{run_cmd, run_fun}; use cmd_lib::{run_cmd, run_fun};
use config::Config; use config::Config;
use pacco::pkg::arch::Architecture; use pacco::pkg::arch::Architecture;
use pacco::pkg::package::run_command; use pacco::pkg::package::{PackageFile, run_command};
use pacco::pkg::{Package, Repository}; use pacco::pkg::{Package, Repository};
use rocket::data::ToByteUnit; use rocket::data::ToByteUnit;
use rocket::{routes, tokio}; use rocket::{routes, tokio};
@ -335,9 +335,14 @@ async fn main() {
} }
} }
} }
cli::PackageCommands::Info(_) => { cli::PackageCommands::Info(info_args) => {
#[rustfmt::skip] if let Some(pkg) = &info_args.pkg {
run_cmd!(makepkg --printsrcinfo -s).unwrap(); let pkginfo = PackageFile::new(std::path::PathBuf::from(pkg)).pkginfo();
println!("{pkginfo:#?}");
} else {
#[rustfmt::skip]
run_cmd!(makepkg --printsrcinfo -s).unwrap();
}
} }
cli::PackageCommands::Push(package_push_command) => { cli::PackageCommands::Push(package_push_command) => {
pacco_push( pacco_push(

View file

@ -1,6 +1,5 @@
use std::{ use std::{
fs::File, io::Write,
io::{BufReader, Cursor, Read, Write},
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{Command, Stdio}, process::{Command, Stdio},
}; };
@ -26,6 +25,31 @@ pub struct Package {
pub compression: Compression, pub compression: Compression,
} }
pub struct PackageFile {
pub path: PathBuf,
pub compression: Compression,
}
impl PackageFile {
pub fn new(path: PathBuf) -> Self {
Self {
path: path.clone(),
compression: Compression::from_filename(path.to_str().unwrap()).unwrap(),
}
}
pub fn pkginfo(&self) -> PackageInfo {
let content = read_file_tar(&self.path, ".PKGINFO", self.compression.clone()).unwrap();
let keys = Package::pkginfo_from_str(&content);
PackageInfo::new(keys)
}
pub fn pkginfo_raw(&self) -> Vec<(String, String)> {
let content = read_file_tar(&self.path, ".PKGINFO", self.compression.clone()).unwrap();
Package::pkginfo_from_str(&content)
}
}
impl Package { impl Package {
/// Create a new package /// Create a new package
pub fn new( pub fn new(
@ -109,14 +133,12 @@ impl Package {
ret ret
} }
pub fn pkginfo(&self) -> Vec<(String, String)> { pub fn pkginfo(&self) -> PackageInfo {
let content = read_file_tar( PackageFile::new(self.base_path().join(self.file_name())).pkginfo()
&self.base_path().join(self.file_name()), }
".PKGINFO",
self.compression.clone(), pub fn pkginfo_raw(&self) -> Vec<(String, String)> {
) PackageFile::new(self.base_path().join(self.file_name())).pkginfo_raw()
.unwrap();
Package::pkginfo_from_str(&content)
} }
pub fn arch(&self) -> Vec<Architecture> { pub fn arch(&self) -> Vec<Architecture> {
@ -661,3 +683,177 @@ impl Compression {
} }
} }
} }
#[derive(Debug, Default)]
pub struct PackageInfo {
/// Architecture
pub architectures: Vec<Architecture>,
/// Build Timestamp
pub build_date: i64,
/// Licenses
pub licenses: Vec<String>,
/// Make Dependencies
pub makedepends: Vec<String>,
/// Packager
pub packager: Option<String>,
/// Package Base
pub pkgbase: String,
/// Description
pub description: String,
/// Package Name
pub name: String,
/// Version
pub version: String,
/// Size
pub size: i64,
/// Website
pub website: Option<String>,
/// XDATA
pub xdata: Option<String>,
/// Dependencies
pub dependencies: Vec<String>,
/// Optional Dependencies
pub opt_depends: Vec<OptionalDependency>,
/// Provides
pub provides: Vec<String>,
// Replaces
pub replaces: Vec<String>,
/// Backup
pub backup: Vec<String>,
/// Conflicts
pub conflict: Vec<String>,
/// Check Dependencies
pub check_depends: Vec<String>,
/// Groups
pub groups: Vec<String>,
}
#[derive(Debug, Default)]
pub struct OptionalDependency {
pub pkg: String,
pub reason: Option<String>,
}
impl PackageInfo {
pub fn new(keys: Vec<(String, String)>) -> Self {
let mut info = Self::default();
for (key, val) in keys {
match key.as_str() {
"arch" => {
info.architectures.push(Architecture::parse(&val).unwrap());
}
"builddate" => {
info.build_date = val.parse().unwrap();
}
"license" => {
let elements: Vec<_> = val.split(';').collect();
for e in elements {
let licenses: Vec<_> = e.split(" OR ").collect();
for e in licenses {
info.licenses.push(e.to_string());
}
}
}
"makedepend" => {
let pkgs: Vec<_> = val.split(';').collect();
for pkg in pkgs {
info.makedepends.push(pkg.to_string());
}
}
"packager" => {
info.packager = Some(val);
}
"pkgbase" => {
info.pkgbase = val;
}
"pkgdesc" => {
info.description = val;
}
"pkgname" => {
info.name = val;
}
"pkgver" => {
info.version = val;
}
"size" => {
info.size = val.parse().unwrap();
}
"url" => {
info.website = Some(val);
}
"xdata" => {
info.xdata = Some(val);
}
"depend" => {
let pkgs: Vec<_> = val.split(';').collect();
for pkg in pkgs {
info.dependencies.push(pkg.to_string());
}
}
"optdepend" => {
let pkgs: Vec<_> = val.split(';').collect();
for pkg in pkgs {
let (pkg, reason) = if let Some((pkg, reason)) = pkg.split_once(':') {
let reason = if !reason.is_empty() {
Some(reason.trim().to_string())
} else {
None
};
(pkg, reason)
} else {
(pkg, None)
};
info.opt_depends.push(OptionalDependency {
pkg: pkg.to_string(),
reason: reason,
});
}
}
"provides" => {
let provides: Vec<_> = val.split(';').collect();
for p in provides {
info.provides.push(p.to_string());
}
}
"replaces" => {
let replaces: Vec<_> = val.split(';').collect();
for r in replaces {
info.replaces.push(r.to_string());
}
}
"backup" => {
let backups: Vec<_> = val.split(';').collect();
for b in backups {
info.backup.push(b.to_string());
}
}
"conflict" => {
let conflicts: Vec<_> = val.split(';').collect();
for e in conflicts {
info.conflict.push(e.to_string());
}
}
"checkdepend" => {
let pkgs: Vec<_> = val.split(';').collect();
for pkg in pkgs {
info.check_depends.push(pkg.to_string());
}
}
"group" => {
let groups: Vec<_> = val.split(';').collect();
for group in groups {
info.groups.push(group.to_string());
}
}
_ => {
println!("Unrecognized key {key} -> {val}");
std::process::exit(1);
}
}
}
info
}
}

View file

@ -46,7 +46,7 @@ pub async fn pkg_ui(
let icons = pkg.icons(); let icons = pkg.icons();
let readmes = pkg.readmes(); let readmes = pkg.readmes();
let fonts = pkg.fonts(); let fonts = pkg.fonts();
let mut pkginfo = pkg.pkginfo(); let mut pkginfo = pkg.pkginfo_raw();
let pkg_info_header = Flex( let pkg_info_header = Flex(
// Package Name // Package Name