AgentSkillsCN

homebrew-formula

创建、测试并维护 Homebrew 公式。当您向 Homebrew Tap 添加软件包、调试公式问题、运行 brew audit/test,或通过 livecheck 自动化版本更新时,均可使用此技能。

SKILL.md
--- frontmatter
name: homebrew-formula
description: 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.

Homebrew 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

Research Phase

Before creating a formula, gather this information:

Required Information

FieldHow to Find
Latest versiongh release view --repo owner/repo --json tagName
LicenseCheck LICENSE file or repo metadata (use SPDX identifier)
Build systemLook at Makefile, go.mod, Cargo.toml, package.json, etc.
DependenciesCheck build docs, CI files, or dependency manifests
Binary locationFor Go: check for cmd/ directory or main.go location

Calculate SHA256

Always calculate the checksum for the source tarball:

bash
curl -sL "https://github.com/owner/repo/archive/refs/tags/vX.Y.Z.tar.gz" | shasum -a 256

Formula Structure

File Location

Formulas are organized alphabetically: Formula/<first-letter>/<name>.rb

Example: Formula/m/mustache.rb

Template

See the slash command /add-homebrew-formula for a complete template, or reference existing formulas in Formula/ directory.

Key Elements

ElementPurpose
descShort description (~80 chars) for brew info
homepageProject's homepage URL
urlSource tarball URL (prefer source over pre-built binaries)
sha256Checksum for integrity verification
licenseSPDX identifier (MIT, Apache-2.0, GPL-3.0, etc.)
headGit URL for --HEAD installs
depends_onBuild or runtime dependencies
testVerification block that proves the install works

Language-Specific Patterns

Go Projects:

text
depends_on "go" => :build

def install
  system "go", "build", *std_go_args(ldflags: "-s -w"), "./cmd/binary"
end

Rust Projects:

text
depends_on "rust" => :build

def install
  system "cargo", "install", *std_cargo_args
end

Local Validation

Step 1: Sync to Tap Location

Formula files must be in the Homebrew tap location for testing:

bash
mkdir -p /usr/local/Homebrew/Library/Taps/arustydev/homebrew-tap/Formula/<letter>/
cp Formula/<letter>/<name>.rb /usr/local/Homebrew/Library/Taps/arustydev/homebrew-tap/Formula/<letter>/
chmod a+r /usr/local/Homebrew/Library/Taps/arustydev/homebrew-tap/Formula/<letter>/<name>.rb

Step 2: Run Audit

bash
brew audit --new --formula arustydev/tap/<name>

This checks for common formula issues but NOT style violations.

Step 3: Run CI Syntax Check (Critical)

bash
brew test-bot --only-tap-syntax

This runs brew style (rubocop) against ALL files in the tap - same as CI. This catches issues that brew audit misses.

Step 4: Test Installation

bash
brew install --build-from-source arustydev/tap/<name>

Step 5: Run Formula Tests

bash
brew test arustydev/tap/<name>

Step 6: Verify Binary

bash
<name> --help

Version Updates with Livecheck

Homebrew's livecheck automatically detects new versions from the formula's URL pattern. No manual version registry needed.

Test livecheck:

bash
brew livecheck arustydev/tap/<name>

Common Issues

CI Failures from Rubocop

Problem: brew test-bot --only-tap-syntax fails on markdown files containing Ruby code blocks.

Cause: brew style uses rubocop-md which lints code fenced as ruby in markdown files. The tap's .rubocop.yml exclusions do NOT apply - brew style uses Homebrew's central config.

Solution: Use text instead of ruby for code fence language in any markdown documentation.

Line Length Errors

Problem: Lines longer than 118 characters.

Solution: Split long strings or use Homebrew's allowed patterns (URLs, sha256 lines, etc. are exempt).

Test Block Failures

Problem: Formula installs but brew test fails.

Solution: Ensure test block creates necessary test files and uses proper paths:

text
test do
  (testpath/"input.txt").write("test content")
  output = shell_output("#{bin}/tool #{testpath}/input.txt")
  assert_equal "expected", output.strip
end

Checklist

  • Research complete (version, license, build system, deps)
  • SHA256 calculated for source tarball
  • Formula file created at Formula/<letter>/<name>.rb
  • brew audit --new passes
  • brew test-bot --only-tap-syntax passes
  • brew install --build-from-source succeeds
  • brew test passes
  • Binary executes correctly
  • Feature branch created and committed
  • PR created with CI passing

References