use clap::Args;
use comfy_table::Cell;
use crate::{
cli::commands::release::{format, OutputFormat},
kubernetes::{KubeRsClient, KubernetesReleaseStorage, ReleaseStorage},
NylError, Result,
};
#[derive(Args, Debug)]
pub struct HistoryArgs {
pub name: String,
#[arg(short, long)]
pub namespace: String,
#[arg(long, default_value = "10")]
pub max: usize,
#[arg(short, long, default_value = "table")]
pub output: OutputFormat,
#[arg(long)]
pub context: Option<String>,
}
pub async fn execute(args: HistoryArgs) -> Result<()> {
let config = KubeRsClient::load_kube_config(None, args.context.as_deref()).await?;
let client = kube::Client::try_from(config)?;
let storage = KubernetesReleaseStorage::new(client);
let revisions: Vec<u32> = storage.list_revisions(&args.name, &args.namespace).await?;
if revisions.is_empty() {
return Err(NylError::Config(format!(
"Release '{}' not found in namespace '{}'",
args.name, args.namespace
)));
}
let mut releases = Vec::new();
for revision in revisions.iter().rev().take(args.max) {
if let Some(release) = storage.get_release(&args.name, &args.namespace, *revision).await? {
releases.push(release);
}
}
match args.output {
OutputFormat::Table | OutputFormat::Wide => {
let mut table = format::create_table();
table.set_header(vec!["REVISION", "STATUS", "RENDERED", "APPLIED", "RESOURCES"]);
for release in releases {
table.add_row(vec![
Cell::new(release.revision),
format::color_status(&release.status),
Cell::new(format::format_timestamp(&release.rendered_at)),
Cell::new(
release
.applied_at
.map_or_else(|| "-".to_string(), |t| format::format_timestamp(&t)),
),
Cell::new(release.resource_keys.len()),
]);
}
println!("{}", table);
}
OutputFormat::Json => {
let json = serde_json::to_string_pretty(&releases)?;
println!("{}", json);
}
OutputFormat::Yaml => {
let yaml = serde_norway::to_string(&releases)?;
print!("{}", yaml);
}
}
Ok(())
}