0
0
mirror of https://github.com/TeFiLeDo/tree-owners.git synced 2024-11-21 11:56:17 +01:00

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

View File

@ -1,6 +1,6 @@
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 crate::{cli::Args, summary::Summary};
@ -14,25 +14,15 @@ fn main() -> Result<()> {
let mut summary = Summary::default();
for root in args.roots {
fs_entry(&root, &mut summary)?;
fs_entry(&root, &mut summary);
}
if !args.raw {
let (uf, gf) = summary.lookup_names();
for (uid, e) in uf {
eprintln!(
"{:#}",
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}"))
);
}
uf.into_iter()
.for_each(|(uid, e)| print_err(e, format!("failed to get name for user {uid}")));
gf.into_iter()
.for_each(|(gid, e)| print_err(e, format!("failed to get name for group {gid}")));
}
let output = match args.json {
false => summary.to_string(),
@ -44,26 +34,48 @@ fn main() -> Result<()> {
}
/// 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();
ensure!(
entry.is_symlink() || entry.exists(),
format!("{} doesn't exist", display)
);
if !entry.exists() && !entry.is_symlink() {
print_root_err(format!("{display} doesn't exist"));
}
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_group(meta.st_gid());
if entry.is_dir() {
let children = read_dir(entry).context(format!("failed to read dir {}", display))?;
for e in children {
let e = e.context(format!("invalid child for {}", display))?;
fs_entry(&e.path(), summary)?;
let children = match read_dir(entry) {
Ok(children) => children,
Err(e) => {
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));
}