Skip to main content

launcher/headless/
updater.rs

1use std::process::ExitCode;
2use std::thread;
3
4use crate::updater::{UpdateStatus, Updater};
5
6pub fn run_self_update() -> ExitCode {
7    println!("Checking for updates...");
8    match Updater::do_check() {
9        Ok(Some(info)) => {
10            println!("Update found: {}", info.tag_name);
11            println!("Starting download...");
12
13            let (tx, rx) = std::sync::mpsc::channel();
14
15            // Spawn thread for printing progress
16            let progress_handle = thread::spawn(move || {
17                while let Ok(status) = rx.recv() {
18                    if let UpdateStatus::Downloading(p) = status {
19                        print!("\rDownloading: {:.1}%", p * 100.0);
20                        if let Err(e) = std::io::Write::flush(&mut std::io::stdout()) {
21                            eprintln!("Failed to flush stdout: {e}");
22                        }
23                    }
24                }
25                println!();
26            });
27
28            match Updater::do_download(&info, tx) {
29                Ok(path) => {
30                    // Wait for progress thread to finish printing
31                    if progress_handle.join().is_err() {
32                        eprintln!("Progress reporting thread panicked");
33                    }
34                    println!("Download complete! Ready to apply: {}", path.display());
35                    println!("Applying update...");
36                    if let Err(e) = Updater::apply_update(&path) {
37                        eprintln!("Failed to apply update: {e}");
38                        ExitCode::FAILURE
39                    } else {
40                        println!("Update applied successfully! (Binary replaced)");
41                        ExitCode::SUCCESS
42                    }
43                }
44                Err(e) => {
45                    if progress_handle.join().is_err() {
46                        eprintln!("Progress reporting thread panicked");
47                    }
48                    eprintln!("Error during download: {e}");
49                    ExitCode::FAILURE
50                }
51            }
52        }
53        Ok(None) => {
54            println!("No update available.");
55            ExitCode::SUCCESS
56        }
57        Err(e) => {
58            eprintln!("Error checking for updates: {e}");
59            ExitCode::FAILURE
60        }
61    }
62}