From ccd108591fd333b915a405e7f61d47add29f0bfa Mon Sep 17 00:00:00 2001 From: innocentzero Date: Thu, 22 Feb 2024 02:26:04 +0530 Subject: [PATCH] feat(rustup): Add rustup as a backend Adds rustup as a backend for pacdef. Only works on components listed for now. Signed-off-by: innocentzero --- crates/pacdef_core/src/backend/actual/mod.rs | 1 + .../pacdef_core/src/backend/actual/rustup.rs | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 crates/pacdef_core/src/backend/actual/rustup.rs diff --git a/crates/pacdef_core/src/backend/actual/mod.rs b/crates/pacdef_core/src/backend/actual/mod.rs index a30c8c1..36ad67e 100644 --- a/crates/pacdef_core/src/backend/actual/mod.rs +++ b/crates/pacdef_core/src/backend/actual/mod.rs @@ -5,3 +5,4 @@ pub mod debian; pub mod flatpak; pub mod python; pub mod rust; +pub mod rustup; diff --git a/crates/pacdef_core/src/backend/actual/rustup.rs b/crates/pacdef_core/src/backend/actual/rustup.rs new file mode 100644 index 0000000..682429b --- /dev/null +++ b/crates/pacdef_core/src/backend/actual/rustup.rs @@ -0,0 +1,69 @@ +use crate::backend::backend_trait::{Backend, Switches, Text}; +use crate::backend::macros::impl_backend_constants; +use crate::{Group, Package}; +use anyhow::Context; +use core::panic; +use std::collections::HashSet; +use std::process::Command; + +#[derive(Debug, Clone)] +pub struct Rustup { + pub(crate) packages: HashSet, +} + +const BINARY: Text = "rustup"; +const SECTION: Text = "rustup"; + +const SWITCHES_INSTALL: Switches = &["component", "add"]; +const SWITCHES_INFO: Switches = &["component", "list", "--installed"]; +const SWITCHES_MAKE_DEPENDENCY: Switches = &[]; +const SWITCHES_NOCONFIRM: Switches = &[]; +const SWITCHES_REMOVE: Switches = &["component", "remove"]; + +const SUPPORTS_AS_DEPENDENCY: bool = false; + +impl Backend for Rustup { + impl_backend_constants!(); + + fn get_all_installed_packages(&self) -> anyhow::Result> { + let mut cmd = Command::new(self.get_binary()); + let packages: HashSet = run_rustup_command(&mut cmd, SWITCHES_INFO) + .context("Getting installed components")? + .iter() + .map(|name| ["component/", name].join("").into()) + .collect(); + Ok(packages) + } + + fn get_explicitly_installed_packages(&self) -> anyhow::Result> { + self.get_all_installed_packages() + .context("Getting all installed packages") + } + + fn make_dependency(&self, _: &[Package]) -> anyhow::Result { + panic!("Not supported by {}", BINARY) + } +} + +fn run_rustup_command(cmd: &mut Command, args: &[&str]) -> Result, anyhow::Error> { + cmd.args(args); + let output = String::from_utf8(cmd.output()?.stdout)?; + let mut val = Vec::new(); + for i in output.lines() { + let mut it = i.splitn(3, "-"); + let component = it.next().expect("Component name is empty!"); + match component { + "cargo" | "rustfmt" | "clippy" | "miri" | "rls" | "rustc" => { + val.push(component.to_string()); + } + _ => { + val.push( + component.to_string() + + "-" + + it.next().expect("No such component is managed by rustup"), + ); + } + } + } + Ok(val) +}