Skip to content

Latest commit

History

History
72 lines (57 loc) 路 6.35 KB

File metadata and controls

72 lines (57 loc) 路 6.35 KB

Agent Instructions for Homebrew/brew

Most importantly, run ./bin/brew lgtm (style checks, type checks and tests) to verify any file edits before prompting for input.

Inline any new or existing methods or variables used only once unless they are needed for unit tests. Keep the diff as small, DRY and YAGNI as possible. Re-read relevant files after each prompt and preserve user edits and comments. Before finishing, check your work and point out anything the user may not have considered.

This is a Ruby repository with Bash scripts for faster execution that provides the brew command for the Homebrew package manager.

Running Commands

  • Use ./bin/brew, never a system brew on PATH.
  • Never use the system Ruby; it is an incompatible older version. Run Ruby with ./bin/brew ruby -- <args> to load Homebrew's vendored Ruby and libraries.

Required Before Each Commit

  • ./bin/brew typecheck: Sorbet type checking. It only runs globally but is fast.
  • ./bin/brew style --fix --changed: RuboCop linting. Pass files to check them individually, e.g. ./bin/brew style --fix Library/Homebrew/cmd/reinstall.rb.
  • ./bin/brew tests --online --changed: RSpec tests. Online tests can be flaky, so ignore failures that pass on a rerun. Pass --only for individual files, e.g. ./bin/brew tests --only=cmd/reinstall runs Library/Homebrew/test/cmd/reinstall_spec.rb.
  • ./bin/brew lgtm --online runs all of the above in one command.
  • The Homebrew MCP Server (./bin/brew mcp-server) can also run all of the above.

Git

  • Inspect git diff and keep it focused.
  • Never commit to main. Branch from origin/HEAD with a relevant name without category prefixes such as fix/ or chore/, replacing any autogenerated branch name before its first commit.
  • Amend the existing commit for related fixes and update its message rather than adding a follow-up commit.
  • Use a commit subject under 51 characters without Conventional Commit prefixes such as feat:, fix: or chore:; the Commit Style GitHub Actions workflow rejects them. When a body is useful, use a dash list with lines under 73 characters focused on why and wrap filenames, code and identifiers in backticks. Pass multiline messages through git commit -F rather than literal \n.
  • Never add Co-Authored-By or other AI attribution trailers to commits or pull requests and never GPG-sign agent commits.
  • Fill in the pull request template from .github/PULL_REQUEST_TEMPLATE.md; never bypass it with e.g. gh pr create --fill.

Code

  • Maintain existing code structure and organisation and document public APIs.
  • Use Sorbet sig type signatures and typed: strict for new files.
  • Never use T.must (enforced by Sorbet/ForbidTMust): bind the value to a local and branch on nil, use fetch or first(n) on collections, or raise an exception with a helpful message where nil is impossible.
  • Never use T.unsafe (enforced by Sorbet/ForbidTUnsafe): give DSL parameters = nil defaults with nilable types, narrow with is_a? or case, use requires_ancestor for typed modules and public_send behind a respond_to? guard for duck typing.
  • Avoid T.cast, T.let, T.untyped and T.anything: use precise types and APIs that return non-nil values. If a generic top type is unavoidable, use T.anything rather than T.untyped.
  • Never use .send: call methods directly, use .public_send only for dynamically-named public methods and make private methods public in tests (enforced by Homebrew/NoSendInTests). In tests, read and write state through public attr_* accessors rather than instance_variable_get/instance_variable_set (enforced by Homebrew/NoInstanceVariableAccessInTests).
  • Shell out via HOMEBREW_BREW_FILE instead of requiring cmd/ or dev-cmd when composing brew commands.
  • Keep extend/os/* prepends thin: put the prepend in the OS-specific linux or macos file rather than the shared loader with an inline if, and put substantive logic in shared code outside extend/ so it is tested on all platforms rather than in :needs_linux or :needs_macos specs.
  • When Bash logic mirrors Ruby logic, keep both in sync with two-way comments naming the matching Ruby and Bash locations and keep matching helper filenames aligned.
  • Use &>/dev/null instead of >/dev/null 2>&1.
  • Put a comment immediately above each shellcheck disable explaining why it is needed.
  • Prefer self-documenting code through strings and variable names to new explanatory comments.
  • Use UK spelling and punctuation; avoid em dashes and Oxford commas.
  • Wrap human-written user-facing terminal output at around 80 characters; generated output and code are exempt.
  • Update docs/ when the behaviour it describes changes.

Tests

  • Write unit tests for new functionality. Try typed: strict first and revert to typed: true if the errors are not easily fixable; never use typed: false.
  • For bug fixes and regressions, use red-green TDD and change the fewest lines needed.
  • When adding or tightening tests, verify them with a red/green cycle using the exact --only=file:line target for the example you changed.
  • Use at most one :integration_test per command: a fast happy-path test. Add another only for essential core functionality in essential non-developer commands.
  • Use a single expect per unit test; combine expectations only in integration tests or when the before setup is non-trivial.
  • Formula classes created in specs may be frozen, so stub instances rather than class methods.
  • Library/Homebrew/test/spec_helper.rb snapshots and restores ENV around every example, so set environment variables directly without with_env or manual cleanup.

Repository Structure

  • bin/brew: Homebrew's brew command main Bash entry point script.
  • completions/ and manpages/: generated shell completions and man pages. Don't edit directly; regenerate with ./bin/brew generate-man-completions.
  • Library/Homebrew/: Homebrew's core Ruby (with a little Bash) logic.
  • Library/Homebrew/bundle/: Homebrew's brew bundle command.
  • Library/Homebrew/cask/: Homebrew's Cask classes and DSL.
  • Library/Homebrew/extend/os/: Homebrew's OS-specific (i.e. macOS or Linux) class extension logic.
  • Library/Homebrew/formula.rb: Homebrew's Formula class and DSL.
  • docs/: Documentation for Homebrew users, contributors and maintainers. Consult these for best practices and help.
  • package/: Files to generate the macOS .pkg file.