Skip to content

Resolve and deduplicate the font set once before processing #74

Description

Inside the process block, Install-NerdFont builds the install list with:

foreach ($fontName in $Name) {
    $nerdFontsToInstall += $script:NerdFonts | Where-Object { $_.Name -like $fontName }
}

Two small issues compound across larger inputs:

  1. += on an array allocates a new array on every iteration. For pipeline input or many -Name values this is O(n²).
  2. Overlapping wildcard patterns produce duplicates — e.g. Install-NerdFont -Name 'Fira*','FiraCode' queues FiraCode twice, doubling the download and extraction work for that font.

Neither issue is visible on tiny inputs, but together they meaningfully slow down -All-adjacent scenarios and waste bandwidth on overlap.

Request

Current experience

Repeated entries in -Name (or repeated pipeline objects) cause the same font to be downloaded, extracted, and installed multiple times in a single command. Building the list also scales quadratically.

Desired experience

The set of fonts to install is resolved once, deduplicated by name, and stored in an efficient collection before any I/O happens. Each font is processed at most once per invocation.

Acceptance criteria

  • The function emits exactly one set of download/extract/install operations per unique font, regardless of how many times the name matches via -Name or pipeline input
  • Building the install list is linear in the number of inputs
  • Verbose output reports the deduplicated count
  • Behavior of -All is unchanged (no duplicates exist in that path)

Technical decisions

Collection type: Use [System.Collections.Generic.List[object]] to accumulate matches without += reallocation, then project to a unique set keyed by Name.

Dedup key: Font Name is unique in FontsData.json and is a stable, case-insensitive identifier. Use Sort-Object -Unique -Property Name (simple and readable) or a HashSet[string] of seen names while iterating.

Place in the function: Resolution stays in the process block (so pipeline input continues to be supported), but the deduplicated set is materialized once before the per-font loop.


Implementation plan

  • Replace the += accumulator with [System.Collections.Generic.List[object]]::new() in src/functions/public/Install-NerdFont.ps1
  • After resolving matches, deduplicate by Name before entering the install loop
  • Update the existing verbose line "Installing [N] fonts" to reflect the deduplicated count
  • Add a Pester test that calls Install-NerdFont -Name 'Fira*','FiraCode' and asserts a single install for FiraCode

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions