use anyhow::Result;
use crate::cli::{
Cli, MaintenanceCommands,
commands::{cmd_gc, cmd_index, cmd_monitor},
should_output_json, worktree_status_options,
};
pub fn cmd_maintenance(cli: &Cli, command: MaintenanceCommands) -> Result<()> {
let repo = cli.open_repo()?;
let options = worktree_status_options(Some(repo.config()));
match command {
MaintenanceCommands::Inspect => {
let report = repo.inspect_performance_with_options(&options)?;
if should_output_json(cli, Some(repo.config())) {
println!("{}", serde_json::to_string(&report)?);
} else {
println!(
"Commit graph: {} (nodes: {}, bloom-covered: {})",
presence(report.commit_graph.present),
report.commit_graph.node_count,
report.commit_graph.bloom_covered_nodes
);
println!(
"Worktree index: {} (files: {}, directories: {}, untracked directories: {})",
presence(report.worktree_index.present),
report.worktree_index.file_entries,
report.worktree_index.directory_entries,
report.worktree_index.untracked_directory_entries
);
println!(
"Change monitor: {} / {}",
report.change_monitor.backend, report.change_monitor.status
);
println!(
"Refs: {} threads, {} markers, {} remotes, {} remote threads",
report.ref_counts.threads,
report.ref_counts.markers,
report.ref_counts.remotes,
report.ref_counts.remote_threads
);
println!(
"Ref summary index: {} (valid: {}, threads: {}, markers: {}, remotes: {}, remote threads: {})",
presence(report.ref_summary_index.present),
yes_no(report.ref_summary_index.valid),
report.ref_summary_index.threads,
report.ref_summary_index.markers,
report.ref_summary_index.remotes,
report.ref_summary_index.remote_threads
);
println!(
"Packs: {} pack files, {} indexes",
report.pack_files.pack_count, report.pack_files.index_count
);
println!(
"Partial fetch: {} missing blobs",
report.partial_fetch.missing_blob_count
);
println!(
"Pull planner cache: {} (manifests: {}, planner entries: {})",
report.pull_planner_cache.status,
report.pull_planner_cache.manifest_count,
report.pull_planner_cache.planner_entry_count
);
}
}
MaintenanceCommands::Run => {
let run = repo.run_maintenance_with_options(&options)?;
if should_output_json(cli, Some(repo.config())) {
println!("{}", serde_json::to_string(&run)?);
} else {
println!("Rebuilt commit graph: {}", yes_no(run.rebuilt_commit_graph));
println!(
"Rebuilt ref summary index: {}",
yes_no(run.rebuilt_ref_summary_index)
);
println!(
"Rebuilt worktree index: {}",
yes_no(run.rebuilt_worktree_index)
);
println!(
"Refreshed change monitor: {}",
yes_no(run.refreshed_change_monitor)
);
println!(
"Rebuilt pull planner cache: {}",
yes_no(run.rebuilt_pull_planner_cache)
);
println!(
"Pruned pull planner entries: {}",
run.pruned_pull_planner_entries
);
println!(
"Commit graph now has {} nodes and {} Bloom-covered nodes",
run.report.commit_graph.node_count, run.report.commit_graph.bloom_covered_nodes
);
println!(
"Ref summary index now covers {} threads, {} markers, {} remotes, and {} remote threads",
run.report.ref_summary_index.threads,
run.report.ref_summary_index.markers,
run.report.ref_summary_index.remotes,
run.report.ref_summary_index.remote_threads
);
println!(
"Worktree index now has {} files cached",
run.report.worktree_index.file_entries
);
println!(
"Pull planner cache now has {} manifests and {} planner entries",
run.report.pull_planner_cache.manifest_count,
run.report.pull_planner_cache.planner_entry_count
);
}
}
MaintenanceCommands::Gc {
prune,
aggressive,
dry_run,
} => {
return cmd_gc(cli, prune, aggressive, dry_run);
}
MaintenanceCommands::Index { dump } => {
return cmd_index(cli, dump);
}
MaintenanceCommands::Monitor { paths, serve } => {
return cmd_monitor(cli, paths, serve);
}
}
Ok(())
}
fn presence(value: bool) -> &'static str {
if value { "present" } else { "absent" }
}
fn yes_no(value: bool) -> &'static str {
if value { "yes" } else { "no" }
}