use std::collections::BTreeMap;
use eyre::{eyre, Result};
use crate::package::Package;
use crate::track::load_tracks;
use crate::pls_command::PlsCommand;
use crate::run_command::run_command;
use crate::vendor_data::VendorData;
use crate::vendors::Vendor;
pub fn reinstall_all(
vendor: Option<Vendor>,
yes: bool,
su: bool,
dry_run: bool,
pager: &Option<String>,
pls_command: &PlsCommand,
) -> Result<i32> {
let tracks = tracks_by_vendor()?;
let mut status = 0;
for (v, packages) in tracks {
if let Some(vendor) = vendor {
if vendor != v {
continue;
}
}
let vendor_data: VendorData = v.try_into()?;
let command = PlsCommand::ReinstallAll.format(
vendor_data,
&packages,
yes,
pager,
);
if command.is_empty() {
continue;
}
if dry_run {
println!("{}", command);
continue;
}
let mut current = run_command(&command, su, &pager, pls_command)?;
if current != 0 {
current = rerun_reinstall_all_on_failure(vendor_data, yes, &pager, su, pls_command);
}
if current != 0 {
status = current;
}
}
Ok(status)
}
fn tracks_by_vendor() -> Result<BTreeMap<Vendor, Vec<Package>>> {
let mut res = BTreeMap::new();
let tracks = load_tracks()?;
if tracks.is_empty() {
return Err(eyre!("no known installed packages"));
}
for track in tracks {
res
.entry(track.vendor)
.or_insert(vec![])
.push(track.clone());
}
for (_, packages) in res.iter_mut() {
packages.sort();
}
Ok(res)
}
fn rerun_reinstall_all_on_failure(
vendor_data: VendorData,
yes: bool,
pager: &Option<String>,
su: bool,
pls_command: &PlsCommand,
) -> i32 {
let tracks = load_tracks().unwrap_or_default();
let mut response = 0;
for track in tracks {
let command = PlsCommand::Install.format(vendor_data, &vec![track], yes, pager);
match run_command(&command, su, pager, pls_command) {
Ok(status) => {
if status != 0 {
response = status;
}
},
Err(err) => {
eprintln!("error running command: {}", err);
response = 1;
}
}
}
response
}