diff --git a/src/main.rs b/src/main.rs index 0397493..70efa7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ mod world; use error::*; use crate::{ - package_manager::get_system_state, + package_manager::{get_system_state, get_unneeded_packages, remove_packages}, world::{World, get_world_location}, }; @@ -40,7 +40,7 @@ compile_error!("'yay' and 'paru' are mutually exclusive and cannot be enabled to #[cfg(not(target_os = "linux"))] compile_error!("Only (Arch) linux is supported!"); -const PRIVLAGE_ESCELATE_COMMAND: &str = "sudo"; +pub const PRIVLAGE_ESCELATE_COMMAND: &str = "sudo"; #[derive(Parser)] struct Args { @@ -233,7 +233,27 @@ fn main() -> Result<()> { print!("{}", s); } } - Commands::Pure { all } => todo!(), + Commands::Pure { all } => { + let world = World::load_from(world_path)?; + let state = get_system_state()?; + + let aditional = { + let mut x = state.exclude(world.get_packages()); + x.ignore = world.get_packages().ignore.clone(); + x.official.extend(get_unneeded_packages()?); + x.exclude_ignored(); + x.get_package_list() + }; + + if aditional.is_empty() { + if !args.quiet { + println!("No packages to remove."); + } + return Ok(()); + } + + remove_packages(&aditional, all)?; + } } Ok(()) } diff --git a/src/package_manager.rs b/src/package_manager.rs index 72104ba..ba334c1 100644 --- a/src/package_manager.rs +++ b/src/package_manager.rs @@ -1,4 +1,4 @@ -use crate::{error::Result, world::Packages}; +use crate::{PRIVLAGE_ESCELATE_COMMAND, error::Result, world::Packages}; use std::process::{Command, Stdio}; pub fn get_system_state() -> Result { @@ -28,3 +28,37 @@ pub fn get_system_state() -> Result { ignore: Vec::new(), }) } + +pub fn get_unneeded_packages() -> Result> { + let command = Command::new("pacman") + .arg("-Qqdt") + .stdout(Stdio::piped()) + .output()?; + + let packages: Vec = String::from_utf8(command.stdout)? + .split_whitespace() + .map(|x| x.to_owned()) + .collect(); + + Ok(packages) +} + +pub fn remove_packages(packages: &[String], all: bool) -> Result<()> { + let mut command = Command::new(PRIVLAGE_ESCELATE_COMMAND); + command.arg("pacman"); + + if all { + command.arg("-Rns"); + } else { + command.arg("-Rs"); + } + + command + .args(packages) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status()?; + + Ok(()) +} diff --git a/src/world.rs b/src/world.rs index 70644ae..e7a3ef2 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,7 +1,5 @@ use std::env; -use std::error::Error; -use std::fs::OpenOptions; -use std::io::{Read, Write}; +use std::io::Read; use std::{fs::File, path::PathBuf}; use serde::{Deserialize, Serialize}; @@ -36,9 +34,7 @@ impl Packages { ignore: Vec::new(), } } -} -impl Packages { pub fn exclude(&self, other: &Self) -> Self { let official = self .official @@ -64,6 +60,13 @@ impl Packages { self.official.retain(|x| !self.ignore.contains(x)); self.foreign.retain(|x| !self.ignore.contains(x)); } + + pub fn get_package_list(&self) -> Vec { + let mut packages_list = self.official.clone(); + packages_list.extend(self.foreign.clone()); + + packages_list + } } impl World {