use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::{Context, Result};
use klasp_core::AgentSurface;
use crate::cli::UninstallArgs;
use crate::cmd::install::{resolve_repo_root, resolve_selection, Selection, AGENT_ALL};
use crate::registry::SurfaceRegistry;
pub fn run(args: &UninstallArgs) -> ExitCode {
match try_run(args) {
Ok(exit) => exit,
Err(e) => {
eprintln!("klasp uninstall: {e:#}");
ExitCode::from(1)
}
}
}
fn try_run(args: &UninstallArgs) -> Result<ExitCode> {
let repo_root = resolve_repo_root(args.repo_root.as_deref())?;
let registry = SurfaceRegistry::default();
let selection = if args.agent.as_deref() == Some(AGENT_ALL) {
Selection::Surfaces(registry.iter().collect())
} else {
resolve_selection(args.agent.as_deref(), ®istry, &repo_root)?
};
let surfaces: Vec<&dyn AgentSurface> = match selection {
Selection::Empty { reason } => {
eprintln!("warning: {reason}; nothing to remove");
return Ok(ExitCode::SUCCESS);
}
Selection::Surfaces(s) => s,
};
for s in &surfaces {
let touched = s
.uninstall(&repo_root, args.dry_run)
.with_context(|| format!("uninstalling {}", s.agent_id()))?;
report(s.agent_id(), &touched, args.dry_run);
}
Ok(ExitCode::SUCCESS)
}
fn report(agent_id: &str, paths: &[PathBuf], dry_run: bool) {
if paths.is_empty() {
println!("{agent_id}: nothing to remove");
return;
}
let verb = if dry_run { "would touch" } else { "removed" };
println!("{agent_id}: {verb}");
for p in paths {
println!(" {}", p.display());
}
}