From ec30fbab6ea45dcdec7d242fba2ff5555fea8e02 Mon Sep 17 00:00:00 2001 From: fx Date: Mon, 23 Sep 2024 18:56:39 +0200 Subject: add dnf package manager --- src/packages.rs | 5 +++++ src/packages/dnf.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/packages/dnf.rs (limited to 'src') diff --git a/src/packages.rs b/src/packages.rs index de818f4..2844a9b 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -1,11 +1,13 @@ use std::{fs::File, io::Read}; +use dnf::Dnf; use pacman::Pacman; use portage::Portage; use serde::{Deserialize, Serialize}; use crate::error::{Error, Result}; +mod dnf; mod pacman; mod portage; @@ -32,6 +34,7 @@ pub struct Package { #[derive(Debug, Clone, clap::ValueEnum, Serialize, Deserialize)] pub enum Manager { + Dnf, Pacman, Portage, } @@ -65,6 +68,7 @@ impl Manager { fn from_str(value: &str) -> Result> { Ok(match value { + "fedora" => Box::new(Dnf), "arch" => Box::new(Pacman), "gentoo" => Box::new(Portage), _ => return Err(Error::Unsupported), @@ -73,6 +77,7 @@ impl Manager { fn to_package_manager(&self) -> Box { match self { + Self::Dnf => Box::new(Dnf), Self::Pacman => Box::new(Pacman), Self::Portage => Box::new(Portage), } diff --git a/src/packages/dnf.rs b/src/packages/dnf.rs new file mode 100644 index 0000000..aad9c8f --- /dev/null +++ b/src/packages/dnf.rs @@ -0,0 +1,50 @@ +use std::process::Command; + +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<()> { todo!() } +} -- cgit v1.2.3 From aa375d821674cd1feea81e27c2918d0429dd54f6 Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Mon, 23 Sep 2024 22:16:54 +0200 Subject: cross device tests --- src/pathinfo.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/pathinfo.rs b/src/pathinfo.rs index 1231ff8..6ca6444 100644 --- a/src/pathinfo.rs +++ b/src/pathinfo.rs @@ -390,11 +390,15 @@ mod tests { #[test] fn compare_to_last_modified() -> color_eyre::Result<()> { + + let cwd = std::env::current_dir()?; + let test_dir = format!("{}/backup-test-dir", cwd.display()); + let mut config = Config::default(); config.root = "./backup-test".to_string(); config .directories - .push("u:fx/code/proj/arbs/backup-test-dir".to_string()); + .push(format!("r:{test_dir}")); create_dir_all("./backup-test-dir")?; let mut f = File::create("./backup-test-dir/size.txt")?; @@ -412,17 +416,21 @@ mod tests { let mut f = File::create("./backup-test-dir/content.txt")?; f.write_all("unmodefied".as_bytes())?; - let pi = PathInfo::from_path(&config, "u:fx/code/proj/arbs/backup-test-dir")?; + let pi = PathInfo::from_path(&config, format!("r:{test_dir}").as_str())?; + + let nothing_full = format!("{test_dir}/nothing.txt"); + let nothing = ¬hing_full[1..nothing_full.len()]; let last_backup = Backup::get_last(&config)?.unwrap(); for file in pi.children { println!("test rel: {}", file.rel_location); - let res = if file.rel_location == "code/proj/arbs/backup-test-dir/nothing.txt" { + println!("nothing: {}", nothing); + let res = if file.rel_location == nothing { Some(last_backup.id.clone()) } else { None }; - println!("Testing {file:?}"); + // println!("Testing {file:?}"); assert_eq!( PathInfo::compare_to_last_modified( &config, @@ -431,7 +439,7 @@ mod tests { )?, res ); - println!("\x1B[FTesting {file:?} ✓"); + // println!("\x1B[FTesting {file:?} ✓"); } remove_dir_all("./backup-test-dir")?; -- cgit v1.2.3 From d1a9d0d8a8746a63b93f8f14ee4f51b1cd240349 Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Sun, 29 Sep 2024 15:26:46 +0200 Subject: dnf install --- src/packages/dnf.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/packages/dnf.rs b/src/packages/dnf.rs index aad9c8f..6f451ee 100644 --- a/src/packages/dnf.rs +++ b/src/packages/dnf.rs @@ -1,4 +1,4 @@ -use std::process::Command; +use std::process::{Command, Stdio}; use super::{Package, PackageList, PackageManager}; @@ -46,5 +46,17 @@ impl PackageManager for Dnf { }) } - fn install(&self, _pkgs: Vec) -> Result<()> { todo!() } + 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(()) + } } -- cgit v1.2.3