🚀 [Feature]: Install only the Nerd Font variants you need with faster reruns#77
Conversation
Closes #71. The progress bar adds per-byte rendering overhead that is especially expensive in non-interactive hosts. \Continue is saved and restored so the user's session is unaffected.
There was a problem hiding this comment.
Pull request overview
This PR currently implements a small Install-NerdFont download optimization by suppressing Invoke-WebRequest progress rendering, and adds a script for measuring install performance scenarios.
Changes:
- Suppresses PowerShell progress output during font archive downloads while restoring the previous preference afterward.
- Adds a performance measurement script for single-font, subset, already-installed, and optional full install scenarios.
- Ignores generated performance JSONL results.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/functions/public/Install-NerdFont.ps1 |
Wraps the download call with temporary progress suppression. |
scripts/Measure-InstallPerformance.ps1 |
Adds a benchmark helper for repeatable install timing scenarios. |
.gitignore |
Excludes generated performance result output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter POWERSHELL |
|
✅ New prerelease: PowerShell Gallery - NerdFonts 1.0.33-perfinstallimprovements001 |
|
✅ New prerelease: GitHub - NerdFonts v1.0.33-perfinstallimprovements001 |
Closes #74. Replaces `+=` array accumulation with a generic List and deduplicates overlapping wildcards via an OrdinalIgnoreCase HashSet, so each font is downloaded, extracted, and installed at most once per invocation. Install loop moves to `end` so pipeline input is fully resolved before any I/O. Also suppresses Write-Host / unused-parameter analyzer warnings in the perf measurement script.
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter POWERSHELL |
|
✅ New prerelease: PowerShell Gallery - NerdFonts 1.0.33-perfinstallimprovements002 |
|
✅ New prerelease: GitHub - NerdFonts v1.0.33-perfinstallimprovements002 |
Builds a HashSet of installed family names once per invocation. When -Force is not set, each font is checked against the set and skipped end-to-end (no download, no extract, no Install-Font call) if at least one installed family matches its base name. Wildcard match handles the multi-family layout of Nerd Fonts archives (e.g. 'Hack Nerd Font', 'Hack Nerd Font Mono'). Also restructure perf script call sites to splat (fixes PSUseConsistentIndentation).
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter POWERSHELL |
Previous HashSet[string] constructor crashed with ArgumentNullException on a fresh runner where Get-Font returns no items. Coerce to a real string[] (empty when no fonts) before passing to the ctor.
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter POWERSHELL |
|
✅ New prerelease: PowerShell Gallery - NerdFonts 1.0.33-perfinstallimprovements003 |
|
✅ New prerelease: GitHub - NerdFonts v1.0.33-perfinstallimprovements003 |
Replace Expand-Archive (which scans every entry through PowerShell and materializes file objects) with the direct .NET ZipFile.ExtractToDirectory call. Same behavior, much lower per-archive overhead.
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter POWERSHELL |
|
✅ New prerelease: PowerShell Gallery - NerdFonts 1.0.33-perfinstallimprovements004 |
|
✅ New prerelease: GitHub - NerdFonts v1.0.33-perfinstallimprovements004 |
…Parameters lint rule Switch from positional 'Join-Path \ '..' 'src' ...' to named 'Join-Path -Path \ -ChildPath ../src/FontsData.json' form. Restores UTF-8 BOM encoding for the test file.
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/functions/public/Install-NerdFont.ps1:330
- After
Install-Fontsucceeds, the function immediately runsRemove-Item -Path $extractPath -Force -Recursewithout guarding against non-critical failures. Under-ErrorAction Stop, an inability to delete the extracted directory (locked file, permissions, long path, etc.) can surface as a terminating error and make the overall install appear failed. Consider making this cleanup best-effort (non-terminating) and/or using-LiteralPathto avoid wildcard expansion edge cases.
if ($PSCmdlet.ShouldProcess("[$fontName] to [$Scope]", 'Install font')) {
Install-Font -Path $extractPath -Scope $Scope -Force:$Force
Remove-Item -Path $extractPath -Force -Recurse
}
…n Stop Use -LiteralPath and -ErrorAction SilentlyContinue for Remove-Item calls that clean up temporary zip files and extraction directories after install. Transient delete failures (file locks, AV scans) no longer terminate the command when callers use -ErrorAction Stop.
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
…state Prevents the catch block from accidentally targeting a temp path from a previous iteration if the current font fails before assigning the variable.
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
tests/NerdFonts.Tests.ps1:156
- Same as the Mono variant test: using
-Forcehere forces another full download of the Hack archive even though the test’sGet-Fontmock already prevents the installed-font skip. Removing-Forcelets the cache be reused across tests and keeps the suite faster/more reliable.
{ Install-NerdFont -Name 'Hack' -Variant Standard -Force -ErrorAction Stop } | Should -Not -Throw
Should -Invoke -ModuleName NerdFonts Install-Font -Times 1 -Exactly
tests/NerdFonts.Tests.ps1:193
- Same as the other variant tests:
-Forcebypasses cache reads and causes repeated downloads of the same archive across tests. SinceGet-Fontis mocked to return empty,-Forceisn’t required; removing it should reduce redundant network I/O and speed up CI runs.
{ Install-NerdFont -Name 'Hack' -Variant Propo -Force -ErrorAction Stop } | Should -Not -Throw
Should -Invoke -ModuleName NerdFonts Install-Font -Times 1 -Exactly
The variant tests mock Get-Font to return empty, so the installed-font skip check never triggers. -Force only served to bypass the cache, causing redundant HTTP downloads of the same Hack archive across three tests. Without -Force, the second and third variant tests reuse the cached archive, reducing CI time and transient download flakiness.
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
|
✅ New release: PowerShell Gallery - NerdFonts 1.1.0 |
|
✅ New release: GitHub - NerdFonts v1.1.0 |
Install-NerdFont can now install only the Nerd Font variants you want, reuse cached archives between runs, and skip work for fonts that are already present in the requested scope. Multi-font installs also finish faster because archive downloads are batched and extraction uses the underlying .NET zip APIs directly.
New: Install only the variants you need
Use
-Variantto limit each archive to the families you actually want to register. This is useful for terminal-focused setups where only the monospace family is needed.Allremains the default, so existing scripts keep the current behavior unless they opt intoStandard,Mono, orPropo.Changed: Repeated installs reuse prior work
When a font is already installed in the requested scope and
-Forceis not used,Install-NerdFontnow skips the download, extraction, and install phases for that font. Downloaded archives are cached per Nerd Fonts release, so retries and overlapping reruns can reuse the same zip instead of fetching it again.Changed: Multi-font installs complete faster
Bulk installs now resolve the target font set once, avoid duplicate work from overlapping name patterns, download archives in bounded batches, and extract them with
System.IO.Compression.ZipFile. The end result is less waiting during-Alland other multi-font runs without changing the default install surface.Technical Details
Install-NerdFontnow deduplicates the resolved font list, skips already-installed fonts without-Force, caches archives under the user cache directory, downloads uncached archives throughSystem.Net.Http.HttpClient, extracts withSystem.IO.Compression.ZipFile, and filters extracted files by-Variantbefore callingInstall-Font.tests/NerdFonts.Tests.ps1adds coverage for-Variant Monoinstalls.scripts/Measure-InstallPerformance.ps1adds repeatable performance scenarios for single-font, subset, rerun, and optional-Allmeasurements.README.mdnow documents variant installs, skip-on-rerun behavior, and cache bypass with-Force.