From 4c22f1cc89c0704ec705ef292583e17d9d9f5ed4 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Thu, 5 Jan 2023 17:25:39 +0100 Subject: [PATCH] add cargo backend --- src/backend/mod.rs | 13 +++++--- src/backend/pacman.rs | 8 ++--- src/backend/rust.rs | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 src/backend/rust.rs diff --git a/src/backend/mod.rs b/src/backend/mod.rs index cd31145..d4acaf8 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,4 +1,5 @@ mod pacman; +mod rust; use std::collections::HashSet; use std::os::unix::process::CommandExt; @@ -7,16 +8,18 @@ use std::process::Command; use crate::Package; pub use pacman::Pacman; +type Switches = &'static [&'static str]; +type Binary = &'static str; pub trait Backend { /// The binary that should be called to run the associated package manager. - const BINARY: &'static str; + const BINARY: Binary; /// The switches that signals the `BINARY` that the packages should be installed. - const SWITCH_INSTALL: &'static str; + const SWITCHES_INSTALL: Switches; /// The switches that signals the `BINARY` that the packages should be removed. - const SWITCH_REMOVE: &'static str; + const SWITCHES_REMOVE: Switches; /// Get all packages that are installed in the system. fn get_all_installed_packages() -> HashSet; @@ -27,7 +30,7 @@ pub trait Backend { /// Install the specified packages. fn install_packages(packages: Vec) { let mut cmd = Command::new(Self::BINARY); - cmd.arg(Self::SWITCH_INSTALL); + cmd.args(Self::SWITCHES_INSTALL); for p in packages { cmd.arg(format!("{p}")); } @@ -37,7 +40,7 @@ pub trait Backend { /// Remove the specified packages. fn remove_packages(packages: Vec) { let mut cmd = Command::new(Self::BINARY); - cmd.arg(Self::SWITCH_REMOVE); + cmd.args(Self::SWITCHES_REMOVE); for p in packages { cmd.arg(format!("{p}")); } diff --git a/src/backend/pacman.rs b/src/backend/pacman.rs index 0958fd4..1309159 100644 --- a/src/backend/pacman.rs +++ b/src/backend/pacman.rs @@ -3,15 +3,15 @@ use std::collections::HashSet; use alpm::Alpm; use alpm::PackageReason::Explicit; -use super::Backend; +use super::{Backend, Binary, Switches}; use crate::Package; pub struct Pacman; impl Backend for Pacman { - const BINARY: &'static str = "paru"; - const SWITCH_INSTALL: &'static str = "-S"; - const SWITCH_REMOVE: &'static str = "-Rsn"; + const BINARY: Binary = "paru"; + const SWITCHES_INSTALL: Switches = &["-S"]; + const SWITCHES_REMOVE: Switches = &["-Rsn"]; fn get_all_installed_packages() -> HashSet { convert_to_pacdef_packages(get_all_installed_packages_from_alpm()) diff --git a/src/backend/rust.rs b/src/backend/rust.rs new file mode 100644 index 0000000..3d9a501 --- /dev/null +++ b/src/backend/rust.rs @@ -0,0 +1,76 @@ +use std::{collections::HashSet, process::Command}; + +use super::{Backend, Binary, Switches}; +use crate::Package; + +pub struct Rust; + +impl Backend for Rust { + const BINARY: Binary = "cargo"; + const SWITCHES_INSTALL: Switches = &["install"]; + const SWITCHES_REMOVE: Switches = &["uninstall"]; + + fn get_all_installed_packages() -> HashSet { + extract_packages_names(&run_cargo_install_list()) + .map(Package::from) + .collect() + } + + fn get_explicitly_installed_packages() -> HashSet { + Self::get_all_installed_packages() + } +} + +fn run_cargo_install_list() -> String { + let stdout = Command::new("cargo") + .args(["install", "--list"]) + .output() + .unwrap() + .stdout; + String::from_utf8(stdout).unwrap() +} + +fn extract_packages_names(output: &str) -> impl Iterator + '_ { + output + .lines() + .filter(|line| !line.starts_with(char::is_whitespace)) + .map(|line| line.split_whitespace().next().unwrap().to_owned()) +} + +#[cfg(test)] +mod tests { + use super::extract_packages_names; + + #[test] + fn test_extract_packages() { + const OUTPUT: &str = "cargo-audit v0.17.4: + cargo-audit +cargo-cache v0.8.3: + cargo-cache +cargo-criterion v1.1.0: + cargo-criterion +cargo-update v11.1.1: + cargo-install-update + cargo-install-update-config +flamegraph v0.6.2: + cargo-flamegraph + flamegraph +topgrade v10.1.2 (/home/ratajc72/tmp/topgrade): + topgrade +wthrr v0.6.1: + wthrr"; + let extracted: Vec = extract_packages_names(OUTPUT).collect(); + assert_eq!( + &extracted, + &[ + "cargo-audit", + "cargo-cache", + "cargo-criterion", + "cargo-update", + "flamegraph", + "topgrade", + "wthrr" + ] + ); + } +}