Add native Windows support (#91)
- Native Windows daemon using TCP loopback endpoints - Direct-mode fallback for CLI/daemon compatibility - Comment operations over RPC - PowerShell installer script - Go 1.24 requirement - Cross-OS testing documented Co-authored-by: danshapiro <danshapiro@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-c6230265-055f-4af1-9712-4481061886db Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
201
install.ps1
Normal file
201
install.ps1
Normal file
@@ -0,0 +1,201 @@
|
||||
# Beads (bd) Windows installer
|
||||
# Usage:
|
||||
# irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$Script:SkipGoInstall = $env:BEADS_INSTALL_SKIP_GOINSTALL -eq "1"
|
||||
$Script:SourceOverride = $env:BEADS_INSTALL_SOURCE
|
||||
|
||||
function Write-Info($Message) { Write-Host "==> $Message" -ForegroundColor Cyan }
|
||||
function Write-Success($Message) { Write-Host "==> $Message" -ForegroundColor Green }
|
||||
function Write-WarningMsg($Message) { Write-Warning $Message }
|
||||
function Write-Err($Message) { Write-Host "Error: $Message" -ForegroundColor Red }
|
||||
|
||||
function Test-GoSupport {
|
||||
$goCmd = Get-Command go -ErrorAction SilentlyContinue
|
||||
if (-not $goCmd) {
|
||||
return [pscustomobject]@{
|
||||
Present = $false
|
||||
MeetsRequirement = $false
|
||||
RawVersion = $null
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$output = & go version
|
||||
} catch {
|
||||
return [pscustomobject]@{
|
||||
Present = $false
|
||||
MeetsRequirement = $false
|
||||
RawVersion = $null
|
||||
}
|
||||
}
|
||||
|
||||
$match = [regex]::Match($output, 'go(?<major>\d+)\.(?<minor>\d+)')
|
||||
if (-not $match.Success) {
|
||||
return [pscustomobject]@{
|
||||
Present = $true
|
||||
MeetsRequirement = $true
|
||||
RawVersion = $output
|
||||
}
|
||||
}
|
||||
|
||||
$major = [int]$match.Groups["major"].Value
|
||||
$minor = [int]$match.Groups["minor"].Value
|
||||
$meets = ($major -gt 1) -or ($major -eq 1 -and $minor -ge 24)
|
||||
|
||||
return [pscustomobject]@{
|
||||
Present = $true
|
||||
MeetsRequirement = $meets
|
||||
RawVersion = $output.Trim()
|
||||
}
|
||||
}
|
||||
|
||||
function Install-WithGo {
|
||||
if ($Script:SkipGoInstall) {
|
||||
Write-Info "Skipping go install (BEADS_INSTALL_SKIP_GOINSTALL=1)."
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Info "Installing bd via go install..."
|
||||
try {
|
||||
& go install github.com/steveyegge/beads/cmd/bd@latest
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-WarningMsg "go install exited with code $LASTEXITCODE"
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-WarningMsg "go install failed: $_"
|
||||
return $false
|
||||
}
|
||||
|
||||
$gopath = (& go env GOPATH)
|
||||
if (-not $gopath) {
|
||||
return $true
|
||||
}
|
||||
|
||||
$binDir = Join-Path $gopath "bin"
|
||||
$bdPath = Join-Path $binDir "bd.exe"
|
||||
if (-not (Test-Path $bdPath)) {
|
||||
Write-WarningMsg "bd.exe not found in $binDir after install"
|
||||
}
|
||||
|
||||
$pathEntries = [Environment]::GetEnvironmentVariable("PATH", "Process").Split([IO.Path]::PathSeparator) | ForEach-Object { $_.Trim() }
|
||||
if (-not ($pathEntries -contains $binDir)) {
|
||||
Write-WarningMsg "$binDir is not in your PATH. Add it with:`n setx PATH `"$Env:PATH;$binDir`""
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
function Install-FromSource {
|
||||
Write-Info "Building bd from source..."
|
||||
|
||||
$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("beads-install-" + [guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Path $tempRoot | Out-Null
|
||||
|
||||
try {
|
||||
$repoPath = Join-Path $tempRoot "beads"
|
||||
if ($Script:SourceOverride) {
|
||||
Write-Info "Using source override: $Script:SourceOverride"
|
||||
if (Test-Path $Script:SourceOverride) {
|
||||
New-Item -ItemType Directory -Path $repoPath | Out-Null
|
||||
Get-ChildItem -LiteralPath $Script:SourceOverride -Force | Where-Object { $_.Name -ne ".git" } | ForEach-Object {
|
||||
$destination = Join-Path $repoPath $_.Name
|
||||
if ($_.PSIsContainer) {
|
||||
Copy-Item -LiteralPath $_.FullName -Destination $destination -Recurse -Force
|
||||
} else {
|
||||
Copy-Item -LiteralPath $_.FullName -Destination $repoPath -Force
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Info "Cloning override repository..."
|
||||
& git clone $Script:SourceOverride $repoPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git clone failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Info "Cloning repository..."
|
||||
& git clone --depth 1 https://github.com/steveyegge/beads.git $repoPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git clone failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
|
||||
Push-Location $repoPath
|
||||
try {
|
||||
Write-Info "Compiling bd.exe..."
|
||||
& go build -o bd.exe ./cmd/bd
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "go build failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$installDir = Join-Path $env:LOCALAPPDATA "Programs\bd"
|
||||
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
|
||||
|
||||
Copy-Item -Path (Join-Path $repoPath "bd.exe") -Destination (Join-Path $installDir "bd.exe") -Force
|
||||
Write-Success "bd installed to $installDir\bd.exe"
|
||||
|
||||
$pathEntries = [Environment]::GetEnvironmentVariable("PATH", "Process").Split([IO.Path]::PathSeparator) | ForEach-Object { $_.Trim() }
|
||||
if (-not ($pathEntries -contains $installDir)) {
|
||||
Write-WarningMsg "$installDir is not in your PATH. Add it with:`n setx PATH `"$Env:PATH;$installDir`""
|
||||
}
|
||||
} finally {
|
||||
Remove-Item -Path $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
function Verify-Install {
|
||||
Write-Info "Verifying installation..."
|
||||
try {
|
||||
$versionOutput = & bd version 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-WarningMsg "bd version exited with code $LASTEXITCODE"
|
||||
return $false
|
||||
}
|
||||
Write-Success "bd is installed: $versionOutput"
|
||||
return $true
|
||||
} catch {
|
||||
Write-WarningMsg "bd is not on PATH yet. Add the install directory to PATH and re-open your shell."
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
$goSupport = Test-GoSupport
|
||||
|
||||
if ($goSupport.Present) {
|
||||
Write-Info "Detected Go: $($goSupport.RawVersion)"
|
||||
} else {
|
||||
Write-WarningMsg "Go not found on PATH."
|
||||
}
|
||||
|
||||
$installed = $false
|
||||
|
||||
if ($goSupport.Present -and $goSupport.MeetsRequirement) {
|
||||
$installed = Install-WithGo
|
||||
if (-not $installed) {
|
||||
Write-WarningMsg "Falling back to source build..."
|
||||
}
|
||||
} elseif ($goSupport.Present -and -not $goSupport.MeetsRequirement) {
|
||||
Write-Err "Go 1.24 or newer is required (found: $($goSupport.RawVersion)). Please upgrade Go or use the fallback build."
|
||||
}
|
||||
|
||||
if (-not $installed) {
|
||||
$installed = Install-FromSource
|
||||
}
|
||||
|
||||
if ($installed) {
|
||||
Verify-Install | Out-Null
|
||||
Write-Success "Installation complete. Run 'bd quickstart' inside a repo to begin."
|
||||
} else {
|
||||
Write-Err "Installation failed. Please install Go 1.24+ and try again."
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user