please_install/
reinstall.rs1use std::collections::BTreeMap;
2
3use eyre::{eyre, Result};
4
5use crate::package::Package;
6use crate::track::load_tracks;
7use crate::pls_command::PlsCommand;
8use crate::run_command::run_command;
9use crate::vendor_data::VendorData;
10use crate::vendors::Vendor;
11
12pub fn reinstall_all(
13 vendor: Option<Vendor>,
14 yes: bool,
15 su: bool,
16 dry_run: bool,
17 pager: &Option<String>,
18 pls_command: PlsCommand,
19) -> Result<i32> {
20 let tracks = tracks_by_vendor()?;
21 let mut status = 0;
22
23 for (v, packages) in tracks {
24 if let Some(vendor) = vendor {
25 if vendor != v {
26 continue;
27 }
28 }
29 let vendor_data: VendorData = v.try_into()?;
30 let command = PlsCommand::ReinstallAll.format(
31 vendor_data,
32 &packages,
33 yes,
34 pager,
35 );
36 if command.is_empty() {
37 continue;
38 }
39
40 if dry_run {
41 println!("{}", command);
42 continue;
43 }
44
45 let mut current = run_command(&command, su, &pager, pls_command)?;
46 if current != 0 {
47 current = rerun_reinstall_all_on_failure(vendor_data, yes, &pager, su, pls_command);
48 }
49
50 if current != 0 {
51 status = current;
52 }
53 }
54
55 Ok(status)
56}
57
58fn tracks_by_vendor() -> Result<BTreeMap<Vendor, Vec<Package>>> {
59 let mut res = BTreeMap::new();
60 let tracks = load_tracks()?;
61 if tracks.is_empty() {
62 return Err(eyre!("no known installed packages"));
63 }
64 for track in tracks {
65 res
66 .entry(track.vendor)
67 .or_insert(vec![])
68 .push(track.clone());
69 }
70 for (_, packages) in res.iter_mut() {
71 packages.sort();
72 }
73 Ok(res)
74}
75
76fn rerun_reinstall_all_on_failure(
77 vendor_data: VendorData,
78 yes: bool,
79 pager: &Option<String>,
80 su: bool,
81 pls_command: PlsCommand,
82) -> i32 {
83 let tracks = load_tracks().unwrap_or_default();
84 let mut response = 0;
85 for track in tracks {
86 let command = PlsCommand::Install.format(vendor_data, &vec![track], yes, pager);
87 match run_command(&command, su, pager, pls_command) {
88 Ok(status) => {
89 if status != 0 {
90 response = status;
91 }
92 },
93 Err(err) => {
94 eprintln!("error running command: {}", err);
95 response = 1;
96 }
97 }
98 }
99 response
100}