From 553bbac36bdc483135a7053ca64507e01397e5e1 Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Mon, 9 Sep 2024 23:03:49 +0200 Subject: add package manager recognition --- src/packages.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) (limited to 'src/packages.rs') diff --git a/src/packages.rs b/src/packages.rs index 5ee5664..2eadcfc 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -1,19 +1,96 @@ +use std::{fs::File, io::Read}; + +use pacman::Pacman; +use portage::Portage; use serde::{Deserialize, Serialize}; -use crate::error::Result; +use crate::error::{Error, Result}; -pub mod pacman; -pub mod portage; +#[cfg(feature = "pacman")] +mod pacman; +#[cfg(feature = "portage")] +mod portage; #[derive(Debug, Serialize, Deserialize)] +pub struct PackageList { + packages: Vec, + manager: Manager, +} + +impl PackageList { + pub fn install(&self) -> Result<()> { + self.manager.to_package_manager().install(self.packages.clone()) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Package { pub id: String, pub version: String, pub explicit: bool, } +#[derive(Debug, Clone, clap::ValueEnum, Serialize, Deserialize)] +pub enum Manager { + #[cfg(feature = "pacman")] + Pacman, + #[cfg(feature = "portage")] + Portage, +} + + +impl Manager { + pub fn get_manager(manager: Option) -> Result> { + #[cfg(not(target_os = "linux"))] + { + return Err(Error::Unsupported); + } + + #[cfg(target_os = "linux")] + { + if let Some(man) = manager { + return Ok(man.to_package_manager()); + } + let mut os_release = File::open("/etc/os-release")?; + let mut content = String::new(); + os_release.read_to_string(&mut content)?; + + let lines: Vec<&str> = content.split('\n').collect(); + for line in lines { + let Some((key, value)) = line.split_once('=') else { + continue; + }; + if key == "ID" { + return Self::from_str(value); + } + } + Err(Error::Unsupported) + } + } + + fn from_str(value: &str) -> Result> { + Ok(match value { + #[cfg(feature = "pacman")] + "arch" => Box::new(Pacman), + #[cfg(feature = "portage")] + "gentoo" => Box::new(Portage), + _ => return Err(Error::Unsupported), + }) + } + + fn to_package_manager(&self) -> Box { + match self { + #[cfg(feature = "pacman")] + Self::Pacman => Box::new(Pacman), + #[cfg(feature = "portage")] + Self::Portage => Box::new(Portage), + } + } +} + + pub trait PackageManager { - fn get_installed(&self) -> Result>; + fn get_installed(&self) -> Result; fn install(&self, pkgs: Vec) -> Result<()>; } -- cgit v1.2.3