Skip to main content

Add A Homebrew Package

Homebrew packages are managed declaratively. The deployed ~/.Brewfile is a single file, but in the chezmoi source it is split into per-category partials (brews/NN-<category>.brewfile) under home/.chezmoitemplates/brews/ so it stays explorable.

File roles:

File / conventionRole
brews/_assemble.brewfileindex of category banners and includeTemplate calls
home/readonly_dot_Brewfile.tmplrenders the assembler into ~/.Brewfile

Preconditionsโ€‹

  • You know whether the package is a formula or cask.
  • You verified the package name with:
brew info <formula-or-cask>

Stepsโ€‹

  1. Pick the category, then edit the matching partial under home/.chezmoitemplates/brews/: brews/NN-<category>.brewfile.

  2. Add the entry (brew "<formula>" or cask "<cask>", with its comment/URL) to that file.

    Non-official taps are declared as tap "<owner>/<tap>", trusted: true next to the entry that needs them. brew bundle writes that into Homebrew's trust store (~/.config/homebrew/trust.json) before loading any formula, so no brew trust run and no HOMEBREW_NO_REQUIRE_TAP_TRUST override is needed for declared taps. The apply hook trusts only retired taps, so it can untap them.

    If the category file does not exist yet:

    StepDetail
    Create partialuse the next free NN-<category> ordinal+slug
    Wire assembleradd {{ includeTemplate "brews/NN-<category>.brewfile" . }} to brews/_assemble.brewfile
  3. Apply:

chezmoi apply

The brew hook is:

It first trusts and force-untaps every tap that brew bundle cleanup --global reports as "Would untap" (cleanup resets brew trust before it untaps, so a tap with installed formulae would fail as untrusted). brew untap --force also uninstalls every formula and cask installed from that tap, including ones with keepme refs; the later brew bundle reinstalls listed names from core. It then runs brew bundle cleanup --global --force and brew bundle --global --no-upgrade, so the assembled Brewfile is the source-of-truth (anything not listed is uninstalled). Its run_onchange hash is computed from the rendered assembler, so editing any partial re-triggers the hook.

Verificationโ€‹

brew bundle check --global
brew list | rg '<formula-or-cask>'

If something unexpected changed:

chezmoi diff

Rollback / Undoโ€‹

  1. Remove the package entry from its home/.chezmoitemplates/brews/NN-<category>.brewfile partial.
  2. Re-apply:
chezmoi apply