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(()) } }