Files
ktui/install.ps1

111 lines
3.7 KiB
PowerShell

$ErrorActionPreference = "Stop"
$ApiBaseUrl = if ($env:KTUI_API_BASE_URL) { $env:KTUI_API_BASE_URL } else { "https://gitea.bytevibe.dev/api/v1/repos/gary/ktui" }
$InstallDir = if ($env:KTUI_INSTALL_DIR) { $env:KTUI_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "ktui\bin" }
$Version = if ($env:KTUI_VERSION) { $env:KTUI_VERSION } else { "latest" }
$BinaryName = "ktui.exe"
function Fail($Message) {
Write-Error "ktui install: $Message"
exit 1
}
function Invoke-KtuiGet($Url, $OutFile) {
$headers = @{}
if ($env:KTUI_UPDATE_TOKEN) {
$headers["Authorization"] = "token $env:KTUI_UPDATE_TOKEN"
} elseif ($env:GITEA_TOKEN) {
$headers["Authorization"] = "token $env:GITEA_TOKEN"
}
if ($OutFile) {
Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $Url -OutFile $OutFile
} else {
Invoke-RestMethod -Headers $headers -Uri $Url
}
}
function Get-KtuiArch {
switch ($env:PROCESSOR_ARCHITECTURE) {
"AMD64" { "amd64"; break }
"ARM64" { "arm64"; break }
default { Fail "unsupported architecture: $env:PROCESSOR_ARCHITECTURE" }
}
}
$endpoint = "$ApiBaseUrl/releases/latest"
if ($Version -ne "latest") {
$endpoint = "$ApiBaseUrl/releases/tags/$Version"
}
$release = Invoke-KtuiGet $endpoint
if (-not $release.tag_name) {
Fail "release response does not include tag_name"
}
$arch = Get-KtuiArch
$suffix = "_windows_${arch}.zip"
$asset = $release.assets | Where-Object {
$_.name -like "ktui_*" -and $_.name.EndsWith($suffix) -and $_.browser_download_url
} | Select-Object -First 1
$checksums = $release.assets | Where-Object {
$_.name -eq "checksums.txt" -and $_.browser_download_url
} | Select-Object -First 1
if (-not $asset) {
Fail "release $($release.tag_name) does not contain an asset for windows/$arch"
}
if (-not $checksums) {
Fail "release does not contain checksums.txt"
}
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("ktui-install-" + [System.Guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Path $tmp | Out-Null
try {
$archivePath = Join-Path $tmp $asset.name
$checksumsPath = Join-Path $tmp "checksums.txt"
Write-Host "ktui install: downloading $($asset.name)"
Invoke-KtuiGet $asset.browser_download_url $archivePath
Invoke-KtuiGet $checksums.browser_download_url $checksumsPath
$expected = $null
foreach ($line in Get-Content $checksumsPath) {
$parts = $line -split "\s+"
if ($parts.Length -lt 2) {
continue
}
$filename = Split-Path ($parts[-1].TrimStart("*")) -Leaf
if ($filename -eq $asset.name) {
$expected = $parts[0].ToLowerInvariant()
break
}
}
if (-not $expected) {
Fail "checksums.txt does not contain $($asset.name)"
}
$got = (Get-FileHash -Algorithm SHA256 $archivePath).Hash.ToLowerInvariant()
if ($got -ne $expected) {
Fail "checksum mismatch for $($asset.name)"
}
Expand-Archive -Force -Path $archivePath -DestinationPath $tmp
$binary = Get-ChildItem -Path $tmp -Recurse -File -Filter $BinaryName | Select-Object -First 1
if (-not $binary) {
Fail "archive does not contain $BinaryName"
}
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
$installPath = Join-Path $InstallDir $BinaryName
Copy-Item -Force $binary.FullName $installPath
Write-Host "ktui install: installed $installPath"
$pathEntries = $env:PATH -split ";"
if ($pathEntries -notcontains $InstallDir) {
Write-Host "ktui install: add $InstallDir to PATH if ktui is not found"
}
& $installPath version
} finally {
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}