# Skeg installer for Windows — irm https://skeg.dev/install.ps1 | iex # Env: SKEG_VERSION · SKEG_DOWNLOAD_BASE · SKEG_INSTALL_DIR · SKEG_SHA256 · SKEG_SKIP_VERIFY=1 # Integrity: the download is checked against the release's signed SHA256SUMS by default. $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest $version = if ($env:SKEG_VERSION) { $env:SKEG_VERSION } else { 'latest' } $base = if ($env:SKEG_DOWNLOAD_BASE) { $env:SKEG_DOWNLOAD_BASE } else { 'https://github.com/skeg-dev/skeg/releases' } $arch = switch ($env:PROCESSOR_ARCHITECTURE) { 'AMD64' { 'amd64' } 'ARM64' { 'arm64' } default { throw "skeg: unsupported architecture $($env:PROCESSOR_ARCHITECTURE)" } } $name = "skeg-windows-$arch.exe" $url = if ($version -eq 'latest') { "$base/latest/download/$name" } else { "$base/download/$version/$name" } # Per-user by default: no administrator rights needed, which is how a developer tool should install. $dir = if ($env:SKEG_INSTALL_DIR) { $env:SKEG_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'Programs\skeg' } New-Item -ItemType Directory -Force -Path $dir | Out-Null $tmp = Join-Path $env:TEMP "skeg-$([guid]::NewGuid()).exe" Write-Host "skeg: downloading $url" try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri $url -OutFile $tmp -UseBasicParsing } catch { Write-Host "skeg: download failed. If the release is not published yet, request access at" Write-Host " https://skeg.dev/feedback, or set SKEG_DOWNLOAD_BASE to a location serving the binary." exit 1 } if ((Get-Item $tmp).Length -eq 0) { Remove-Item $tmp -Force; throw 'skeg: downloaded file is empty' } $have = (Get-FileHash -Algorithm SHA256 -Path $tmp).Hash.ToLower() if ($env:SKEG_SHA256) { if ($have -ne $env:SKEG_SHA256.ToLower()) { Remove-Item $tmp -Force; throw 'skeg: checksum mismatch — refusing to install' } Write-Host 'skeg: checksum verified (pinned)' } elseif ($env:SKEG_SKIP_VERIFY -eq '1') { Write-Host 'skeg: WARNING integrity check skipped at your request' } else { $sumsUrl = if ($version -eq 'latest') { "$base/latest/download/SHA256SUMS" } else { "$base/download/$version/SHA256SUMS" } $sums = $null try { $sums = (Invoke-WebRequest -Uri $sumsUrl -UseBasicParsing).Content } catch { } if (-not $sums) { Remove-Item $tmp -Force Write-Host 'skeg: could not fetch SHA256SUMS — refusing to install unattested binary.' Write-Host ' Request access at https://skeg.dev/feedback, or pin a build with $env:SKEG_SHA256.' exit 1 } $want = ($sums -split "`n" | Where-Object { $_ -match [regex]::Escape($name) } | Select-Object -First 1) -split '\s+' | Select-Object -First 1 if (-not $want) { Remove-Item $tmp -Force; throw "skeg: $name is not listed in SHA256SUMS — refusing to install" } if ($have -ne $want.ToLower()) { Remove-Item $tmp -Force; throw 'skeg: checksum mismatch against the published SHA256SUMS — refusing to install' } Write-Host 'skeg: checksum verified against the published SHA256SUMS' } $target = Join-Path $dir 'skeg.exe' Move-Item -Force $tmp $target Write-Host "skeg: installed $target" # Put it on PATH for this user, and for this session, so the next command just works. $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') if ($userPath -notlike "*$dir*") { [Environment]::SetEnvironmentVariable('Path', "$userPath;$dir", 'User') Write-Host "skeg: added $dir to your user PATH (new terminals will pick it up)" } $env:Path = "$env:Path;$dir" & $target version Write-Host "" Write-Host "next:" Write-Host " cd ; skeg try # adds the template, runs a security baseline (undo with: skeg undo)" Write-Host " skeg # where you are and the one next step" Write-Host " skeg feedback bug `"...`" # tell us what to fix"