mirror of
				https://github.com/TeFiLeDo/tree-owners.git
				synced 2025-11-04 05:51:19 +01:00 
			
		
		
		
	continue data gathering past individual failures
This commit is contained in:
		
							parent
							
								
									02166a07ef
								
							
						
					
					
						commit
						5ad2ece4e4
					
				
							
								
								
									
										72
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								src/main.rs
									
									
									
									
									
								
							@ -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;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
        for child in children {
 | 
			
		||||
            match child {
 | 
			
		||||
                Ok(child) => fs_entry(&child.path(), summary),
 | 
			
		||||
                Err(e) => {
 | 
			
		||||
                    print_err(e, format!("invalid child for {display}"));
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn print_root_err(message: String) {
 | 
			
		||||
    eprintln!("{:#}", anyhow!("{message}"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn print_err(err: impl Into<Error>, message: String) {
 | 
			
		||||
    eprintln!("{:#}", err.into().context(message));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user