use std::process::{Command, Stdio}; use super::{Package, PackageList, PackageManager}; use crate::error::{Error, Result}; pub struct Dnf; impl PackageManager for Dnf { fn get_installed(&self) -> Result { let list = Command::new("dnf").args(["list", "installed"]).output().unwrap(); let explicit_list = Command::new("dnf").args(["repoquery", "--userinstalled"]).output().unwrap(); let list_str = String::from_utf8(list.stdout).unwrap(); let ex_list_str = String::from_utf8(explicit_list.stdout).unwrap(); let mut pkgs: Vec = Vec::new(); 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() != 3 { return Err(Error::UnknownOutput); }; let explicit = ex_list_str.contains(pkg); let Some(pkg_id) = split[0].split_once('.') else { return Err(Error::UnknownOutput); }; pkgs.push(Package { id: pkg_id.0.to_string(), version: split[1].to_string(), explicit, }); } Ok(PackageList { packages: pkgs, manager: super::Manager::Dnf, }) } fn install(&self, pkgs: Vec) -> Result<()> { let mut args = vec!["dnf".to_string(), "install".to_string(), "--assumeyes".to_string()]; for pkg in pkgs { args.push(pkg.id); } Command::new("sudo") .stdout(Stdio::inherit()) .args(args) .spawn()? .wait_with_output()?; Ok(()) } }