Convert from Homebrew Formulae to Casks for font installation

Formulae can't install to ~/Library/Fonts/ due to Homebrew sandboxing.
Casks have a built-in `font` artifact that handles this automatically.

- Replace Formula/ with Casks/ directory
- Rewrite generator to produce cask files instead of formulae
- Add .ttc (TrueType Collection) support
- Update all tests for cask format
- Update CLI and documentation
- Fonts with no installable files (TTF/OTF/TTC) are skipped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt Troutman 2026-03-07 21:38:59 -06:00
parent cb1918c30f
commit 76743cdc4d
No known key found for this signature in database
273 changed files with 2509 additions and 10048 deletions

View file

@ -1,4 +1,4 @@
"""add-font CLI: add or update a font in the tap, then run cleanup, generator, and tests."""
"""add-font CLI: add or update a font in the tap, then run cleanup, cask generator, and tests."""
import re
import shutil
import subprocess
@ -7,7 +7,7 @@ from pathlib import Path
def _repo_root() -> Path:
"""Repository root (directory containing font_files/ and Formula/)."""
"""Repository root (directory containing font_files/ and Casks/)."""
root = Path(__file__).resolve().parent.parent
assert (root / "font_files").exists(), f"Repo root not found: {root}"
return root
@ -44,7 +44,7 @@ def main() -> None:
import argparse
parser = argparse.ArgumentParser(
description="Add or update a font in the tap: run cleanup, generate formula, run tests."
description="Add or update a font in the tap: run cleanup, generate cask, run tests."
)
parser.add_argument(
"path_or_name",
@ -102,9 +102,9 @@ def main() -> None:
if _run([sys.executable, str(cleanup_script), "--path", font_files_abs]) != 0:
sys.exit(1)
# Run formula generator
formula_script = script_dir / "create_homebrew_formula.py"
if _run([sys.executable, str(formula_script)]) != 0:
# Run cask generator
cask_script = script_dir / "create_homebrew_formula.py"
if _run([sys.executable, str(cask_script)]) != 0:
sys.exit(1)
if not args.no_test:
@ -114,9 +114,9 @@ def main() -> None:
sys.exit(1)
if not args.no_audit:
formula_path = root / "Formula" / f"{font_name}.rb"
if formula_path.exists():
code = _run(["brew", "audit", "--formula", str(formula_path)])
cask_path = root / "Casks" / f"{font_name}.rb"
if cask_path.exists():
code = _run(["brew", "audit", "--cask", str(cask_path)])
if code != 0:
print("brew audit reported issues (non-fatal).", file=sys.stderr)