From fc9eb7ea697b0c070d83f0929e0236028cddcad3 Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:25:57 -0400 Subject: [PATCH] Match Windows update artifact to native architecture --- src/bin/dosh-client.rs | 112 +++++++++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 31 deletions(-) diff --git a/src/bin/dosh-client.rs b/src/bin/dosh-client.rs index 40dc845..325b587 100644 --- a/src/bin/dosh-client.rs +++ b/src/bin/dosh-client.rs @@ -4164,18 +4164,43 @@ fn local_server_install_detected() -> bool { bin_dir.join("dosh-server").exists() || bin_dir.join("dosh-server.exe").exists() } -fn release_artifact_name() -> &'static str { - match (std::env::consts::OS, std::env::consts::ARCH) { - ("macos", "aarch64") => "dosh-macos-aarch64.tar.gz", - ("macos", "x86_64") => "dosh-macos-x86_64.tar.gz", - ("linux", "aarch64") => "dosh-linux-aarch64.tar.gz", - ("linux", "x86_64") => "dosh-linux-x86_64.tar.gz", - ("windows", "x86_64") => "dosh-windows-x86_64.zip", - ("windows", "aarch64") => "dosh-windows-aarch64.zip", - _ => "dosh-unknown.tar.gz", +fn release_artifact_name() -> String { + release_artifact_name_for( + std::env::consts::OS, + std::env::consts::ARCH, + std::env::var("PROCESSOR_ARCHITEW6432").ok().as_deref(), + ) +} + +fn release_artifact_name_for(os: &str, arch: &str, native_windows_arch: Option<&str>) -> String { + let arch = if os == "windows" { + normalize_windows_artifact_arch(native_windows_arch.unwrap_or(arch)) + } else { + normalize_artifact_arch(arch) + }; + match (os, arch.as_str()) { + ("macos", "aarch64") => "dosh-macos-aarch64.tar.gz".to_string(), + ("macos", "x86_64") => "dosh-macos-x86_64.tar.gz".to_string(), + ("linux", "aarch64") => "dosh-linux-aarch64.tar.gz".to_string(), + ("linux", "x86_64") => "dosh-linux-x86_64.tar.gz".to_string(), + ("windows", "x86_64") => "dosh-windows-x86_64.zip".to_string(), + ("windows", "aarch64") => "dosh-windows-aarch64.zip".to_string(), + _ => "dosh-unknown.tar.gz".to_string(), } } +fn normalize_artifact_arch(arch: &str) -> String { + match arch.to_ascii_lowercase().as_str() { + "amd64" => "x86_64".to_string(), + "arm64" => "aarch64".to_string(), + other => other.to_string(), + } +} + +fn normalize_windows_artifact_arch(arch: &str) -> String { + normalize_artifact_arch(arch) +} + fn update_installer_name(os: &str) -> &'static str { if os == "windows" { "install.ps1" @@ -4425,13 +4450,13 @@ fn run_update(config: &dosh::config::ClientConfig, options: UpdateOptions) -> Re } None => println!("latest: unknown"), } - if let Some(latest_url) = latest_release_download_url(&repo, artifact) { + if let Some(latest_url) = latest_release_download_url(&repo, &artifact) { let mut status = "missing"; let mut display_url = latest_url.clone(); if let Some(tag_url) = effective_update_artifact_tag(local_version, latest_tag.as_deref()) .as_deref() - .and_then(|tag| release_tag_download_url(&repo, tag, artifact)) + .and_then(|tag| release_tag_download_url(&repo, tag, &artifact)) { display_url = tag_url; if url_reachable(&display_url)? { @@ -10230,26 +10255,27 @@ mod tests { parse_ssh_config, parse_trace_line, parse_trace_options, parse_trace_report_options, parse_trace_summary, parse_update_options, post_submit_hold_duration, queue_or_send_stream_data, queue_pending_user_input, queue_stale_pending_user_input, - raw_contains_host_table, recv_response_until, refresh_live_addr, release_tag_download_url, - release_tag_from_effective_url, release_version_from_tag, render_frame_bytes, - render_status_clear, render_status_overlay, requested_env, resolve_forward_agent_endpoint, - resolved_startup_command, retire_stream_state, retransmit_stream_closes, - retransmit_stream_eofs, retransmit_stream_opens, retransmit_stream_window_adjusts, - rewrite_forward_command, sanitize_trace_name, selected_predict_mode, selected_udp_host, - send_stream_eof, server_version_mismatch, should_flush_terminal_input_after_contact, - should_health_log_client_start, should_hold_during_startup_gate, - should_hold_post_submit_input, should_reconnect_before_input_for_local_sleep, - should_repaint_idle_terminal, should_strip_unowned_terminal_reports, - split_after_command_submit, split_trace_tokens, ssh_command_target, ssh_config_uses_proxy, - ssh_config_word_for_os, ssh_destination_host, ssh_username, ssh_with_user, startup_command, - status_ssh_target, 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_binary_version_for_installer, - update_installer_url, update_version_status, upsert_managed_block, valid_forward_host, - vscode_safe_alias, wake_repaint_retry_deadline, windows_command_word, - windows_deferred_update_script, windows_effective_url_script, windows_mode_from_readonly, - windows_readonly_from_mode, windows_update_script, windows_url_reachable_script, + raw_contains_host_table, recv_response_until, refresh_live_addr, release_artifact_name_for, + release_tag_download_url, release_tag_from_effective_url, release_version_from_tag, + render_frame_bytes, render_status_clear, render_status_overlay, requested_env, + resolve_forward_agent_endpoint, resolved_startup_command, retire_stream_state, + retransmit_stream_closes, retransmit_stream_eofs, retransmit_stream_opens, + retransmit_stream_window_adjusts, rewrite_forward_command, sanitize_trace_name, + selected_predict_mode, selected_udp_host, send_stream_eof, server_version_mismatch, + should_flush_terminal_input_after_contact, should_health_log_client_start, + should_hold_during_startup_gate, should_hold_post_submit_input, + should_reconnect_before_input_for_local_sleep, should_repaint_idle_terminal, + should_strip_unowned_terminal_reports, split_after_command_submit, split_trace_tokens, + ssh_command_target, ssh_config_uses_proxy, ssh_config_word_for_os, ssh_destination_host, + ssh_username, ssh_with_user, startup_command, status_ssh_target, 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_binary_version_for_installer, update_installer_url, update_version_status, + upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline, + windows_command_word, windows_deferred_update_script, windows_effective_url_script, + windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script, + windows_url_reachable_script, }; use dosh::config::{ClientConfig, CommandExtension, HostConfig}; use dosh::native::EnvVar; @@ -12665,6 +12691,30 @@ mod tests { ); } + #[test] + fn release_artifact_name_matches_platform_and_native_windows_arch() { + assert_eq!( + release_artifact_name_for("macos", "aarch64", None), + "dosh-macos-aarch64.tar.gz" + ); + assert_eq!( + release_artifact_name_for("macos", "x86_64", None), + "dosh-macos-x86_64.tar.gz" + ); + assert_eq!( + release_artifact_name_for("windows", "x86_64", None), + "dosh-windows-x86_64.zip" + ); + assert_eq!( + release_artifact_name_for("windows", "x86_64", Some("ARM64")), + "dosh-windows-aarch64.zip" + ); + assert_eq!( + release_artifact_name_for("windows", "AMD64", Some("AMD64")), + "dosh-windows-x86_64.zip" + ); + } + #[test] fn release_tag_parses_effective_latest_url() { assert_eq!(