Skip to main content

pacenotes_installer\runlog/
log_files.rs

1/// Runs kept per game folder: enough that a re-run or two before asking for
2/// help cannot prune the run that failed.
3pub const KEEP_LOGS: usize = 5;
4
5/// `<game dir>\.pacenotes\logs`, beside the ledger, so one folder holds
6/// everything this installer knows about one game.
7pub fn log_dir(game_dir: &std::path::Path) -> std::path::PathBuf {
8    game_dir.join(crate::ledger::STATE_DIR).join("logs")
9}
10
11/// One file per run, named by its `utc_time::file_stamp`, so reopening the
12/// installer to read a run cannot erase it.
13pub fn log_path(game_dir: &std::path::Path, stamp: &str) -> std::path::PathBuf {
14    log_dir(game_dir).join(format!("install-{stamp}.log"))
15}
16
17/// Deletes all but the newest `keep` run logs in `dir`, by name rather than
18/// modification time, so a log restored from a backup cannot pass for the
19/// newest; failures are ignored, since housekeeping must never stop an install.
20pub fn prune(dir: &std::path::Path, keep: usize) {
21    let Ok(entries) = std::fs::read_dir(dir) else {
22        return;
23    };
24    let mut logs: Vec<std::path::PathBuf> = entries
25        .flatten()
26        .map(|entry| entry.path())
27        .filter(|path| {
28            path.file_name()
29                .and_then(|name| name.to_str())
30                .is_some_and(|name| name.starts_with("install-") && name.ends_with(".log"))
31        })
32        .collect();
33    if logs.len() <= keep {
34        return;
35    }
36    logs.sort();
37    for old in &logs[..logs.len() - keep] {
38        let _ = std::fs::remove_file(old);
39    }
40}