use console::style;
use miette::IntoDiagnostic;
use sherpack_core::{LoadedPack, Values, parse_set_values};
use sherpack_kube::{
InstallOptions, KubeClient,
storage::{FileDriver, StorageConfig},
};
use std::path::Path;
use crate::error::Result;
#[allow(clippy::too_many_arguments)]
pub async fn run(
name: &str,
pack_path: &Path,
values_files: &[std::path::PathBuf],
set_values: &[String],
namespace: &str,
wait: bool,
timeout: Option<u64>,
atomic: bool,
create_namespace: bool,
dry_run: bool,
show_diff: bool,
skip_crds: bool,
) -> Result<()> {
let pack = LoadedPack::load(pack_path).into_diagnostic()?;
println!(
"{} Installing pack {} version {}",
style("→").blue().bold(),
style(&pack.pack.metadata.name).cyan(),
style(&pack.pack.metadata.version).yellow()
);
if pack.has_crds() {
let crd_files = pack.crd_files().into_diagnostic()?;
if skip_crds {
println!(
"{} Skipping {} CRD file(s) (--skip-crds)",
style("⚠").yellow(),
crd_files.len()
);
} else {
println!(
"{} Found {} CRD file(s) in crds/ directory",
style("→").blue(),
crd_files.len()
);
}
}
let mut values = Values::from_file(&pack.values_path).into_diagnostic()?;
if let Some(schema) = pack.load_schema().into_diagnostic()? {
let defaults = Values(schema.extract_defaults());
values = Values::with_schema_defaults(defaults, values);
}
for vf in values_files {
let overlay = Values::from_file(vf).into_diagnostic()?;
values.merge(&overlay);
}
if !set_values.is_empty() {
let set_values_map = parse_set_values(set_values).into_diagnostic()?;
values.merge(&set_values_map);
}
let storage_path = dirs::data_dir()
.unwrap_or_else(|| std::path::PathBuf::from("."))
.join("sherpack")
.join("releases");
let storage = FileDriver::new(storage_path, StorageConfig::default()).into_diagnostic()?;
let client = KubeClient::new(storage).await.into_diagnostic()?;
let mut options = InstallOptions::new(name, namespace);
options.wait = wait;
options.atomic = atomic;
options.create_namespace = create_namespace;
options.dry_run = dry_run;
options.show_diff = show_diff;
if let Some(t) = timeout {
options.timeout = Some(chrono::Duration::seconds(t as i64));
}
let release = client
.install(&pack, values, &options)
.await
.into_diagnostic()?;
if dry_run {
println!(
"{} Dry run - would install {} in namespace {}",
style("✓").green().bold(),
style(name).cyan(),
style(namespace).yellow()
);
} else {
println!(
"{} Successfully installed {} (revision {}) in namespace {}",
style("✓").green().bold(),
style(&release.name).cyan(),
style(release.version).yellow(),
style(&release.namespace).yellow()
);
}
if let Some(notes) = &release.notes {
println!("\n{}", style("NOTES:").bold());
println!("{}", notes);
}
Ok(())
}