mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 17:55:08 +00:00
219 lines
5.7 KiB
PowerShell
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
|
|
}
|