馃 [Fix]: Font installs handle variants and interrupted downloads - #100
馃 [Fix]: Font installs handle variants and interrupted downloads#100Marius Storhaug (MariusStorhaug) wants to merge 16 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors Install-NerdFont to better handle Nerd Font variants (Standard/Mono/Propo), improve resiliency when downloads/extraction fail, and reduce unnecessary side effects during -WhatIf. It also introduces a reusable, streaming download implementation with core-bounded concurrency and standardizes cache locations on macOS/Linux.
Changes:
- Update
Install-NerdFontto (a) skip only when the requested variant is already installed, (b) guard cache copy + downloads behindShouldProcess(keeping-WhatIfside-effect free), and (c) continue installation when extraction fails for a single archive. - Add private helpers to stream downloads to disk with retries (
Invoke-/Start-/Receive-NerdFontDownload), plus core-bounded runspace pooling and a sharedHttpClient. - Update tests/docs for new cache root behavior and add a performance measurement script (with
.gitignoreentry for results output).
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/NerdFonts.Tests.ps1 | Expands coverage for streaming downloads, core-bounded concurrency, variant-aware install skipping, -Force, -WhatIf, dedupe, and extraction-failure continuation. |
| src/functions/public/Install-NerdFont.ps1 | Variant-aware installed checks, ShouldProcess-guarded cache/download ops, streaming download workflow, runspace concurrency, and improved extraction error handling. |
| src/functions/private/Start-NerdFontDownload.ps1 | Adds async/sync wrapper for invoking streaming download logic. |
| src/functions/private/Receive-NerdFontDownload.ps1 | Adds completion/cleanup helper for async download operations. |
| src/functions/private/New-NerdFontHttpClient.ps1 | Creates shared HttpClient with connection pooling knobs. |
| src/functions/private/New-NerdFontDownloadRunspacePool.ps1 | Creates a bounded runspace pool that can invoke the download helper concurrently. |
| src/functions/private/Invoke-NerdFontDownload.ps1 | Implements streaming download-to-disk with retries + atomic temp-file move. |
| src/functions/private/Get-NerdFontCacheRoot.ps1 | Centralizes platform-standard cache root selection (macOS + XDG). |
| scripts/Measure-InstallPerformance.ps1 | Adds a scriptable harness for measuring install scenarios and writing JSONL results. |
| README.md | Documents updated cache locations and how to compute them at runtime. |
| .gitignore | Ignores generated performance results file. |
馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/functions/public/Install-NerdFont.ps1:220
- When a cached archive exists and the user declines the "Copy cached archive" ShouldProcess prompt (e.g., via -Confirm), the function currently
continues and skips the font entirely, never reaching the separate "Download archive" ShouldProcess prompt. This makes a "no" to cache-copy implicitly mean "no" to downloading, which is unexpected (and differs from the fallback behavior used when cache-copy throws).
Write-Warning "[$fontName] - Cache read failed, falling back to download: $($_.Exception.Message)"
}
} else {
continue
}
Font installation now recognizes the requested Standard, Mono, or Propo variant before skipping a family, keeps
-WhatIffree of archive copies and network activity, and continues when an archive cannot be installed. Downloads stream directly to disk and scale concurrent work to the machine's available processor cores.Fixed: Safer installation and archive handling
An installed standard or proportional family no longer prevents a missing Mono variant from being installed.
-Forcecontinues to download and install a requested family, while overlapping wildcard and exact names process a matching archive only once.Archive downloads retry transient failures and enter the local cache only after extraction succeeds. A corrupt archive now reports its font-specific error and allows the remaining requested fonts to continue.
Changed: Platform-standard cache locations
macOS now uses
~/Library/Caches/PSModule/NerdFonts. Linux honorsXDG_CACHE_HOMEand otherwise continues to use~/.cache/PSModule/NerdFonts.Technical details
HttpClientand queue in aRunspacePoolcapped at[System.Environment]::ProcessorCount.SocketsHttpHandlerconnection pooling, core-bounded connections per server, and a 15-minute pooled-connection lifetime. Downloads retainResponseHeadersRead,FileStream,CopyToAsync, atomic temporary files, a per-attempt cancellation deadline, and the existing transient retry policy.ShouldProcess; filtering, deduplication, and installation run only after successful extraction.-Allresults are partial because both runs stop on pre-existing cross-archive font-file collisions.src/functions/**(PowerShell)tests/**(Pester)scripts/**(PowerShell)README.md.gitignoreRelevant issues (or links)