Agents pkgmgr-homebrew-formula-dev
Create, test, and maintain Homebrew formulas. Use when adding packages to a Homebrew tap, debugging formula issues, running brew audit/test, or automating version updates with livecheck. Use when creating a new Homebrew formula for a project.
git clone https://github.com/aRustyDev/agents
T=$(mktemp -d) && git clone --depth=1 https://github.com/aRustyDev/agents "$T" && mkdir -p ~/.claude/skills && cp -r "$T/content/plugins/releases/homebrew-dev/skills/pkgmgr-homebrew-formula-dev" ~/.claude/skills/arustydev-agents-pkgmgr-homebrew-formula-dev && rm -rf "$T"
content/plugins/releases/homebrew-dev/skills/pkgmgr-homebrew-formula-dev/SKILL.mdHomebrew Formula Development
Guide for researching, creating, testing, and maintaining Homebrew formulas in a custom tap.
When to Use This Skill
- Creating a new Homebrew formula for a project
- Debugging formula build or test failures
- Running local validation before CI
- Understanding Homebrew's Ruby DSL
- Setting up livecheck for automatic version detection
Template Pipeline
This skill includes a JSON Schema → Mustache template pipeline for generating formulas from structured data.
Workflow
- Create a JSON file conforming to
scripts/formula.schema.ts - Run
to validate and renderjust template-formula <path-to-json> - The pipeline validates with AJV, preprocesses (PascalCase, language dispatch, license rendering), then renders via Mustache
Key Files
| File | Purpose |
|---|---|
| JSON Schema (draft-2020-12) defining formula structure |
| Preprocessing: PascalCase, license rendering, install flattening, partials loading |
| Main template — renders all shared fields, dispatches to language partials |
| Language-specific install partials (go, rust, python, zig, cmake, autotools, meson) |
| Test fixtures covering each scenario |
| Test cases that validate rendered output |
Running
# Render a formula from JSON just template-formula path/to/formula.json # Run all tests just test
Adding a New Language
- Add
definition toinstall-<lang>scripts/formula.schema.ts - Add language dispatch
entry in theallOf
definitionformula - Create
partialreference/templates/langs/<lang>.mustache - Add
to the"<lang>"
enumlanguage - Add a test fixture in
and test case intest/data/test/cases/
Research Phase
Before creating a formula, gather this information:
| Field | How to Find |
|---|---|
| Latest version | (404 → HEAD-only) |
| License | Check LICENSE file or repo metadata (use SPDX identifier) |
| Build system | Look at Makefile, go.mod, Cargo.toml, pyproject.toml, etc. |
| Dependencies | Check build docs, CI files, or dependency manifests |
| Default branch | Check repo settings — may be or |
| Binary name | May differ from formula name — check Cargo.toml , Go , or pyproject.toml |
Determine Formula Type
| Scenario | Type | Has /? | Has ? |
|---|---|---|---|
| Tagged releases | Standard | Yes | Yes |
| No releases | HEAD-only | No | No |
| Monorepo subdirectory | Standard | Yes | Yes |
Calculate SHA256
curl -sL "https://github.com/owner/repo/archive/refs/tags/vX.Y.Z.tar.gz" | shasum -a 256
Formula Naming
- Formula name: kebab-case (
,hex-patch
)jwt-ui - Class name: PascalCase (
,HexPatch
)JwtUi
Formula Structure
File Location
Formulas are organized alphabetically:
Formula/<first-letter>/<name>.rb
Key Elements
| Element | Purpose |
|---|---|
| Short description (~80 chars) for |
| Project homepage URL |
| Source tarball URL (omit for HEAD-only) |
| Checksum (omit for HEAD-only) |
| SPDX identifier |
| Git URL for installs |
| Auto-detect new versions (omit for HEAD-only) |
| Build or runtime dependencies |
| Verification block |
SPDX License Identifiers
| License | SPDX |
|---|---|
| MIT | |
| Apache 2.0 | |
| GPL 3.0 (only) | |
| GPL 3.0 (or later) | |
| BSD 2-Clause | |
| BSD 3-Clause | |
Always specify
-only or -or-later for GPL/LGPL/AGPL.
Language-Specific Patterns
Each language has a reference doc with install patterns, schema fields, and common issues:
- Go:
reference/langs/go.md - Rust:
reference/langs/rust.md - Python:
reference/langs/python.md
Additional languages supported by the template pipeline (cmake, autotools, meson, zig) — see their Mustache partials in
reference/templates/langs/.
Reference Materials
| Topic | Location |
|---|---|
| Local validation steps | |
| Common issues & FAQ | |
| Test block patterns | |
| Generated formula examples | |
| JSON Schema definition | |
| Bottle attestation & provenance | |
Batch Formula Creation
When creating many formulas at once:
- Compute SHA256 hashes in parallel — launch multiple
calls concurrentlycurl | shasum - Research build details in parallel — check build manifests concurrently
- Write all formula files — no dependencies between them
- Create branches/PRs sequentially — one branch per formula, each from main
- Use
to syntax-check all formulas before pushingruby -c *.rb
Architecture-Specific Binaries
When a project provides pre-built binaries for different architectures:
Preferred: Build from source (avoids architecture complexity)
If pre-built binaries required: Use resource blocks, NOT url/sha256 in on_arm/on_intel:
on_arm do resource "binary" do url "https://github.com/org/repo/releases/download/vX.Y.Z/tool-darwin-arm64.tar.gz" sha256 "..." end end on_intel do resource "binary" do url "https://github.com/org/repo/releases/download/vX.Y.Z/tool-darwin-amd64.tar.gz" sha256 "..." end end def install resource("binary").stage do bin.install "tool" end end
See
reference/faq/common.md for details on deprecated patterns.
Common Pitfalls
Dependency Issues
| Problem | Symptom | Solution |
|---|---|---|
| Missing runtime dependency | shows broken deps | Add dependency globally, not just in |
| Wrong dependency order | fails with ordering error | Build deps () before runtime deps, alphabetically within each |
| Rust + OpenSSL linkage | Linkage test shows broken | Add globally (not just Linux) if binary links dynamically |
Python Formula Issues
| Problem | Symptom | Solution |
|---|---|---|
missing deps | at runtime | Use to install from PyPI |
| PyPI name differs from repo | pip can't find package | Check for actual field (e.g., → ) |
| Missing setuptools | | Add before main package |
| Wrong pip invocation | | Use , not |
Test Block Issues
| Problem | Symptom | Solution |
|---|---|---|
| Binary name mismatch | Test can't find binary | Check or for actual name |
| Help text mismatch | fails | Run binary locally to verify actual output before writing test |
| Output to stderr | returns empty | Add redirect: |
See
reference/faq/common.md for detailed explanations and additional issues.
Checklist
- Research complete (version, license, build system, deps, binary name, default branch)
- Formula type determined (standard vs HEAD-only)
- SHA256 calculated (if not HEAD-only)
- Formula file created at
Formula/<letter>/<name>.rb -
passes (syntax check)ruby -c -
passesbrew audit --new -
passes (or issues addressed)brew style -
succeedsbrew install --build-from-source -
passesbrew test - Binary executes correctly
- PR created with CI passing