(
status: &JobContext,
cancel: Receiver<()>,
config: UpdateConfig,
)
| 22 | } |
| 23 | |
| 24 | fn run_update( |
| 25 | status: &JobContext, |
| 26 | cancel: Receiver<()>, |
| 27 | config: UpdateConfig, |
| 28 | ) -> Result<Box<UpdateResult>> { |
| 29 | update_status(status, "Fetching latest release".to_string(), 0, 3, &cancel)?; |
| 30 | let updater = (config.build_updater)().context("Failed to create release updater")?; |
| 31 | let latest_release = updater.get_latest_release()?; |
| 32 | let asset = |
| 33 | latest_release.assets.iter().find(|a| a.name == config.bin_name).ok_or_else(|| { |
| 34 | anyhow::Error::msg(format!("No release asset for {}", config.bin_name)) |
| 35 | })?; |
| 36 | |
| 37 | update_status(status, "Downloading release".to_string(), 1, 3, &cancel)?; |
| 38 | let tmp_dir = tempfile::Builder::new().prefix("update").tempdir_in(current_dir()?)?; |
| 39 | let tmp_path = tmp_dir.path().join(&asset.name); |
| 40 | let tmp_file = File::create(&tmp_path)?; |
| 41 | self_update::Download::from_url(&asset.download_url) |
| 42 | .set_header(reqwest::header::ACCEPT, "application/octet-stream".parse()?) |
| 43 | .download_to(tmp_file)?; |
| 44 | |
| 45 | update_status(status, "Extracting release".to_string(), 2, 3, &cancel)?; |
| 46 | let tmp_file = tmp_dir.path().join("replacement_tmp"); |
| 47 | let target_file = current_exe()?; |
| 48 | self_update::Move::from_source(&tmp_path) |
| 49 | .replace_using_temp(&tmp_file) |
| 50 | .to_dest(&target_file)?; |
| 51 | #[cfg(unix)] |
| 52 | { |
| 53 | use std::{fs, os::unix::fs::PermissionsExt}; |
| 54 | fs::set_permissions(&target_file, fs::Permissions::from_mode(0o755))?; |
| 55 | } |
| 56 | tmp_dir.close()?; |
| 57 | |
| 58 | update_status(status, "Complete".to_string(), 3, 3, &cancel)?; |
| 59 | Ok(Box::from(UpdateResult { exe_path: target_file })) |
| 60 | } |
| 61 | |
| 62 | pub fn start_update(waker: Waker, config: UpdateConfig) -> JobState { |
| 63 | start_job(waker, "Update app", Job::Update, move |context, cancel| { |
no test coverage detected