forked from mirrors/kingfisher
179 lines
5.3 KiB
PowerShell
179 lines
5.3 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Kingfisher pre-commit hook with automatic binary download for Windows.
|
|
|
|
.DESCRIPTION
|
|
Downloads and caches the Kingfisher binary, then scans staged changes.
|
|
No manual installation required.
|
|
|
|
.PARAMETER Version
|
|
Specific version to download (e.g., "1.76.0" or "v1.76.0").
|
|
Defaults to "latest".
|
|
|
|
.PARAMETER Arch
|
|
Optional architecture override. Defaults to auto-detection.
|
|
Allowed values: auto, x64, arm64.
|
|
|
|
.EXAMPLE
|
|
./kingfisher-pre-commit-auto.ps1
|
|
|
|
.EXAMPLE
|
|
$env:KINGFISHER_VERSION = "1.76.0"; ./kingfisher-pre-commit-auto.ps1
|
|
|
|
.EXAMPLE
|
|
./kingfisher-pre-commit-auto.ps1 -Arch arm64
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateSet('auto', 'x64', 'arm64')]
|
|
[string]$Arch = 'auto'
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$repo = 'mongodb/kingfisher'
|
|
$cacheDir = if ($env:KINGFISHER_CACHE_DIR) {
|
|
$env:KINGFISHER_CACHE_DIR
|
|
} else {
|
|
Join-Path $env:LOCALAPPDATA 'kingfisher'
|
|
}
|
|
$expectedVersion = if ($env:KINGFISHER_VERSION) { $env:KINGFISHER_VERSION } else { 'latest' }
|
|
$resolvedArch = $null
|
|
$kingfisherBin = $null
|
|
$versionFile = $null
|
|
|
|
function Resolve-ArchSuffix {
|
|
param(
|
|
[ValidateSet('auto', 'x64', 'arm64')]
|
|
[string]$RequestedArch
|
|
)
|
|
|
|
if ($RequestedArch -ne 'auto') {
|
|
return $RequestedArch
|
|
}
|
|
|
|
$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
|
switch ($osArch) {
|
|
'X64' { return 'x64' }
|
|
'Arm64' { return 'arm64' }
|
|
default { throw "Unsupported Windows architecture '$osArch'. Supported values are x64 and arm64." }
|
|
}
|
|
}
|
|
|
|
function Get-AssetName {
|
|
param(
|
|
[string]$ArchSuffix
|
|
)
|
|
|
|
return "kingfisher-windows-$ArchSuffix.zip"
|
|
}
|
|
|
|
function Download-Kingfisher {
|
|
param(
|
|
[string]$Version
|
|
)
|
|
|
|
$assetName = Get-AssetName -ArchSuffix $resolvedArch
|
|
|
|
if (-not (Test-Path $cacheDir)) {
|
|
New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
|
|
}
|
|
|
|
$tempDir = New-Item -ItemType Directory -Path ([System.IO.Path]::GetTempPath()) -Name ([System.Guid]::NewGuid().ToString())
|
|
|
|
try {
|
|
if ($Version -eq 'latest') {
|
|
$downloadUrl = "https://github.com/$repo/releases/latest/download/$assetName"
|
|
Write-Host "Downloading kingfisher (latest) for Windows $resolvedArch..." -ForegroundColor Cyan
|
|
} else {
|
|
# Support both "v1.76.0" and "1.76.0" formats
|
|
if (-not $Version.StartsWith('v')) {
|
|
$Version = "v$Version"
|
|
}
|
|
$downloadUrl = "https://github.com/$repo/releases/download/$Version/$assetName"
|
|
Write-Host "Downloading kingfisher ($Version) for Windows $resolvedArch..." -ForegroundColor Cyan
|
|
}
|
|
|
|
$archivePath = Join-Path $tempDir.FullName $assetName
|
|
|
|
try {
|
|
Invoke-WebRequest -Uri $downloadUrl -OutFile $archivePath -UseBasicParsing
|
|
} catch {
|
|
Write-Error "Failed to download $downloadUrl : $_"
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Extracting archive..." -ForegroundColor Cyan
|
|
Expand-Archive -Path $archivePath -DestinationPath $tempDir.FullName -Force
|
|
|
|
$extractedBinary = Join-Path $tempDir.FullName 'kingfisher.exe'
|
|
if (-not (Test-Path $extractedBinary)) {
|
|
Write-Error "Binary not found in downloaded archive"
|
|
exit 1
|
|
}
|
|
|
|
Copy-Item -Path $extractedBinary -Destination $kingfisherBin -Force
|
|
|
|
# Store the version we downloaded
|
|
if ($Version -eq 'latest') {
|
|
try {
|
|
$versionOutput = & $kingfisherBin --version 2>$null | Select-Object -First 1
|
|
Set-Content -Path $versionFile -Value $versionOutput -NoNewline
|
|
} catch {
|
|
Set-Content -Path $versionFile -Value 'latest' -NoNewline
|
|
}
|
|
} else {
|
|
Set-Content -Path $versionFile -Value $Version -NoNewline
|
|
}
|
|
|
|
Write-Host "Kingfisher installed to $kingfisherBin" -ForegroundColor Green
|
|
}
|
|
finally {
|
|
if ($tempDir -and (Test-Path $tempDir.FullName)) {
|
|
Remove-Item -Path $tempDir.FullName -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
function Test-NeedsDownload {
|
|
# Binary doesn't exist
|
|
if (-not (Test-Path $kingfisherBin)) {
|
|
return $true
|
|
}
|
|
|
|
# No version tracking - always use existing binary for 'latest'
|
|
if ($expectedVersion -eq 'latest') {
|
|
return $false
|
|
}
|
|
|
|
# Check if version matches
|
|
if (Test-Path $versionFile) {
|
|
$installedVersion = Get-Content -Path $versionFile -Raw
|
|
|
|
# Normalize version format for comparison
|
|
$expectedNormalized = $expectedVersion
|
|
if (-not $expectedNormalized.StartsWith('v')) {
|
|
$expectedNormalized = "v$expectedNormalized"
|
|
}
|
|
|
|
if ($installedVersion -like "*$expectedNormalized*" -or $installedVersion -eq $expectedVersion) {
|
|
return $false
|
|
}
|
|
}
|
|
|
|
return $true
|
|
}
|
|
|
|
# Main execution
|
|
$resolvedArch = Resolve-ArchSuffix -RequestedArch $Arch
|
|
$kingfisherBin = Join-Path $cacheDir 'kingfisher.exe'
|
|
$versionFile = Join-Path $cacheDir ".version-$resolvedArch"
|
|
|
|
if (Test-NeedsDownload) {
|
|
Download-Kingfisher -Version $expectedVersion
|
|
}
|
|
|
|
# Run kingfisher scan on staged changes
|
|
# Pass through any additional arguments
|
|
& $kingfisherBin scan . --staged --quiet --no-update-check @args
|
|
exit $LASTEXITCODE
|