Class: Ucode::Fetch::SpecialistFontFetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/ucode/fetch/specialist_font_fetcher.rb

Overview

Concrete font fetcher: walks a Models::SpecialistFontManifest and materializes each font's path on disk.

Behavior (per acceptance in TODO 30):

  • Idempotent. A font whose path already exists with the manifest's SHA256 is :skipped. A file with a mismatched hash is re-downloaded.
  • Hashed. On download, SHA256 is computed. If the manifest has a hash, mismatch raises Ucode::FontChecksumError. If the manifest hash is null, the computed hash is written back to the YAML at the end of the run (atomic write).
  • License-checked. Non-OFL entries require allow_proprietary: true; otherwise the result is :failed with Ucode::FontLicenseError.
  • Extracted. extract: true entries unzip to a temp dir and only extract_member is moved into place.
  • Local-only. url: null entries are never fetched over the network; the result is :local whether or not the file is yet present (with a note instructing placement when missing).

A single font failure does not abort the run. The fetcher returns an array of FontFetcher::Result; the caller decides how to report failures.

Instance Method Summary collapse

Constructor Details

#initialize(manifest_path:, fonts_root: ".", allow_proprietary: false, dry_run: false, http: Fetch::Http) ⇒ SpecialistFontFetcher

Returns a new instance of SpecialistFontFetcher.

Parameters:

  • manifest_path (String, Pathname)

    path to the YAML manifest. The file is rewritten in place when SHA256 hashes are populated.

  • fonts_root (String, Pathname) (defaults to: ".")

    root for relative path: values. Defaults to the project root (current working dir). Absolute paths in the manifest bypass this.

  • allow_proprietary (Boolean) (defaults to: false)

    when true, non-OFL entries are fetched; when false, they produce a :failed result.

  • dry_run (Boolean) (defaults to: false)

    when true, no network or disk writes; each font that would have been fetched yields a :planned result.

  • http (Module, nil) (defaults to: Fetch::Http)

    injectable HTTP module responding to .get(url, dest:). Defaults to Http. Real-in-class test stubs can substitute a module that writes local fixture bytes; never use a double.



54
55
56
57
58
59
60
61
62
# File 'lib/ucode/fetch/specialist_font_fetcher.rb', line 54

def initialize(manifest_path:, fonts_root: ".", allow_proprietary: false,
               dry_run: false, http: Fetch::Http)
  @manifest_path = Pathname.new(manifest_path)
  @fonts_root = Pathname.new(fonts_root)
  @allow_proprietary = allow_proprietary
  @dry_run = dry_run
  @http = http
  @computed_hashes = {}
end

Instance Method Details

#call(only_label: nil) ⇒ Array<FontFetcher::Result>

Returns one per manifest entry actually visited, in declared order.

Parameters:

  • only_label (String, nil) (defaults to: nil)

    restrict the run to a single manifest entry by label. nil (default) = run all entries.

Returns:



68
69
70
71
72
73
74
75
76
# File 'lib/ucode/fetch/specialist_font_fetcher.rb', line 68

def call(only_label: nil)
  manifest = load_manifest
  return [unknown_label_result(only_label)] if only_label && manifest.find_by_label(only_label).nil?

  entries = only_label ? [manifest.find_by_label(only_label)] : manifest.fonts
  results = entries.map { |font| fetch_one(font) }
  persist_computed_hashes(manifest) unless @dry_run
  results
end