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
3563if ($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)
54112if (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
67169Write-Host " Creating installation directory..." - ForegroundColor Blue
68170New-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)
93234try {
94235 $TestOutput = & $TempFile version 2>&1
0 commit comments