use anyhow::{Result, anyhow};
use colored::Colorize;
use rigg_core::graph;
use rigg_core::store::{ProjectState, Store};
use crate::cli::DeleteArgs;
use crate::commands::remote::{Remote, ensure_any_connection};
use crate::commands::{
CommandError, GlobalContext, confirm_protected_env, interactive, load_workspace, resolve_env,
};
use crate::say;
pub async fn run(ctx: &GlobalContext, args: DeleteArgs) -> Result<()> {
if !args.remote {
return Err(anyhow!(CommandError::Usage(
"rigg delete removes remote resources and requires --remote; \
to remove local files just delete them (then `rigg push --prune`)"
.to_string()
)));
}
let ws = load_workspace()?;
let env = resolve_env(&ws, ctx)?;
let project = ws.project(&args.project)?;
let store = Store::new(project, &env.name);
let remote = Remote::for_project(&env, project);
ensure_any_connection(&remote, project)?;
let mut state = ProjectState::load(&ws, &env.name, &project.name);
let mut items = Vec::new();
for (r, _) in store.list()? {
if remote.supported_kinds().contains(&r.kind) && remote.get(&r).await?.is_some() {
let body = store.read(&r)?;
items.push((r, body));
}
}
if items.is_empty() {
say!(
ctx,
"Nothing to delete: no remote resources found for project '{}' in environment '{}'.",
project.name,
env.name
);
return Ok(());
}
say!(
ctx,
"{} the following resources of project '{}' from {} (env: {}{}):",
"DELETING".red().bold(),
project.name.bold(),
"Azure".bold(),
env.name,
if env.protected() {
format!(", {}", "protected".yellow())
} else {
String::new()
}
);
for line in remote.target_lines() {
say!(ctx, "{line}");
}
let order = graph::delete_order(&items)?;
for r in &order {
say!(ctx, " {} {}", "delete".red(), r);
}
if !confirm_protected_env(
ctx,
&env,
args.confirm_env.as_deref(),
"delete",
"delete",
serde_json::json!({"project": project.name, "env": env.name}),
)? {
say!(ctx, "Aborted.");
return Ok(());
}
if ctx.interactive() {
say!(ctx);
let answer = interactive::text("Type the project name to confirm:", ctx.no_color)?;
if answer.trim() != project.name {
say!(ctx, "aborted");
return Ok(());
}
} else if !ctx.yes {
return Err(anyhow!(CommandError::Usage(
"non-interactive delete requires --yes".to_string()
)));
}
for r in &order {
remote.delete(r).await?;
state.clear_baseline(r);
state.save(&ws, &env.name, &project.name)?;
say!(ctx, " {} deleted {}", "✓".green(), r);
}
say!(
ctx,
"{} local files kept; push the project to re-create everything",
"i".blue()
);
Ok(())
}