From 6b3cdf3e3d4417caa8f9d622561696a8d50c86aa Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Fri, 1 Nov 2024 22:22:18 +0100 Subject: add basic apt compatability --- src/packages.rs | 5 +++++ src/packages/apt.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/packages/apt.rs diff --git a/src/packages.rs b/src/packages.rs index 8efc928..3ff997d 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -1,5 +1,6 @@ use std::{fs::File, io::Read}; +use apt::Apt; use dnf::Dnf; use pacman::Pacman; use portage::Portage; @@ -7,6 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::error::{Error, Result}; +mod apt; mod dnf; mod pacman; mod portage; @@ -34,6 +36,7 @@ pub struct Package { #[derive(Debug, Clone, clap::ValueEnum, Serialize, Deserialize)] pub enum Manager { + Apt, Dnf, Pacman, Portage, @@ -65,6 +68,7 @@ impl Manager { fn from_str(value: &str) -> Result { Ok(match value { + "debian" | "ubuntu" |"linuxmint" => Self::Apt, "fedora" => Self::Dnf, "arch" => Self::Pacman, "gentoo" => Self::Portage, @@ -74,6 +78,7 @@ impl Manager { pub fn to_package_manager(&self) -> Box { match self { + Self::Apt => Box::new(Apt), Self::Dnf => Box::new(Dnf), Self::Pacman => Box::new(Pacman), Self::Portage => Box::new(Portage), diff --git a/src/packages/apt.rs b/src/packages/apt.rs new file mode 100644 index 0000000..2036559 --- /dev/null +++ b/src/packages/apt.rs @@ -0,0 +1,58 @@ +use std::process::{Command, Stdio}; + +use super::{Package, PackageList, PackageManager}; + +use crate::error::{Error, Result}; + +pub struct Apt; + +impl PackageManager for Apt { + fn get_installed(&self) -> Result { + let list = Command::new("apt").args(["list", "--installed"]).output().unwrap(); + + let mut pkgs: Vec = Vec::new(); + + let list_str = String::from_utf8(list.stdout).unwrap(); + let list_lines: Vec<&str> = list_str.split('\n').collect(); + // Pop first info line + let list_lines = &list_lines[1..list_lines.len()]; + for pkg in list_lines { + if pkg.is_empty() { + continue; + }; + + let split: Vec<&str> = pkg.split_whitespace().collect(); + if split.len() != 4 { + return Err(Error::UnknownOutput); + }; + + let Some(pkg_id) = split[0].split_once('/') else { + return Err(Error::UnknownOutput); + }; + + let explicit = split[3] == "[installed]"; + + pkgs.push(Package { + id: pkg_id.0.to_string(), + version: split[1].to_string(), + explicit + }) + } + + Ok(PackageList { packages: pkgs, manager: super::Manager::Apt }) + } + + fn install(&self, pkgs: Vec) -> Result<()> { + let mut args = vec!["apt".to_string(), "install".to_string(), "--yes".to_string()]; + + for pkg in pkgs { + args.push(pkg.id); + } + Command::new("sudo") + .stdout(Stdio::inherit()) + .args(args) + .spawn()? + .wait_with_output()?; + Ok(()) + } +} -- cgit v1.2.3