use anyhow::Result;
use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
use crate::{
config::{Config, LockedConfig, LockedPackage, Package},
context::Context,
installer::install_package,
provider::{Github, Provider},
};
pub fn sync_package(
ctx: &Context,
pkg: &Package,
lpkg: Option<&LockedPackage>,
update: bool,
) -> Result<LockedPackage> {
match (&pkg.version, lpkg) {
(Some(version), Some(lpkg)) if version == &lpkg.version => {
ctx.log_status("Checked", format!("{}@{}", pkg.name, lpkg.version));
Ok(lpkg.clone())
}
(None, Some(lpkg)) if !update => {
ctx.log_status("Checked", format!("{}@{}", pkg.name, lpkg.version));
Ok(lpkg.clone())
}
_ => {
let provider = Github::new(ctx.clone())?;
let new_lpkg = provider.lock(pkg)?;
provider.download(&new_lpkg)?;
install_package(ctx, &new_lpkg)?;
match lpkg {
Some(old_lpkg) if old_lpkg != &new_lpkg => {
ctx.log_status(
"Updated",
format!("{}@{} => {}", pkg.name, old_lpkg.version, new_lpkg.version),
);
}
_ => {
ctx.log_status("Checked", format!("{}@{}", pkg.name, new_lpkg.version));
}
};
Ok(new_lpkg)
}
}
}
pub fn restore_package(ctx: &Context, lpkg: &LockedPackage) -> Result<()> {
let provider = Github::new(ctx.clone())?;
provider.download(lpkg)?;
install_package(ctx, lpkg)?;
ctx.log_status("Checked", format!("{}@{}", lpkg.name, lpkg.version));
Ok(())
}
pub fn sync_packages(
ctx: &Context,
cfg: &Config,
lcfg: &mut LockedConfig,
update: bool,
) -> Result<()> {
let new_lpkgs: Vec<_> = cfg
.pkgs
.par_iter()
.map(|(name, pkg)| {
let old_lpkg = lcfg.pkgs.get(name);
sync_package(ctx, pkg, old_lpkg, update)
})
.collect::<Result<_>>()?;
lcfg.pkgs = new_lpkgs
.into_iter()
.map(|lpkg| (lpkg.name.clone(), lpkg))
.collect();
Ok(())
}
pub fn restore_packages(lcfg: LockedConfig) -> Result<()> {
lcfg.pkgs.into_par_iter().for_each(|(_, pkg)| {
restore_package(&lcfg.ctx, &pkg).unwrap();
});
Ok(())
}