0
0
Fork 0

continue data gathering past individual failures

This commit is contained in:
Adrian Wannenmacher 2023-09-24 14:41:57 +02:00
parent 02166a07ef
commit 5ad2ece4e4
Signed by: tfld
GPG Key ID: 19D986ECB1E492D5
1 changed files with 42 additions and 30 deletions

View File

@ -1,6 +1,6 @@
use std::{fs::read_dir, os::linux::fs::MetadataExt, path::Path}; use std::{fs::read_dir, os::linux::fs::MetadataExt, path::Path};
use anyhow::{anyhow, ensure, Context, Result}; use anyhow::{anyhow, ensure, Context, Error, Result};
use clap::Parser; use clap::Parser;
use crate::{cli::Args, summary::Summary}; use crate::{cli::Args, summary::Summary};
@ -14,25 +14,15 @@ fn main() -> Result<()> {
let mut summary = Summary::default(); let mut summary = Summary::default();
for root in args.roots { for root in args.roots {
fs_entry(&root, &mut summary)?; fs_entry(&root, &mut summary);
} }
if !args.raw { if !args.raw {
let (uf, gf) = summary.lookup_names(); let (uf, gf) = summary.lookup_names();
uf.into_iter()
for (uid, e) in uf { .for_each(|(uid, e)| print_err(e, format!("failed to get name for user {uid}")));
eprintln!( gf.into_iter()
"{:#}", .for_each(|(gid, e)| print_err(e, format!("failed to get name for group {gid}")));
anyhow!(e).context(format!("failed to get name for user {uid}"))
);
}
for (gid, e) in gf {
eprintln!(
"{:#}",
anyhow!(e).context(format!("failed to get name for group {gid}"))
);
}
} }
let output = match args.json { let output = match args.json {
false => summary.to_string(), false => summary.to_string(),
@ -44,26 +34,48 @@ fn main() -> Result<()> {
} }
/// Perform gid & uid gathering for a file, or a directory and its children. /// Perform gid & uid gathering for a file, or a directory and its children.
fn fs_entry(entry: &Path, summary: &mut Summary) -> Result<()> { fn fs_entry(entry: &Path, summary: &mut Summary) {
let display = entry.display(); let display = entry.display();
ensure!( if !entry.exists() && !entry.is_symlink() {
entry.is_symlink() || entry.exists(), print_root_err(format!("{display} doesn't exist"));
format!("{} doesn't exist", display) }
);
let meta = match entry.symlink_metadata() {
Ok(meta) => meta,
Err(e) => {
print_err(e, format!("failed to get metadata for {display}"));
return;
}
};
let meta = entry
.symlink_metadata()
.context(format!("failed to get metadata for {}", display))?;
summary.add_user(meta.st_uid()); summary.add_user(meta.st_uid());
summary.add_group(meta.st_gid()); summary.add_group(meta.st_gid());
if entry.is_dir() { if entry.is_dir() {
let children = read_dir(entry).context(format!("failed to read dir {}", display))?; let children = match read_dir(entry) {
for e in children { Ok(children) => children,
let e = e.context(format!("invalid child for {}", display))?; Err(e) => {
fs_entry(&e.path(), summary)?; print_err(e, format!("failed to read dir {display}"));
return;
}
};
for child in children {
match child {
Ok(child) => fs_entry(&child.path(), summary),
Err(e) => {
print_err(e, format!("invalid child for {display}"));
return;
}
}
} }
} }
}
Ok(())
fn print_root_err(message: String) {
eprintln!("{:#}", anyhow!("{message}"));
}
fn print_err(err: impl Into<Error>, message: String) {
eprintln!("{:#}", err.into().context(message));
} }