fix(cli): harden tht installer replacement

This commit is contained in:
2026-08-15 22:10:59 +02:00
parent 5e13396669
commit a2d5a244de
4 changed files with 73 additions and 16 deletions
+35 -2
View File
@@ -37,6 +37,40 @@ function Add-InstallDirectoryToUserPath([string]$InstallDirectory) {
return $true
}
function Replace-InstalledBinary([string]$StagedBinary, [string]$TargetBinary) {
$backupBinary = $null
$replacedExistingBinary = $false
try {
if (Test-Path -LiteralPath $TargetBinary -PathType Leaf) {
$backupBinary = Join-Path (Split-Path -Parent $TargetBinary) ('.tht-previous-' + [guid]::NewGuid() + '.exe')
[System.IO.File]::Replace($StagedBinary, $TargetBinary, $backupBinary, $true)
$replacedExistingBinary = $true
} else {
[System.IO.File]::Move($StagedBinary, $TargetBinary)
}
& $TargetBinary --help | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'installed tht did not pass its help check' }
if ($backupBinary -and (Test-Path -LiteralPath $backupBinary -PathType Leaf)) {
Remove-Item -LiteralPath $backupBinary -Force -ErrorAction Stop
}
} catch {
$installFailure = $_
if ($replacedExistingBinary -and $backupBinary -and (Test-Path -LiteralPath $backupBinary -PathType Leaf)) {
try {
[System.IO.File]::Replace($backupBinary, $TargetBinary, $null, $true)
$backupBinary = $null
} catch {
throw "tht replacement failed; the previous executable remains at $backupBinary. Original failure: $installFailure. Restore failure: $_"
}
}
throw $installFailure
} finally {
Remove-Item -LiteralPath $StagedBinary -Force -ErrorAction SilentlyContinue
}
}
$repositoryRoot = Split-Path -Parent $PSScriptRoot
$buildOutput = $null
$sourceArtifactForInstall = $null
@@ -86,9 +120,8 @@ try {
Copy-Item -LiteralPath $sourceArtifactForInstall -Destination $stagedBinary -Force
& $stagedBinary --help | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'native artifact did not pass its help check' }
Move-Item -LiteralPath $stagedBinary -Destination (Join-Path $installDirectory 'tht.exe') -Force
Replace-InstalledBinary $stagedBinary (Join-Path $installDirectory 'tht.exe')
} finally {
Remove-Item -LiteralPath $stagedBinary -Force -ErrorAction SilentlyContinue
if ($buildOutput) { Remove-Item -LiteralPath $buildOutput -Recurse -Force -ErrorAction SilentlyContinue }
}