From d04156e43aba17bf51967c6e33ab236d024f6474 Mon Sep 17 00:00:00 2001 From: theMZet Date: Sat, 30 May 2026 04:13:33 +0200 Subject: [PATCH] feat: package manager change Now at runtime package manager can be swapped! --- Cargo.toml | 4 ---- src/main.rs | 23 ++++++++++++++--------- src/package_manager.rs | 34 ++++++++++++++++++---------------- src/world.rs | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 37c2854..1689503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,6 @@ repository = "https://git.polydevs.dev/theMZet/topaz" license="GPL-3.0-or-later" publish = false -[features] -yay = [] -paru = [] - [profile.release] strip = true diff --git a/src/main.rs b/src/main.rs index f8a83c1..86e1193 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,12 +31,9 @@ use error::*; use crate::{ package_manager::{get_system_state, get_unneeded_packages, remove_packages, update_packages}, - world::{Packages, World, get_world_location}, + world::{PackageManager, Packages, World, get_world_location}, }; -#[cfg(all(feature = "yay", feature = "paru"))] -compile_error!("'yay' and 'paru' are mutually exclusive and cannot be enabled together."); - #[cfg(not(target_os = "linux"))] compile_error!("Only (Arch) linux is supported!"); @@ -58,6 +55,9 @@ struct Args { #[arg(short, long, global = true)] quiet: bool, + #[arg(short, long, global = true)] + manager: Option, + #[command(subcommand)] command: Commands, } @@ -118,10 +118,10 @@ fn main() -> Result<()> { let mut x = world_state.exclude(&state); x.ignore = world_state.ignore.clone(); x.exclude_ignored(); - x.get_package_list() + x }; - update_packages(¬_installed, args.quiet)?; + update_packages(args.manager.unwrap_or(world.get_manager()), not_installed, args.quiet)?; if !args.quiet { println!("Succesfully synchronized state with the world file!"); @@ -133,8 +133,13 @@ fn main() -> Result<()> { persist_ignore, } => { let mut world = match World::load_from(world_path.clone()) { - Ok(x) => x, - Err(_) => World::new_empty(), + Ok(mut x) => { + x.set_manager(args.manager); + x + }, + Err(_) => { + World::new_empty(args.manager.unwrap_or(PackageManager::Pacman)) + }, }; let mut state = get_system_state()?; @@ -199,7 +204,7 @@ fn main() -> Result<()> { } } Commands::Diff => { - let world = World::load_from(world_path).unwrap_or(World::new_empty()); + let world = World::load_from(world_path).unwrap_or(World::new_empty(PackageManager::Pacman)); let world_state = world.get_packages(); let state = get_system_state()?; diff --git a/src/package_manager.rs b/src/package_manager.rs index b3185d0..69c2293 100644 --- a/src/package_manager.rs +++ b/src/package_manager.rs @@ -1,4 +1,4 @@ -use crate::{PRIVLAGE_ESCELATE_COMMAND, error::Result, world::Packages}; +use crate::{PRIVLAGE_ESCELATE_COMMAND, error::Result, world::{PackageManager, Packages}}; use std::process::{Command, Stdio}; pub fn get_system_state() -> Result { @@ -78,19 +78,21 @@ fn _update_packages(command: Command, packages: &[String], quiet: bool) -> Resul Ok(()) } -#[cfg(not(any(feature = "yay", feature = "paru")))] -pub fn update_packages(packages: &[String], quiet: bool) -> Result<()> { - let mut command = Command::new(PRIVLAGE_ESCELATE_COMMAND); - command.arg("pacman"); - _update_packages(command, packages, quiet) -} - -#[cfg(feature = "yay")] -pub fn update_packages(packages: &[String], quiet: bool) -> Result<()> { - _update_packages(Command::new("yay"), packages, quiet) -} - -#[cfg(feature = "paru")] -pub fn update_packages(packages: &[String], quiet: bool) -> Result<()> { - _update_packages(Command::new("paru"), packages, quiet) +pub fn update_packages(manager: PackageManager, packages: Packages, quiet: bool) -> Result<()> { + let (command, packages) = match manager { + PackageManager::Pacman => { + let mut command = Command::new(PRIVLAGE_ESCELATE_COMMAND); + command.arg("pacman"); + (command, packages.official.clone()) + }, + PackageManager::Yay => { + let command = Command::new("yay"); + (command, packages.get_package_list()) + }, + PackageManager::Paru => { + let command = Command::new("paru"); + (command, packages.get_package_list()) + } + }; + _update_packages(command, &packages, quiet) } diff --git a/src/world.rs b/src/world.rs index 82c53a4..4f058e0 100644 --- a/src/world.rs +++ b/src/world.rs @@ -2,6 +2,8 @@ use std::env; use std::io::Read; use std::{fs::File, path::PathBuf}; +use clap::ValueEnum; +use clap::builder::PossibleValue; use serde::{Deserialize, Serialize}; use crate::Result; @@ -24,6 +26,28 @@ pub struct Packages { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct World { packages: Packages, + manager: PackageManager, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum PackageManager { + Pacman, + Yay, + Paru, +} + +impl ValueEnum for PackageManager { + fn value_variants<'a>() -> &'a [Self] { + &[Self::Pacman, Self::Yay, Self::Paru] + } + + fn to_possible_value(&self) -> Option { + match self { + PackageManager::Pacman => Some(PossibleValue::new("pacman").alias("pm").help("Pacman package manager")), + PackageManager::Yay => Some(PossibleValue::new("yay").alias("yy").help("Yay package manager")), + PackageManager::Paru => Some(PossibleValue::new("paru").alias("pr").help("Paru package manager")), + } + } } impl Packages { @@ -70,9 +94,10 @@ impl Packages { } impl World { - pub fn new_empty() -> World { + pub fn new_empty(manager: PackageManager) -> World { World { packages: Packages::new(), + manager, } } @@ -84,6 +109,16 @@ impl World { &mut self.packages } + pub fn get_manager(&self) -> PackageManager { + self.manager + } + + pub fn set_manager(&mut self, manager: Option) { + if let Some(manager) = manager { + self.manager = manager; + } + } + pub fn load_from(world_path: PathBuf) -> Result { let mut file = File::open(world_path)?; let mut text = String::new();