feat: package manager change

Now at runtime package manager can
be swapped!
This commit is contained in:
2026-05-30 04:13:33 +02:00
parent 87f79ef1b9
commit 7da2415ca1
4 changed files with 68 additions and 30 deletions
-4
View File
@@ -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
+14 -9
View File
@@ -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<PackageManager>,
#[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(&not_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()?;
+16 -14
View File
@@ -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<Packages> {
@@ -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<()> {
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");
_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)
(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)
}
+36 -1
View File
@@ -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<clap::builder::PossibleValue> {
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<PackageManager>) {
if let Some(manager) = manager {
self.manager = manager;
}
}
pub fn load_from(world_path: PathBuf) -> Result<World> {
let mut file = File::open(world_path)?;
let mut text = String::new();