Skip to content

Commit fec1d0f

Browse files
committed
Enhance installation scripts with improved user experience and automation support
- Added environment variable support for non-interactive installations and dry runs - Introduced splash banner and tagline for better visibility during installation - Implemented checksum verification for downloaded binaries to ensure integrity - Improved output formatting and color handling based on terminal capabilities
1 parent 637f3d2 commit fec1d0f

2 files changed

Lines changed: 318 additions & 44 deletions

File tree

scripts/install.ps1

Lines changed: 147 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,39 @@
66
# # Or with a specific version:
77
# $env:FONTGET_VERSION="1.0.0"; irm https://raw.githubusercontent.com/Graphixa/FontGet/main/scripts/install.ps1 | iex
88
#
9+
# Environment:
10+
# FONTGET_VERSION Version or latest (default: latest)
11+
# FONTGET_NONINTERACTIVE=1 Skip "Continue?" (non-interactive install)
12+
# CI When non-empty, prompt is skipped (common on CI runners)
13+
# NO_COLOR=1 Disable ANSI colors / subdued styling where supported
14+
#
915

1016
# Set error handling
1117
$ErrorActionPreference = "Stop"
1218
$ProgressPreference = 'SilentlyContinue'
1319

20+
function Write-InstallDimLine {
21+
param([Parameter(Mandatory)][string]$Message)
22+
if ($env:NO_COLOR -eq '1') {
23+
Write-Host $Message
24+
} else {
25+
Write-Host $Message -ForegroundColor DarkGray
26+
}
27+
}
28+
29+
function Write-InstallOsLine {
30+
param([Parameter(Mandatory)][string]$OsName, [Parameter(Mandatory)][string]$ArchName)
31+
if ($env:NO_COLOR -eq '1') {
32+
Write-Host "OS: $OsName | ARCH: $ArchName"
33+
return
34+
}
35+
Write-Host -NoNewline -ForegroundColor Blue "OS: "
36+
Write-Host -NoNewline "$OsName "
37+
Write-Host -NoNewline -ForegroundColor Blue "| "
38+
Write-Host -NoNewline -ForegroundColor Blue "ARCH: "
39+
Write-Host $ArchName
40+
}
41+
1442
# Repository information
1543
$Repo = "Graphixa/FontGet"
1644
$RepoUrl = "https://github.com/$Repo"
@@ -34,14 +62,14 @@ if (-not $Version -or $Version -eq "") {
3462

3563
if ($Version -eq "latest") {
3664
$BaseUrl = "$RepoUrl/releases/latest/download"
37-
Write-Host "Installing latest version of FontGet..." -ForegroundColor Blue
3865
} else {
3966
# Remove 'v' prefix if present
4067
$Version = $Version -replace '^v', ''
4168
$BaseUrl = "$RepoUrl/releases/download/v$Version"
42-
Write-Host "Installing FontGet v$Version..." -ForegroundColor Blue
4369
}
4470

71+
$DisplayVersion = $Version
72+
4573
# Binary name (with .exe extension for Windows)
4674
$BinaryName = "fontget-windows-$Arch.exe"
4775
$DownloadUrl = "$BaseUrl/$BinaryName"
@@ -50,19 +78,93 @@ $DownloadUrl = "$BaseUrl/$BinaryName"
5078
$InstallDir = "$env:USERPROFILE\AppData\Local\Programs\FontGet"
5179
$InstalledBin = Join-Path $InstallDir "fontget.exe"
5280

53-
# Check if fontget is already installed
81+
# --- splash (default terminal foreground — no accent color on banner); aligned with install.sh ---
82+
$SplashBanner = @'
83+
84+
███████╗░█████╗░███╗░░██╗████████╗░██████╗░███████╗████████╗
85+
██╔════╝██╔══██╗████╗░██║╚══██╔══╝██╔════╝░██╔════╝╚══██╔══╝
86+
█████╗░░██║░░██║██╔██╗██║░░░██║░░░██║░░██╗░█████╗░░░░░██║░░░
87+
██╔══╝░░██║░░██║██║╚████║░░░██║░░░██║░░╚██╗██╔══╝░░░░░██║░░░
88+
██║░░░░░╚█████╔╝██║░╚███║░░░██║░░░╚██████╔╝███████╗░░░██║░░░
89+
╚═╝░░░░░░╚════╝░╚═╝░░╚══╝░░░╚═╝░░░░╚═════╝░╚══════╝░░░╚═╝░░░
90+
91+
'@
92+
Write-Host $SplashBanner
93+
94+
$Tagline = "Discover, install & manage fonts from the command line."
95+
$SplashW = 60
96+
if ($Tagline.Length -gt $SplashW) {
97+
Write-InstallDimLine $Tagline
98+
} else {
99+
$padL = [math]::Floor(($SplashW - $Tagline.Length) / 2)
100+
$padR = $SplashW - $Tagline.Length - $padL
101+
Write-InstallDimLine ((" " * $padL) + $Tagline + (" " * $padR))
102+
}
103+
Write-Host ""
104+
105+
Write-InstallOsLine -OsName "windows" -ArchName $Arch
106+
Write-Host ""
107+
108+
Write-Host "This will install FontGet $DisplayVersion to $InstalledBin"
109+
Write-Host ""
110+
111+
# Existing install notice before prompt (aligned with install.sh)
54112
if (Test-Path $InstalledBin) {
55113
try {
56114
$CurrentVersion = & $InstalledBin version 2>$null | Select-Object -First 1
57-
Write-Host "FontGet is already installed at: $InstalledBin" -ForegroundColor Yellow
58-
Write-Host "Current version: $CurrentVersion" -ForegroundColor Yellow
59-
Write-Host "This will be overwritten." -ForegroundColor Yellow
115+
if ($env:NO_COLOR -eq '1') {
116+
Write-Host "FontGet is already installed at: $InstalledBin"
117+
Write-Host "Current version: $CurrentVersion"
118+
Write-Host "This will be overwritten."
119+
} else {
120+
Write-Host "FontGet is already installed at: $InstalledBin" -ForegroundColor Yellow
121+
Write-Host "Current version: $CurrentVersion" -ForegroundColor Yellow
122+
Write-Host "This will be overwritten." -ForegroundColor Yellow
123+
}
60124
Write-Host ""
61125
} catch {
62126
# Ignore errors when checking version
63127
}
64128
}
65129

130+
# Continue prompt: only when interactive; CI / non-TTY / NONINTERACTIVE skip (aligned with install.sh)
131+
$ShouldPrompt = $true
132+
if ($env:FONTGET_NONINTERACTIVE -eq '1') {
133+
$ShouldPrompt = $false
134+
} elseif ($env:CI) {
135+
$ShouldPrompt = $false
136+
} else {
137+
try {
138+
if ([Console]::IsInputRedirected -or [Console]::IsOutputRedirected) {
139+
$ShouldPrompt = $false
140+
}
141+
} catch {
142+
$ShouldPrompt = $false
143+
}
144+
}
145+
146+
if ($ShouldPrompt) {
147+
Write-Host -NoNewline "Continue? [y/N] "
148+
try {
149+
$reply = [Console]::ReadLine()
150+
} catch {
151+
$reply = "n"
152+
}
153+
if ([string]::IsNullOrWhiteSpace($reply)) {
154+
$reply = "n"
155+
}
156+
$replyNorm = $reply.Trim().ToLowerInvariant()
157+
if ($replyNorm -ne "y" -and $replyNorm -ne "yes") {
158+
if ($env:NO_COLOR -eq '1') {
159+
Write-Host "Cancelled."
160+
} else {
161+
Write-Host "Cancelled." -ForegroundColor Yellow
162+
}
163+
exit 0
164+
}
165+
Write-Host ""
166+
}
167+
66168
# Create installation directory
67169
Write-Host "Creating installation directory..." -ForegroundColor Blue
68170
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
@@ -89,6 +191,45 @@ if (-not (Test-Path $TempFile)) {
89191
exit 1
90192
}
91193

194+
# Verify SHA256 against release checksums.txt (GoReleaser)
195+
$ChecksumsUrl = "$BaseUrl/checksums.txt"
196+
$ChecksumsTemp = Join-Path $env:TEMP "fontget-checksums-$Arch.txt"
197+
Write-Host "Downloading checksums..." -ForegroundColor Blue
198+
try {
199+
Invoke-WebRequest -Uri $ChecksumsUrl -OutFile $ChecksumsTemp -UseBasicParsing
200+
} catch {
201+
Write-Error "Failed to download checksums.txt"
202+
Remove-Item $TempFile -Force -ErrorAction SilentlyContinue
203+
exit 1
204+
}
205+
206+
$expectedHash = $null
207+
Get-Content -LiteralPath $ChecksumsTemp -ErrorAction SilentlyContinue | ForEach-Object {
208+
$line = $_.TrimEnd("`r")
209+
if ($line -match '^\s*([A-Fa-f0-9]{64})\s+[\*]?\s*(.+)$') {
210+
$name = $Matches[2].Trim()
211+
if ($name -eq $BinaryName) {
212+
$expectedHash = $Matches[1].ToLowerInvariant()
213+
}
214+
}
215+
}
216+
Remove-Item $ChecksumsTemp -Force -ErrorAction SilentlyContinue
217+
218+
if (-not $expectedHash) {
219+
Write-Error "No checksum line for $BinaryName in checksums.txt"
220+
Remove-Item $TempFile -Force -ErrorAction SilentlyContinue
221+
exit 1
222+
}
223+
224+
$actualHash = (Get-FileHash -LiteralPath $TempFile -Algorithm SHA256).Hash.ToLowerInvariant()
225+
if ($actualHash -ne $expectedHash) {
226+
Write-Error "Checksum mismatch for $BinaryName"
227+
Remove-Item $TempFile -Force -ErrorAction SilentlyContinue
228+
exit 1
229+
}
230+
231+
Write-Host "✓ Checksum verified" -ForegroundColor Green
232+
92233
# Verify binary works (basic check)
93234
try {
94235
$TestOutput = & $TempFile version 2>&1

0 commit comments

Comments
 (0)