From 99bdced2a1edd508e0e02d68e2df72fca7b53892 Mon Sep 17 00:00:00 2001 From: steven-omaha <35634100+steven-omaha@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:45:37 +0100 Subject: [PATCH] add error handling per backend --- src/backend/mod.rs | 22 ++++++++++++++-------- src/backend/pacman.rs | 13 +++++++++---- src/backend/rust.rs | 26 ++++++++++++++++---------- src/core.rs | 16 ++++++++++------ 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 7aec621..7e62f79 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -7,6 +7,8 @@ use std::collections::HashSet; use std::os::unix::process::CommandExt; use std::process::Command; +use anyhow::{Context, Result}; + use crate::{Group, Package}; pub(crate) use todo_per_backend::ToDoPerBackend; @@ -58,10 +60,10 @@ pub(crate) trait Backend { fn load(&mut self, groups: &HashSet); /// Get all packages that are installed in the system. - fn get_all_installed_packages(&self) -> HashSet; + fn get_all_installed_packages(&self) -> Result>; /// Get all packages that were installed in the system explicitly. - fn get_explicitly_installed_packages(&self) -> HashSet; + fn get_explicitly_installed_packages(&self) -> Result>; /// Install the specified packages. fn install_packages(&self, packages: &[Package]) { @@ -99,21 +101,25 @@ pub(crate) trait Backend { .collect() } - fn get_missing_packages_sorted(&self) -> Vec { - let installed = self.get_all_installed_packages(); + fn get_missing_packages_sorted(&self) -> Result> { + let installed = self + .get_all_installed_packages() + .context("could not get installed packages")?; let managed = self.get_managed_packages(); let mut diff: Vec<_> = managed.difference(&installed).cloned().collect(); diff.sort_unstable(); - diff + Ok(diff) } fn add_packages(&mut self, packages: HashSet); - fn get_unmanaged_packages_sorted(&self) -> Vec { - let installed = self.get_explicitly_installed_packages(); + fn get_unmanaged_packages_sorted(&self) -> Result> { + let installed = self + .get_explicitly_installed_packages() + .context("could not get explicitly installed packages")?; let required = self.get_managed_packages(); let mut diff: Vec<_> = installed.difference(required).cloned().collect(); diff.sort_unstable(); - diff + Ok(diff) } } diff --git a/src/backend/pacman.rs b/src/backend/pacman.rs index 9518c52..519c680 100644 --- a/src/backend/pacman.rs +++ b/src/backend/pacman.rs @@ -2,6 +2,7 @@ use std::collections::HashSet; use alpm::Alpm; use alpm::PackageReason::Explicit; +use anyhow::Result; use super::{Backend, Switches, Text}; use crate::{impl_backend_constants, Group, Package}; @@ -18,12 +19,16 @@ const SWITCHES_REMOVE: Switches = &["-Rsn"]; impl Backend for Pacman { impl_backend_constants!(); - fn get_all_installed_packages(&self) -> HashSet { - convert_to_pacdef_packages(get_all_installed_packages_from_alpm()) + fn get_all_installed_packages(&self) -> Result> { + Ok(convert_to_pacdef_packages( + get_all_installed_packages_from_alpm(), + )) } - fn get_explicitly_installed_packages(&self) -> HashSet { - convert_to_pacdef_packages(get_explicitly_installed_packages_from_alpm()) + fn get_explicitly_installed_packages(&self) -> Result> { + Ok(convert_to_pacdef_packages( + get_explicitly_installed_packages_from_alpm(), + )) } } diff --git a/src/backend/rust.rs b/src/backend/rust.rs index 752f4a5..5665256 100644 --- a/src/backend/rust.rs +++ b/src/backend/rust.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::fs::read_to_string; use std::path::PathBuf; -use anyhow::Result; +use anyhow::{Context, Result}; use serde_json::Value; use super::{Backend, Switches, Text}; @@ -20,28 +20,34 @@ const SWITCHES_REMOVE: Switches = &["uninstall"]; impl Backend for Rust { impl_backend_constants!(); - fn get_all_installed_packages(&self) -> HashSet { + fn get_all_installed_packages(&self) -> Result> { let file = get_crates_file().unwrap(); let content = read_to_string(file).unwrap(); let json: Value = serde_json::from_str(&content).unwrap(); extract_packages(json) } - fn get_explicitly_installed_packages(&self) -> HashSet { + fn get_explicitly_installed_packages(&self) -> Result> { self.get_all_installed_packages() } } -fn extract_packages(json: Value) -> HashSet { - json.get("installs") - .unwrap() +fn extract_packages(json: Value) -> Result> { + let result: HashSet<_> = json + .get("installs") + .context("get 'installs' field from json")? .as_object() - .unwrap() + .context("getting object")? .into_iter() .map(|(name, _)| name) - .map(|name| name.split_whitespace().next().unwrap()) - .filter_map(Package::try_from) - .collect() + .map(|name| { + name.split_whitespace() + .next() + .expect("identifier is whitespace-delimited") + }) + .map(|name| Package::try_from(name).expect("name is valid")) + .collect(); + Ok(result) } impl Rust { diff --git a/src/core.rs b/src/core.rs index 4494200..73e092f 100644 --- a/src/core.rs +++ b/src/core.rs @@ -39,11 +39,13 @@ impl Pacdef { fn get_missing_packages(&self) -> ToDoPerBackend { let mut to_install = ToDoPerBackend::new(); - for mut b in Backends::iter() { - b.load(&self.groups); + for mut backend in Backends::iter() { + backend.load(&self.groups); - let diff = b.get_missing_packages_sorted(); - to_install.push((b, diff)); + match backend.get_missing_packages_sorted() { + Ok(diff) => to_install.push((backend, diff)), + Err(e) => println!("WARNING: skipping backend '{}': {e}", backend.get_section()), + }; } to_install @@ -119,8 +121,10 @@ impl Pacdef { for mut backend in Backends::iter() { backend.load(&self.groups); - let unmanaged = backend.get_unmanaged_packages_sorted(); - result.push((backend, unmanaged)); + match backend.get_unmanaged_packages_sorted() { + Ok(unmanaged) => result.push((backend, unmanaged)), + Err(e) => println!("WARNING: skipping backend '{}': {e}", backend.get_section()), + }; } result }