1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 20:50:06 +00:00
Files
Mole/lib/core/tui_binaries.ps1

219 lines
5.7 KiB
PowerShell

# Mole - TUI binary helper
# Resolves, downloads, or builds analyze/status executables on Windows.
#Requires -Version 5.1
Set-StrictMode -Version Latest
if ((Get-Variable -Name 'MOLE_TUI_BINARIES_LOADED' -Scope Script -ErrorAction SilentlyContinue) -and $script:MOLE_TUI_BINARIES_LOADED) {
return
}
$script:MOLE_TUI_BINARIES_LOADED = $true
$script:MOLE_TUI_CORE_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$script:MOLE_TUI_CORE_DIR\version.ps1"
$script:MoleGitHubRepo = "tw93/Mole"
$script:MoleGitHubApiRoot = "https://api.github.com/repos/$($script:MoleGitHubRepo)"
$script:MoleGitHubHeaders = @{
"User-Agent" = "Mole-Windows"
"Accept" = "application/vnd.github+json"
}
function Get-MoleVersionFromScriptFile {
param([string]$WindowsDir)
return Get-MoleVersionString -RootDir $WindowsDir
}
function Get-TuiBinaryAssetName {
param([string]$Name)
return "$Name-windows-x64.exe"
}
function Resolve-TuiBinaryPath {
param(
[string]$WindowsDir,
[string]$Name
)
$candidates = @(
(Join-Path $WindowsDir "bin\$Name.exe"),
(Join-Path $WindowsDir "$Name.exe")
)
foreach ($candidate in $candidates) {
if (Test-Path $candidate) {
return $candidate
}
}
return $null
}
function Get-WindowsPrereleaseReleaseInfo {
param([string]$Version)
if (-not $Version) {
return $null
}
$tagCandidates = @(
"V$Version-windows",
"v$Version-windows"
)
foreach ($tag in $tagCandidates) {
$uri = "$($script:MoleGitHubApiRoot)/releases/tags/$tag"
try {
return Invoke-RestMethod -Uri $uri -Headers $script:MoleGitHubHeaders -Method Get
}
catch {
continue
}
}
return $null
}
function Restore-PrebuiltTuiBinary {
param(
[string]$Name,
[string]$WindowsDir,
[string]$DestinationPath,
[string]$Version
)
$releaseInfo = Get-WindowsPrereleaseReleaseInfo -Version $Version
if (-not $releaseInfo) {
return $false
}
$assetName = Get-TuiBinaryAssetName -Name $Name
$asset = $releaseInfo.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
if (-not $asset) {
return $false
}
$binDir = Split-Path -Parent $DestinationPath
if (-not (Test-Path $binDir)) {
New-Item -ItemType Directory -Path $binDir -Force | Out-Null
}
Write-Host "Downloading prebuilt $Name tool..." -ForegroundColor Cyan
try {
Invoke-WebRequest -Uri $asset.browser_download_url -Headers $script:MoleGitHubHeaders -OutFile $DestinationPath -UseBasicParsing
return (Test-Path $DestinationPath)
}
catch {
if (Test-Path $DestinationPath) {
Remove-Item $DestinationPath -Force -ErrorAction SilentlyContinue
}
return $false
}
}
function Build-TuiBinary {
param(
[string]$Name,
[string]$WindowsDir,
[string]$DestinationPath,
[string]$SourcePath
)
$binDir = Split-Path -Parent $DestinationPath
if (-not (Test-Path $binDir)) {
New-Item -ItemType Directory -Path $binDir -Force | Out-Null
}
Write-Host "Building $Name tool..." -ForegroundColor Cyan
$stdoutPath = Join-Path $env:TEMP "mole-$Name-build.stdout.log"
$stderrPath = Join-Path $env:TEMP "mole-$Name-build.stderr.log"
foreach ($path in @($stdoutPath, $stderrPath)) {
if (Test-Path $path) {
Remove-Item $path -Force -ErrorAction SilentlyContinue
}
}
Push-Location $WindowsDir
try {
$process = Start-Process -FilePath "go" `
-ArgumentList @("build", "-o", $DestinationPath, $SourcePath) `
-NoNewWindow `
-Wait `
-PassThru `
-RedirectStandardOutput $stdoutPath `
-RedirectStandardError $stderrPath
}
catch {
Write-Host "Failed to start go build for $Name tool: $_" -ForegroundColor Red
return $false
}
finally {
Pop-Location
}
$buildOutput = @()
foreach ($path in @($stdoutPath, $stderrPath)) {
if (Test-Path $path) {
$content = (Get-Content $path -Raw).Trim()
if ($content) {
$buildOutput += $content
}
Remove-Item $path -Force -ErrorAction SilentlyContinue
}
}
if ($process.ExitCode -ne 0) {
$message = if ($buildOutput.Count -gt 0) { $buildOutput -join [Environment]::NewLine } else { "go build exited with code $($process.ExitCode)" }
Write-Host "Failed to build $Name tool: $message" -ForegroundColor Red
return $false
}
return $true
}
function Ensure-TuiBinary {
param(
[string]$Name,
[string]$WindowsDir,
[string]$DestinationPath,
[string]$SourcePath,
[string]$Version
)
$existingBin = Resolve-TuiBinaryPath -WindowsDir $WindowsDir -Name $Name
if ($existingBin) {
return $existingBin
}
if (-not $Version) {
$Version = Get-MoleVersionFromScriptFile -WindowsDir $WindowsDir
}
try {
if (Restore-PrebuiltTuiBinary -Name $Name -WindowsDir $WindowsDir -DestinationPath $DestinationPath -Version $Version) {
return $DestinationPath
}
}
catch {
Write-Host "Failed to restore prebuilt $Name tool: $_" -ForegroundColor Yellow
}
if (Get-Command go -ErrorAction SilentlyContinue) {
try {
if (Build-TuiBinary -Name $Name -WindowsDir $WindowsDir -DestinationPath $DestinationPath -SourcePath $SourcePath) {
return $DestinationPath
}
}
catch {
Write-Host "Failed to prepare $Name tool: $_" -ForegroundColor Yellow
}
}
return $null
}