#![allow(dead_code)] #[macro_use] extern crate pin_project; #[macro_use] extern crate lazy_static; #[cfg(feature="inspect")] use serde::{Serialize, Deserialize}; use color_eyre::{ eyre::{ self, eyre, WrapErr as _, }, Help as _, SectionExt as _, }; #[macro_use] mod ext; pub use ext::prelude::*; mod data; mod config; mod state; mod arg; mod work; #[cfg(feature="inspect")] mod serial; #[cfg(feature="defer-drop")] mod defer_drop; async fn normal(cfg: config::Config) -> eyre::Result<()> { let state = state::State::new(cfg .validate() .wrap_err(eyre!("Invalid config")) .with_suggestion(|| "Try running `--help`")?); let (graph, cfg) = tokio::select!{ x = work::work_on_all(state) => {x} _ = tokio::signal::ctrl_c() => { return Err(eyre!("Interrupt signalled, exiting")); } }; let cfg = cfg.make_global(); let graph = tokio::task::spawn_blocking(move || { cfg_println!(Verbose; cfg, "Computing hierarchy..."); let mut graph = graph.into_hierarchical(); cfg_println!(Verbose; cfg, "Computing sizes..."); graph.compute_recursive_sizes(); graph }).await.expect("Failed to compute hierarchy from graph"); #[cfg(debug_assertions)] cfg_eprintln!(Verbose; cfg, "{:?}", graph); cfg_println!(Quiet; cfg, "Max size file: {:?}", graph.path_max_size_for(data::FsKind::File)); cfg_println!(Quiet; cfg, "Max size dir: {:?}", graph.path_max_size_for(data::FsKind::Directory)); cfg_println!(Quiet; cfg, "Max size all: {:?}", graph.path_max_size()); #[cfg(feature="inspect")] match cfg.serialise_output.as_ref().map(|ser_out| { type BoxedWrite = Box; use futures::FutureExt; match ser_out { Some(output_file) => { use tokio::fs::OpenOptions; async move { let stream = OpenOptions::new() .write(true) .truncate(true) .create(true) .open(output_file).await .wrap_err(eyre!("Failed to open file for writing")) .with_section(|| format!("{:?}", output_file).header("File was"))?; Ok::(Box::new(stream)) }.boxed() }, None => async move { Ok::(Box::new(tokio::io::stdout())) }.boxed(), } }) { Some(stream_fut) => { let stream = stream_fut.await?; serial::write_async(stream, &graph).await .wrap_err(eyre!("Failed to serialise graph to stream"))?; }, _ => (), } Ok(()) } async fn parse_mode() -> eyre::Result<()> { match arg::parse_args().wrap_err(eyre!("Failed to parse args"))? { arg::Mode::Normal(cfg) => { normal(cfg).await }, arg::Mode::Help => arg::help(), } } #[tokio::main] async fn main() -> eyre::Result<()> { color_eyre::install()?; parse_mode().await .wrap_err(eyre!("Fatal error"))?; /* let max_size = graph.directories().map(|x| x.size()).max(); println!("Max size: {:?}", max_size);*/ //println!("{:?}", graph); Ok(()) }