From bea46747008fe06aa58d88bbf7824db0f683ad71 Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Sun, 12 Jul 2026 21:30:14 -0400 Subject: [PATCH] Prevent update from using stale latest release --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/bin/dosh-client.rs | 86 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b34210f..ca4b428 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,7 +436,7 @@ dependencies = [ [[package]] name = "dosh" -version = "1.0.0-rc41" +version = "1.0.0-rc42" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 9e766e1..f0f1df4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dosh" -version = "1.0.0-rc41" +version = "1.0.0-rc42" edition = "2024" license = "MIT" diff --git a/src/bin/dosh-client.rs b/src/bin/dosh-client.rs index 2d5d516..3554d3b 100644 --- a/src/bin/dosh-client.rs +++ b/src/bin/dosh-client.rs @@ -4124,6 +4124,15 @@ fn update_version_status(local: &str, latest: &str) -> &'static str { } } +fn update_binary_version_for_installer(local: &str, latest_tag: Option<&str>) -> Option { + let latest = latest_tag.map(release_version_from_tag)?; + if compare_dotted_versions(latest, local) == std::cmp::Ordering::Less { + Some(format!("v{local}")) + } else { + None + } +} + fn compare_dotted_versions(left: &str, right: &str) -> std::cmp::Ordering { let left = parse_dotted_version(left); let right = parse_dotted_version(right); @@ -4249,6 +4258,10 @@ fn run_update(config: &dosh::config::ClientConfig, options: UpdateOptions) -> Re .join("dosh") .join("source"); let use_prebuilt = std::env::var("DOSH_USE_PREBUILT").unwrap_or_else(|_| "1".to_string()); + let binary_version = update_binary_version_for_installer( + env!("CARGO_PKG_VERSION"), + latest_release_tag(&repo)?.as_deref(), + ); let status = run_update_installer( config, &repo, @@ -4256,6 +4269,7 @@ fn run_update(config: &dosh::config::ClientConfig, options: UpdateOptions) -> Re installer_role, &update_cache.display().to_string(), &use_prebuilt, + binary_version.as_deref(), )?; if !status.success() { return Err(anyhow!("dosh update failed with status {status}")); @@ -4270,6 +4284,7 @@ fn run_update_installer( installer_role: &str, update_cache: &str, use_prebuilt: &str, + binary_version: Option<&str>, ) -> Result { if cfg!(windows) { let script = windows_update_script( @@ -4279,6 +4294,7 @@ fn run_update_installer( installer_role, update_cache, use_prebuilt, + binary_version, ); return Command::new("powershell.exe") .arg("-NoProfile") @@ -4297,6 +4313,7 @@ fn run_update_installer( installer_role, update_cache, use_prebuilt, + binary_version, ); Command::new("sh") .arg("-c") @@ -4313,14 +4330,22 @@ fn unix_update_script( installer_role: &str, update_cache: &str, use_prebuilt: &str, + binary_version: Option<&str>, ) -> String { - let mut script = format!( - "curl -fsSL {} | DOSH_REPO={} DOSH_PORT={} DOSH_UPDATE_CACHE={} DOSH_UPDATE_QUIET=1 DOSH_USE_PREBUILT={} sh -s -- {}", - shell_word(installer), + let mut env = format!( + "DOSH_REPO={} DOSH_PORT={} DOSH_UPDATE_CACHE={} DOSH_UPDATE_QUIET=1 DOSH_USE_PREBUILT={}", shell_word(repo), config.update_port.unwrap_or(config.dosh_port), shell_word(update_cache), - shell_word(use_prebuilt), + shell_word(use_prebuilt) + ); + if let Some(version) = binary_version { + env.push_str(&format!(" DOSH_BINARY_VERSION={}", shell_word(version))); + } + let mut script = format!( + "curl -fsSL {} | {} sh -s -- {}", + shell_word(installer), + env, shell_word(installer_role) ); if config.server != "user@example.com" { @@ -4339,6 +4364,7 @@ fn windows_update_script( installer_role: &str, update_cache: &str, use_prebuilt: &str, + binary_version: Option<&str>, ) -> String { let mut script = String::from("$ErrorActionPreference='Stop';"); script.push_str("$ProgressPreference='SilentlyContinue';"); @@ -4355,6 +4381,12 @@ fn windows_update_script( ] { script.push_str(&format!("$env:{name}={};", powershell_string(value))); } + if let Some(version) = binary_version { + script.push_str(&format!( + "$env:DOSH_BINARY_VERSION={};", + powershell_string(version) + )); + } if config.server != "user@example.com" { script.push_str(&format!( "$env:DOSH_SERVER={};", @@ -9433,8 +9465,8 @@ mod tests { strip_stale_mouse_reports, strip_terminal_focus_reports, strip_unowned_terminal_reports, summarize_trace_file, summarize_trace_file_with_mode, terminal_private_mode_transition, toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script, - update_installer_url, update_version_status, upsert_managed_block, valid_forward_host, - vscode_safe_alias, windows_update_script, + update_binary_version_for_installer, update_installer_url, update_version_status, + upsert_managed_block, valid_forward_host, vscode_safe_alias, windows_update_script, }; use dosh::config::{ClientConfig, CommandExtension, HostConfig}; use dosh::native::EnvVar; @@ -11098,6 +11130,7 @@ mod tests { "both", "/tmp/dosh-cache", "1", + None, ); assert!(unix.contains("curl -fsSL")); assert!(unix.contains("install.sh")); @@ -11112,6 +11145,7 @@ mod tests { "client", "C:\\Users\\palav\\AppData\\Local\\dosh\\source", "1", + None, ); assert!( windows.contains( @@ -11125,6 +11159,46 @@ mod tests { assert!(!windows.contains(" sh -s ")); } + #[test] + fn update_uses_local_tag_when_release_latest_is_older() { + assert_eq!( + update_binary_version_for_installer("1.0.0-rc41", Some("v1.0.0-rc37")).as_deref(), + Some("v1.0.0-rc41") + ); + assert_eq!( + update_binary_version_for_installer("1.0.0-rc41", Some("v1.0.0-rc41")), + None + ); + assert_eq!( + update_binary_version_for_installer("1.0.0-rc41", Some("v1.0.0-rc42")), + None + ); + let config = ClientConfig::default(); + let unix = unix_update_script( + &config, + "https://git.palav.dev/Palav/dosh.git", + "https://git.palav.dev/Palav/dosh/raw/branch/main/install.sh", + "both", + "/tmp/dosh-cache", + "1", + Some("v1.0.0-rc41"), + ); + assert!(unix.contains("DOSH_BINARY_VERSION='v1.0.0-rc41'")); + assert!(unix.contains("| DOSH_REPO=")); + assert!(unix.contains(" sh -s -- 'both'")); + + let windows = windows_update_script( + &config, + "https://git.palav.dev/Palav/dosh.git", + "https://git.palav.dev/Palav/dosh/raw/branch/main/install.ps1", + "client", + "C:\\Users\\palav\\AppData\\Local\\dosh\\source", + "1", + Some("v1.0.0-rc41"), + ); + assert!(windows.contains("$env:DOSH_BINARY_VERSION='v1.0.0-rc41';")); + } + #[test] fn status_uses_host_alias_and_user() { let host = HostConfig {