From 6b4875b5029191444b25c097522b097566886855 Mon Sep 17 00:00:00 2001 From: "Calum H. (IMB11)" Date: Fri, 24 Jul 2026 16:38:18 +0100 Subject: [PATCH] fix: clean up updater temp folders --- apps/app/src/main.rs | 17 ++++++++++ packages/app-lib/src/lib.rs | 2 ++ packages/app-lib/src/updater.rs | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 packages/app-lib/src/updater.rs diff --git a/apps/app/src/main.rs b/apps/app/src/main.rs index 2d70869a6f..f59a7251f9 100644 --- a/apps/app/src/main.rs +++ b/apps/app/src/main.rs @@ -181,6 +181,23 @@ fn main() { .build(), ) .setup(|app| { + #[cfg(target_os = "windows")] + { + let app_name = app.package_info().name.clone(); + tauri::async_runtime::spawn(async move { + match theseus::cleanup_updater_temp_folders(&app_name).await + { + Ok(0) => {} + Ok(count) => tracing::info!( + "Cleaned up {count} updater temp folders" + ), + Err(error) => tracing::warn!( + "Failed to clean up updater temp folders: {error}" + ), + } + }); + } + #[cfg(target_os = "macos")] { let payload = macos::deep_link::get_or_init_payload(app); diff --git a/packages/app-lib/src/lib.rs b/packages/app-lib/src/lib.rs index 79b0e997a6..dd5c12533c 100644 --- a/packages/app-lib/src/lib.rs +++ b/packages/app-lib/src/lib.rs @@ -17,6 +17,7 @@ pub mod install; mod launcher; mod logger; mod state; +mod updater; pub use api::*; pub use error::*; @@ -26,6 +27,7 @@ pub use event::{ }; pub use logger::start_logger; pub use state::State; +pub use updater::cleanup_updater_temp_folders; pub use util::fetch::DownloadReason; pub fn launcher_user_agent() -> String { diff --git a/packages/app-lib/src/updater.rs b/packages/app-lib/src/updater.rs new file mode 100644 index 0000000000..39c831f122 --- /dev/null +++ b/packages/app-lib/src/updater.rs @@ -0,0 +1,58 @@ +use std::io; + +const UPDATER_SEPARATOR: &str = "-updater-"; +const UPDATER_RANDOM_SUFFIX_LENGTH: usize = 6; + +pub async fn cleanup_updater_temp_folders( + app_name: &str, +) -> io::Result { + let mut entries = tokio::fs::read_dir(std::env::temp_dir()).await?; + let mut removed = 0; + + while let Some(entry) = entries.next_entry().await? { + let file_name = entry.file_name(); + let Some(file_name) = file_name.to_str() else { + continue; + }; + + if !is_updater_temp_folder(app_name, file_name) + || !entry.file_type().await?.is_dir() + { + continue; + } + + let path = entry.path(); + match tokio::fs::remove_dir_all(&path).await { + Ok(()) => removed += 1, + Err(error) => { + tracing::warn!( + "Failed to clean up updater temp folder {}: {error}", + path.display() + ); + } + } + } + + Ok(removed) +} + +fn is_updater_temp_folder(app_name: &str, file_name: &str) -> bool { + let Some(name) = file_name + .strip_prefix(app_name) + .and_then(|name| name.strip_prefix('-')) + else { + return false; + }; + let Some((version, random_suffix)) = + name.rsplit_once(UPDATER_SEPARATOR) + else { + return false; + }; + + !version.is_empty() + && version + .bytes() + .all(|byte| byte.is_ascii_alphanumeric() || b".-+".contains(&byte)) + && random_suffix.len() == UPDATER_RANDOM_SUFFIX_LENGTH + && random_suffix.bytes().all(|byte| byte.is_ascii_alphanumeric()) +}