From 1fc8add2c2edacb73b34f6aad1e9dea8dfd5525d Mon Sep 17 00:00:00 2001 From: innocentzero Date: Fri, 1 Mar 2024 22:07:26 +0530 Subject: [PATCH] feat(fedora): Add fedora as a backend Note- This is currently heavily experimental and not tested thoroughly. Signed-off-by: innocentzero --- .../pacdef_core/src/backend/actual/fedora.rs | 138 ++++++++++++++++++ crates/pacdef_core/src/backend/actual/mod.rs | 2 + crates/pacdef_core/src/backend/mod.rs | 2 + 3 files changed, 142 insertions(+) create mode 100644 crates/pacdef_core/src/backend/actual/fedora.rs diff --git a/crates/pacdef_core/src/backend/actual/fedora.rs b/crates/pacdef_core/src/backend/actual/fedora.rs new file mode 100644 index 0000000..195032e --- /dev/null +++ b/crates/pacdef_core/src/backend/actual/fedora.rs @@ -0,0 +1,138 @@ +use core::panic; +use std::collections::HashSet; +use std::process::{Command, ExitStatus}; + +use anyhow::{Context, Result}; +use regex::Regex; + +use crate::backend::backend_trait::{Backend, Switches, Text}; +use crate::backend::macros::impl_backend_constants; +use crate::{Group, Package}; + +#[derive(Debug, Clone)] +pub struct Fedora { + pub(crate) packages: HashSet, +} + +const BINARY: Text = "dnf"; +const SECTION: Text = "fedora"; + +const SWITCHES_INFO: Switches = &["list", "--installed"]; +const SWITCHES_INSTALL: Switches = &["install"]; +const SWITCHES_MAKE_DEPENDENCY: Switches = &[]; +const SWITCHES_NOCONFIRM: Switches = &["--assumeyes"]; +const SWITCHES_REMOVE: Switches = &["remove"]; + +const SUPPORTS_AS_DEPENDENCY: bool = true; + +impl Backend for Fedora { + impl_backend_constants!(); + + fn get_all_installed_packages(&self) -> Result> { + let re_str = r"^[0-9A-Za-z_-]*."; + let re = Regex::new(re_str)?; + + let mut cmd = Command::new(self.get_binary()); + cmd.args(self.get_switches_info()); + let output = String::from_utf8(cmd.output()?.stdout)?; + + let packages: HashSet = output + .lines() + .map(|line| { + let result = re + .find( + line.split_whitespace() + .next() + .expect("First word cannot be empty!"), + ) + .expect("Not a valid package name!"); + let mut result = result.as_str().to_string(); + result.pop(); + result.into() + }) + .collect(); + Ok(packages) + } + + fn get_explicitly_installed_packages(&self) -> Result> { + let re_str = r"^(([A-Za-z_]*[0-9]*)-)*"; + let re = Regex::new(re_str)?; + + let mut cmd = Command::new(self.get_binary()); + cmd.args(&["history", "userinstalled"]); + let output = String::from_utf8(cmd.output()?.stdout)?; + + let packages: HashSet = output + .lines() + .skip(1) + .map(|line| { + let word = re.find(line).expect("Not a valid package name"); + let mut word = word.as_str().to_string(); + word.pop(); + let pack = word.rsplit_once('-').map_or(word.clone(), |(pack, term)| { + let mut value = true; + for i in term.chars() { + if !i.is_numeric() { + value = false; + break; + } + } + if !value { + pack.to_string() + "-" + term + } else { + pack.to_string() + } + }); + pack.into() + }) + .collect(); + Ok(packages) + } + + /// Install the specified packages. + fn install_packages(&self, packages: &[Package], noconfirm: bool) -> Result { + let mut cmd = Command::new("sudo"); + cmd.arg(self.get_binary()); + cmd.args(self.get_switches_install()); + + if noconfirm { + cmd.args(self.get_switches_noconfirm()); + } + + for p in packages { + cmd.arg(format!("{p}")); + } + + cmd.status() + .with_context(|| format!("running command {cmd:?}")) + } + + fn remove_packages(&self, packages: &[Package], noconfirm: bool) -> Result { + let mut cmd = Command::new("sudo"); + cmd.arg(self.get_binary()); + cmd.args(self.get_switches_remove()); + + if noconfirm { + cmd.args(self.get_switches_noconfirm()); + } + + for p in packages { + cmd.arg(format!("{p}")); + } + + cmd.status() + .with_context(|| format!("running command [{cmd:?}]")) + } + + fn make_dependency(&self, _: &[Package]) -> Result { + panic!("Not supported by the package manager!") + } +} + +impl Fedora { + pub fn new() -> Self { + Fedora { + packages: HashSet::new(), + } + } +} diff --git a/crates/pacdef_core/src/backend/actual/mod.rs b/crates/pacdef_core/src/backend/actual/mod.rs index ea93f66..a652467 100644 --- a/crates/pacdef_core/src/backend/actual/mod.rs +++ b/crates/pacdef_core/src/backend/actual/mod.rs @@ -2,6 +2,8 @@ pub mod arch; #[cfg(feature = "debian")] pub mod debian; +#[cfg(feature = "fedora")] +pub mod fedora; pub mod flatpak; pub mod python; pub mod rust; diff --git a/crates/pacdef_core/src/backend/mod.rs b/crates/pacdef_core/src/backend/mod.rs index ab67304..cf6d1fc 100644 --- a/crates/pacdef_core/src/backend/mod.rs +++ b/crates/pacdef_core/src/backend/mod.rs @@ -18,6 +18,8 @@ pub enum Backends { #[cfg(feature = "debian")] Debian, Flatpak, + #[cfg(feature = "fedora")] + Fedora, Python, Rust, Rustup,