Current section
Files
Jump to
Current section
Files
priv/templates/install.ps1.eex
# <%= @app %> installer -- generated by tinfoil <%= @tinfoil_version %>
#
# Usage (in PowerShell):
# iex (irm <%= @raw_ps_url %>)
# iex "& { $(irm <%= @raw_ps_url %>) } -Version v1.2.3"
# iex "& { $(irm <%= @raw_ps_url %>) } -InstallDir 'C:\tools'"
#
# Or download and run manually:
# irm <%= @raw_ps_url %> -OutFile install.ps1
# .\install.ps1 -Version v1.2.3
[CmdletBinding()]
param(
[string]$Version = "",
[string]$InstallDir = ""
)
$ErrorActionPreference = "Stop"
$App = "<%= @app %>"
$Repo = "<%= @repo %>"
if (-not $InstallDir) {
$InstallDir = Join-Path $env:LOCALAPPDATA (Join-Path "Programs" $App)
}
# Expand a leading ~ the same way the bash installer does.
if ($InstallDir.StartsWith("~")) {
$InstallDir = $InstallDir.Substring(1)
if ($InstallDir.StartsWith("/") -or $InstallDir.StartsWith("\")) {
$InstallDir = $InstallDir.Substring(1)
}
$InstallDir = Join-Path $env:USERPROFILE $InstallDir
}
# Resolve the version: explicit -Version, or the latest release tag.
if (-not $Version) {
Write-Host "Resolving latest release..."
try {
$release = Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest"
$Version = $release.tag_name
}
catch {
throw "failed to determine latest release tag: $_"
}
}
# Normalize tag <-> version string.
$VersionNoV = $Version -replace '^v', ''
$Tag = if ($Version.StartsWith("v")) { $Version } else { "v$Version" }
$Triple = "x86_64-pc-windows-msvc"
$Archive = "$App-$VersionNoV-$Triple.zip"
$Base = "https://github.com/$Repo/releases/download/$Tag"
$Url = "$Base/$Archive"
$SumsUrl = "$Base/checksums-sha256.txt"
$Tmp = Join-Path $env:TEMP "$App-install-$(Get-Random)"
New-Item -ItemType Directory -Path $Tmp | Out-Null
try {
Write-Host "Downloading $Archive..."
$ArchivePath = Join-Path $Tmp $Archive
Invoke-WebRequest -Uri $Url -OutFile $ArchivePath -UseBasicParsing
Write-Host "Verifying checksum..."
$SumsPath = Join-Path $Tmp "checksums-sha256.txt"
try {
Invoke-WebRequest -Uri $SumsUrl -OutFile $SumsPath -UseBasicParsing
# Each line in checksums-sha256.txt is "<sha> <filename>" (two
# spaces). Match by suffix — PowerShell's -like uses * as wildcard,
# no regex escaping needed. Handle both " name" and " *name"
# (the binary-mode prefix some tools emit).
$line = Get-Content $SumsPath | Where-Object {
$_ -like "* $Archive" -or $_ -like "*`*$Archive"
} | Select-Object -First 1
if (-not $line) {
throw "no checksum entry for $Archive in checksums-sha256.txt"
}
# Split on any run of whitespace; first field is the sha.
$expected = ($line -split '\s+')[0]
$actual = (Get-FileHash -Path $ArchivePath -Algorithm SHA256).Hash.ToLower()
if ($expected -ne $actual) {
throw "checksum mismatch (expected $expected, got $actual)"
}
Write-Host "Checksum OK."
}
catch [System.Net.WebException] {
Write-Warning "checksums-sha256.txt not found; skipping verification"
}
Write-Host "Extracting..."
Expand-Archive -LiteralPath $ArchivePath -DestinationPath $Tmp -Force
if (-not (Test-Path $InstallDir)) {
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
}
$BinaryName = "$App.exe"
$SourceBin = Join-Path $Tmp $BinaryName
$DestBin = Join-Path $InstallDir $BinaryName
if (-not (Test-Path $SourceBin)) {
throw "archive did not contain $BinaryName"
}
Move-Item -Path $SourceBin -Destination $DestBin -Force
Write-Host ""
Write-Host "Installed $App $Version to $DestBin"
$pathDirs = $env:PATH -split ';'
if ($pathDirs -notcontains $InstallDir) {
Write-Host ""
Write-Host "note: $InstallDir is not on your PATH."
Write-Host " add it permanently via System Properties > Environment Variables,"
Write-Host " or for this session run:"
Write-Host " `$env:PATH = `"$InstallDir;`$env:PATH`""
}
}
finally {
Remove-Item -Recurse -Force $Tmp -ErrorAction SilentlyContinue
}