Skip to content

Cache downloaded font archives to avoid re-downloading on retries and reruns #72

@MariusStorhaug

Description

Install-NerdFont deletes every downloaded archive immediately after extraction and again when the clean block runs. Any subsequent invocation — whether a retry after a partial failure, a reinstall with -Force, or a separate command targeting overlapping fonts — re-downloads the same multi-megabyte zips from GitHub Releases.

A small on-disk cache keyed by the release tag and asset filename eliminates the duplicate transfers and makes recovery from interrupted batches essentially free.

Request

Current experience

Every run starts from zero. A user who runs Install-NerdFont -All, hits a transient network error halfway through, and re-runs the command pays the full download cost again for every font.

Desired experience

Downloaded archives persist in a well-known cache directory. On the next invocation, if the cached file matches the expected URL/version, it is reused instead of re-fetched. The cache is opt-out, has a clear default location, and is bounded so it does not grow without limit.

Acceptance criteria

  • Successful downloads are saved into a cache directory tied to the Nerd Fonts release version
  • A second invocation that needs the same archive does not perform a network request
  • Cache lookup is keyed by URL (or release tag + filename), not just filename, so a future release that ships a same-named archive is not served stale content
  • A -NoCache switch (or -Force already implies cache bypass — see Technical decisions) is available to force a fresh download
  • The cache location is documented and discoverable via verbose output

Related


Technical decisions

Cache location: Under the platform-appropriate user cache directory:

  • Windows: $Env:LOCALAPPDATA\PSModule\NerdFonts\cache
  • Linux: $Env:XDG_CACHE_HOME ?? $HOME/.cache + /PSModule/NerdFonts
  • macOS: $HOME/Library/Caches/PSModule/NerdFonts

Cache key: <release-tag>/<asset-filename>. The release tag is already encoded in FontsData.json URLs (e.g. v3.4.0), so the cache key is derivable without an extra API call.

Validation: Before reuse, verify the cached file's size against the Content-Length of a cheap HEAD request, or simply trust the tagged path and rely on a successful extraction as the integrity check. The latter is simpler and adequate for GitHub Releases assets, which are immutable per tag.

Bypass: -Force already means "do work even if not needed"; reuse it to mean "ignore the cache and re-download". No new parameter is required for the first iteration; a dedicated -NoCache switch can be added later if needed.

Eviction: Out of scope for this issue — the cache grows monotonically. A follow-up can add LRU eviction or a Clear-NerdFontCache command if the directory becomes a problem in practice.


Implementation plan

  • Add a helper that computes the cache directory for the current platform and ensures it exists
  • Before downloading, check for <cacheDir>/<release-tag>/<asset-filename> and reuse it if present and -Force is not set
  • After a successful download, move the file from the per-run temp dir into the cache (or download directly into the cache)
  • Emit verbose output indicating cache hit vs. miss per font
  • Document the cache location in the function help
  • Add a Pester test asserting that a second invocation for the same font issues no Invoke-WebRequest call

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions