From c29c43d4db0f2061390f1aeb08741f6528074d40 Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:20:35 -0400 Subject: [PATCH] Reuse Windows update source cache --- install.ps1 | 43 +++++++++++++++++++++++++++++++++------- tests/release_scripts.rs | 14 +++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/install.ps1 b/install.ps1 index 005bb22..8c9b942 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,6 +11,7 @@ param( [string]$BinaryBase = $env:DOSH_BINARY_BASE, [string]$BinaryName = $env:DOSH_BINARY_NAME, [string]$BinaryVersion = $(if ($env:DOSH_BINARY_VERSION) { $env:DOSH_BINARY_VERSION } else { "latest" }), + [string]$UpdateCache = $(if ($env:DOSH_UPDATE_CACHE) { $env:DOSH_UPDATE_CACHE } else { Join-Path $HOME ".cache\dosh\source" }), [switch]$BinaryRequired = $($env:DOSH_BINARY_REQUIRED -and $env:DOSH_BINARY_REQUIRED -ne "0"), [switch]$ForceConfig ) @@ -268,6 +269,27 @@ function Install-Binary($Source, $Destination) { } } +function Normalize-PathForCompare($Path) { + [System.IO.Path]::GetFullPath($Path).TrimEnd( + [System.IO.Path]::DirectorySeparatorChar, + [System.IO.Path]::AltDirectorySeparatorChar + ) +} + +function Assert-SafeUpdateCache($Path) { + if (-not $Path) { + throw "refusing unsafe update cache path: $Path" + } + $full = Normalize-PathForCompare $Path + $root = Normalize-PathForCompare ([System.IO.Path]::GetPathRoot($full)) + $homePath = Normalize-PathForCompare $HOME + $homeCache = Normalize-PathForCompare (Join-Path $HOME ".cache") + if ($full -eq $root -or $full -eq $homePath -or $full -eq $homeCache) { + throw "refusing unsafe update cache path: $Path" + } + $full +} + $bindir = Join-Path $Prefix "bin" $configDir = Join-Path $HOME ".config\dosh" New-Item -ItemType Directory -Force -Path $bindir, $configDir | Out-Null @@ -316,7 +338,6 @@ function Install-Prebuilt { function Install-FromSource { Require-Command cargo - $tmp = $null if (Test-Path "Cargo.toml") { $src = (Get-Location).Path } else { @@ -324,9 +345,20 @@ function Install-FromSource { throw "DOSH_REPO is required when running the installer from irm/iex" } Require-Command git - $tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("dosh-" + [guid]::NewGuid()) - git clone --depth 1 $Repo $tmp | Out-Null - $src = $tmp + $sourceCache = Assert-SafeUpdateCache $UpdateCache + $parent = Split-Path -Parent $sourceCache + New-Item -ItemType Directory -Force -Path $parent | Out-Null + if (Test-Path (Join-Path $sourceCache ".git")) { + git -C $sourceCache remote set-url origin $Repo + git -C $sourceCache fetch --depth 1 origin main + git -C $sourceCache checkout -q -B main FETCH_HEAD + } else { + if (Test-Path $sourceCache) { + Remove-Item -Recurse -Force $sourceCache + } + git clone --depth 1 --branch main $Repo $sourceCache | Out-Null + } + $src = $sourceCache } try { @@ -338,9 +370,6 @@ function Install-FromSource { } finally { Pop-Location - if ($tmp) { - Remove-Item -Recurse -Force $tmp - } } } diff --git a/tests/release_scripts.rs b/tests/release_scripts.rs index 76aeb21..603401a 100644 --- a/tests/release_scripts.rs +++ b/tests/release_scripts.rs @@ -95,6 +95,20 @@ fn installers_refuse_prebuilts_without_checksums() { ); } +#[test] +fn windows_installer_reuses_persistent_source_update_cache() { + let ps1 = include_str!("../install.ps1"); + assert!(ps1.contains("DOSH_UPDATE_CACHE")); + assert!(ps1.contains("$sourceCache = Assert-SafeUpdateCache $UpdateCache")); + assert!(ps1.contains("git -C $sourceCache fetch --depth 1 origin main")); + assert!(ps1.contains("git -C $sourceCache checkout -q -B main FETCH_HEAD")); + assert!(ps1.contains("git clone --depth 1 --branch main $Repo $sourceCache")); + assert!( + !ps1.contains("git clone --depth 1 $Repo $tmp"), + "Windows source updates should reuse a persistent cache instead of recloning into temp" + ); +} + #[test] fn package_check_verifies_only_artifacts_it_builds() { let makefile = include_str!("../Makefile");