diff --git a/TODO.md b/TODO.md index e65c3a7..413f0e6 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ # To Do - tutorial -* group file not found (e.g. group edit) * invalid group name (e.g. '.') * building on non-Arch diff --git a/crates/pacdef_core/src/core.rs b/crates/pacdef_core/src/core.rs index 9b04d19..1fe0097 100644 --- a/crates/pacdef_core/src/core.rs +++ b/crates/pacdef_core/src/core.rs @@ -3,7 +3,7 @@ use std::fs::{remove_file, File}; use std::os::unix::fs::symlink; use std::path::Path; -use anyhow::{anyhow, bail, ensure, Context, Result}; +use anyhow::{bail, ensure, Context, Result}; use clap::ArgMatches; use const_format::formatcp; @@ -206,20 +206,40 @@ impl Pacdef { } fn show_group_content(&self, groups: &ArgMatches) -> Result<()> { - let mut iter = groups + let args: Vec<_> = groups .get_many::("groups") .context("getting groups from args")? - .peekable(); + .collect(); - let show_more_than_one_group = iter.size_hint().0 > 1; + let mut errors = vec![]; + let mut groups = vec![]; - while let Some(arg_group) = iter.next() { - let group = self - .groups - .iter() - .find(|g| g.name == *arg_group) - .ok_or_else(|| anyhow!(crate::Error::GroupFileNotFound(g.name)))?; + // make sure all args exist before doing anything + for arg_group in &args { + let group = self.groups.iter().find(|g| g.name == **arg_group); + let group = match group { + Some(g) => g, + None => { + errors.push((*arg_group).clone()); + continue; + } + }; + + groups.push(group); + } + + // return an error if any arg was not found + ensure!( + errors.is_empty(), + crate::Error::MultipleGroupsNotFound(errors) + ); + + let show_more_than_one_group = args.len() > 1; + + let mut iter = groups.into_iter().peekable(); + + while let Some(group) = iter.next() { if show_more_than_one_group { let name = &group.name; println!("{name}"); diff --git a/crates/pacdef_core/src/errors.rs b/crates/pacdef_core/src/errors.rs index 510903c..2207c11 100644 --- a/crates/pacdef_core/src/errors.rs +++ b/crates/pacdef_core/src/errors.rs @@ -1,5 +1,5 @@ use std::error::Error as ErrorTrait; -use std::fmt::Display; +use std::fmt::{Display, Write}; use std::path::PathBuf; /// Error types for pacdef. @@ -16,6 +16,8 @@ pub enum Error { GroupAlreadyExists(PathBuf), /// Invalid group name ('.' or '..') InvalidGroupName(String), + /// Multiple groups not found. + MultipleGroupsNotFound(Vec), } impl Display for Error { @@ -31,6 +33,17 @@ impl Display for Error { Self::InvalidGroupName(name) => { f.write_str(&format!("group name '{name}' is not valid")) } + Self::MultipleGroupsNotFound(vec) => { + f.write_str("could not find the following groups:\n")?; + let mut iter = vec.iter().peekable(); + while let Some(group) = iter.next() { + f.write_str(&format!(" {group}"))?; + if iter.peek().is_some() { + f.write_char('\n')?; + } + } + Ok(()) + } } } }