use crate::{BoxError, StandardOptions, SysexitsError::*};
use asimov_installer::InstallOptions;
use asimov_module::ModuleName;
use color_print::cprintln;
pub async fn upgrade(
module_names: Vec<ModuleName>,
version: Option<String>,
model_size: Option<String>,
flags: &StandardOptions,
) -> Result<(), BoxError> {
let registry = asimov_registry::Registry::default();
let installer = asimov_installer::Installer::default();
let module_names = if !module_names.is_empty() {
module_names.to_vec()
} else {
registry
.installed_modules()
.await
.map_err(|e| {
tracing::error!("failed to read installed modules: {e}");
EX_UNAVAILABLE
})?
.into_iter()
.map(|manifest| ModuleName::try_from(manifest.manifest.name))
.collect::<Result<Vec<_>, _>>()?
};
let install_options = InstallOptions::builder()
.maybe_version(version.clone())
.maybe_model_size(model_size.clone())
.build();
for module_name in module_names {
let current = registry.module_version(&module_name).await.map_err(|_| {
tracing::error!("failed to read installed version of `{module_name}`");
EX_UNAVAILABLE
})?;
let target_version = if let Some(ref want) = version {
want.clone()
} else {
installer
.fetch_latest_release(&module_name)
.await
.map_err(|e| {
tracing::error!(
"unable to find latest release for module `{module_name}`: {e}"
);
EX_UNAVAILABLE
})?
};
if current.is_some_and(|current| current == target_version) {
if flags.verbose > 0 {
let vers_txt = if version.is_some() {
"version"
} else {
"latest version"
};
cprintln!(
"<s,g>✓</> Module <s>{module_name}</> already has {vers_txt} <s>{target_version}</> installed."
);
}
continue;
}
if flags.verbose > 1 {
cprintln!("<s,c>»</> Upgrading module <s>{module_name}</>...");
}
installer
.upgrade_module(&module_name, &install_options)
.await
.map_err(|e| {
tracing::error!("module upgrade failed for `{module_name}`: {e}");
EX_UNAVAILABLE
})?;
if flags.verbose > 0 {
cprintln!(
"<s,g>✓</> Upgraded module <s>{module_name}</> to version <s>{target_version}</>."
);
}
}
Ok(())
}