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)]
#[argh(subcommand, name = "info")]
/// Print package info from PKGBUILD
pub struct PackageInfoCommand {}
/// Print package info from PKGBUILD or package file
pub struct PackageInfoCommand {
#[argh(positional)]
/// package file
pub pkg: Option<String>,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "push")]

View file

@ -10,7 +10,7 @@ use cli::PaccoCLI;
use cmd_lib::{run_cmd, run_fun};
use config::Config;
use pacco::pkg::arch::Architecture;
use pacco::pkg::package::run_command;
use pacco::pkg::package::{PackageFile, run_command};
use pacco::pkg::{Package, Repository};
use rocket::data::ToByteUnit;
use rocket::{routes, tokio};
@ -335,10 +335,15 @@ async fn main() {
}
}
}
cli::PackageCommands::Info(_) => {
cli::PackageCommands::Info(info_args) => {
if let Some(pkg) = &info_args.pkg {
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) => {
pacco_push(
&package_push_command.package,

View file

@ -1,6 +1,5 @@
use std::{
fs::File,
io::{BufReader, Cursor, Read, Write},
io::Write,
path::{Path, PathBuf},
process::{Command, Stdio},
};
@ -26,6 +25,31 @@ pub struct Package {
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 {
/// Create a new package
pub fn new(
@ -109,14 +133,12 @@ impl Package {
ret
}
pub fn pkginfo(&self) -> Vec<(String, String)> {
let content = read_file_tar(
&self.base_path().join(self.file_name()),
".PKGINFO",
self.compression.clone(),
)
.unwrap();
Package::pkginfo_from_str(&content)
pub fn pkginfo(&self) -> PackageInfo {
PackageFile::new(self.base_path().join(self.file_name())).pkginfo()
}
pub fn pkginfo_raw(&self) -> Vec<(String, String)> {
PackageFile::new(self.base_path().join(self.file_name())).pkginfo_raw()
}
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 readmes = pkg.readmes();
let fonts = pkg.fonts();
let mut pkginfo = pkg.pkginfo();
let mut pkginfo = pkg.pkginfo_raw();
let pkg_info_header = Flex(
// Package Name