diskr-cli 1.0.0

Save your disk space, without fear of deleting the wrong thing.
Documentation
use anyhow::Result;
use serde::Serialize;
use std::path::PathBuf;
use std::process::Command;

#[derive(Debug, Clone, Serialize)]
pub struct LogSource {
    pub label: String,
    pub path: Option<PathBuf>,
    pub size_bytes: u64,
}

pub fn scan_logs() -> Vec<LogSource> {
    let mut out = Vec::new();

    if let Some(size) = journald_size() {
        out.push(LogSource { label: "journald".into(), path: Some(PathBuf::from("/var/log/journal")), size_bytes: size });
    }
    for p in ["/var/log/syslog", "/var/log/syslog.1", "/var/log/kern.log"] {
        if let Ok(meta) = std::fs::metadata(p) {
            out.push(LogSource { label: p.to_string(), path: Some(PathBuf::from(p)), size_bytes: meta.len() });
        }
    }
    if let Some(home) = dirs::home_dir() {
        let share = home.join(".local/share");
        if let Ok(entries) = std::fs::read_dir(&share) {
            for e in entries.flatten() {
                let p = e.path();
                if p.extension().and_then(|x| x.to_str()) == Some("log") {
                    if let Ok(meta) = e.metadata() {
                        out.push(LogSource { label: p.display().to_string(), path: Some(p), size_bytes: meta.len() });
                    }
                }
            }
        }
    }
    out.sort_by(|a, b| b.size_bytes.cmp(&a.size_bytes));
    out
}

fn journald_size() -> Option<u64> {
    let out = Command::new("journalctl").arg("--disk-usage").output().ok()?;
    let text = String::from_utf8_lossy(&out.stdout);
    let mb = text.split_whitespace().find(|w| w.parse::<f64>().is_ok())?.parse::<f64>().ok()?;
    Some((mb * 1024.0 * 1024.0) as u64)
}

pub fn vacuum_journald(keep: &str) -> Result<()> {
    Command::new("journalctl").arg(format!("--vacuum-time={keep}")).status()?;
    Ok(())
}