Install

Homebrew/brew

Homebrew Package Manager

Last updated on Dec 18, 2025 (Commit: 0ff3a70)

Overview

Relevant Files
  • README.md
  • AGENTS.md
  • bin/brew
  • Library/Homebrew/brew.rb
  • Library/Homebrew/

Homebrew is a free and open-source package manager for macOS and Linux. This repository contains the core brew command implementation and the infrastructure that powers package management across both platforms. The project is maintained by a community of volunteers and is fiscally hosted by the Open Source Collective.

Purpose and Scope

The Homebrew/brew repository is the central hub for the package manager's command-line interface and core logic. It provides:

  • Package Installation & Management - Install, update, remove, and manage software packages (formulae) and applications (casks)
  • Dependency Resolution - Automatically handle complex dependency chains across packages
  • Cross-Platform Support - Native support for macOS and Linux with OS-specific optimizations
  • Bundle Management - Manage collections of packages via Brewfiles (similar to package.json or Gemfile)
  • Development Tools - Extensive tooling for package maintainers and contributors

Architecture Overview

Loading diagram...

Repository Structure

  • bin/brew - Bash entry point script that validates environment and bootstraps the Ruby runtime
  • Library/Homebrew/ - Core Ruby implementation containing all package management logic
    • cmd/ - Individual command implementations (install, update, list, etc.)
    • cask/ - macOS application (cask) management system
    • bundle/ - Brewfile and dependency bundle handling
    • formula.rb - Formula class and DSL for package definitions
    • test/ - Comprehensive RSpec test suite
  • docs/ - User and contributor documentation
  • completions/ - Shell completion files (bash, fish, zsh)
  • manpages/ - Generated man page documentation

Technology Stack

  • Ruby - Primary implementation language with Sorbet type checking
  • Bash - Entry point and performance-critical scripts
  • RSpec - Unit testing framework
  • RuboCop - Code linting and style enforcement

Key Development Practices

Before committing code, contributors must:

  1. Run brew typecheck to verify Sorbet type signatures
  2. Run brew style --fix --changed to lint and format code
  3. Run brew tests --online --changed to ensure tests pass

All code uses Sorbet sig type signatures and typed: strict declarations for type safety. Tests follow a single-assertion pattern and avoid multiple integration tests per file for performance.

Architecture & Core Systems

Relevant Files
  • Library/Homebrew/abstract_command.rb
  • Library/Homebrew/commands.rb
  • Library/Homebrew/cli/parser.rb
  • Library/Homebrew/formula.rb
  • Library/Homebrew/cask/cask.rb
  • Library/Homebrew/formulary.rb
  • Library/Homebrew/brew.rb

Command Execution Architecture

Homebrew's command system is built on a modular, extensible foundation. Commands are discovered, routed, and executed through a well-defined pipeline:

  1. Command Discovery (commands.rb): The Commands module manages command resolution by checking multiple sources in order:

    • Internal commands in Library/Homebrew/cmd/
    • Developer commands in Library/Homebrew/dev-cmd/
    • External commands from taps (third-party repositories)
    • Command aliases (e.g., lslist)
  2. Command Routing (brew.rb): The main entry point parses arguments, identifies the command, and routes execution. It handles help flags, command aliases, and determines whether to run internal Ruby commands or external shell commands.

  3. AbstractCommand Pattern (abstract_command.rb): Modern commands subclass AbstractCommand, providing:

    • Isolated namespaces for each command
    • Automatic argument parsing via CLI::Parser
    • Type-safe argument handling with Sorbet
    • Consistent run method interface

Package Management Abstractions

Homebrew manages two primary package types through parallel abstraction layers:

Formula (formula.rb): Represents source-based packages. Each formula is a Ruby class defining:

  • Download URLs and checksums
  • Build dependencies and requirements
  • Installation and testing procedures
  • Metadata (homepage, description, license)

Cask (cask/cask.rb): Represents macOS GUI applications. Casks define:

  • Application artifacts (.app bundles, preference panes, etc.)
  • Installation and uninstallation procedures
  • Metadata and versioning

Factory Pattern for Package Loading

Formulary (formulary.rb) and CaskLoader (cask/cask_loader.rb) implement sophisticated factory patterns:

  • Multiple Loaders: Try different sources in order (API, taps, cache, paths)
  • Lazy Loading: Formulas can be loaded from stubs or full definitions
  • Caching: Platform-specific caches prevent redundant loading
  • API Integration: Formulas can be loaded from Homebrew's JSON API
# Example: Loading a formula
formula = Formulary.factory("wget")
# Tries: API → Tap → Path → Cache → Keg

CLI Argument Parsing

CLI::Parser (cli/parser.rb) provides declarative argument definition:

class MyCommand < AbstractCommand
  cmd_args do
    description "My command description"
    flag "--option=", description: "An option"
    named_args :formula, min: 1
  end
end

The parser generates type-safe argument objects, validates constraints, and handles help text generation automatically.

Data Flow Diagram

Loading diagram...

Command Dispatch & CLI

Relevant Files
  • bin/brew
  • Library/Homebrew/brew.rb
  • Library/Homebrew/abstract_command.rb
  • Library/Homebrew/cli/parser.rb
  • Library/Homebrew/commands.rb

Overview

Homebrew's command dispatch system routes user input from the brew command through multiple layers: a Bash entry point, Ruby initialization, command resolution, and finally execution. The system supports three command types: internal Ruby commands, external Ruby commands, and external shell commands.

Loading diagram...

Entry Point: bin/brew

The bin/brew Bash script is the user-facing entry point. It performs critical setup:

  1. Environment validation – Ensures Bash, $PWD, and $HOME are set
  2. Path resolution – Locates the Homebrew installation directory by resolving symlinks
  3. Environment configuration – Loads configuration from /etc/homebrew/brew.env, prefix config, and user config (~/.homebrew/brew.env)
  4. Environment filtering – Restricts the environment to a whitelist of safe variables (PATH, HOME, SHELL, etc.) to prevent user environment pollution
  5. Ruby invocation – Executes Library/Homebrew/brew.sh with a filtered environment

Command Resolution: brew.rb

Library/Homebrew/brew.rb is the main Ruby entry point. It:

  1. Parses arguments – Extracts the command name and help flags from ARGV
  2. Resolves aliases – Maps command aliases (e.g., lslist) using HOMEBREW_INTERNAL_COMMAND_ALIASES
  3. Determines command type – Checks if the command is internal, external Ruby, or external shell
  4. Loads and executes – Instantiates the command class or execs the external process
  5. Handles errors – Catches exceptions and provides helpful error messages with debugging info

Command Types

Internal Commands (Library/Homebrew/cmd/*.rb or .sh)

  • Subclass AbstractCommand and implement a run method
  • Parsed by CLI::Parser for argument validation
  • Executed in-process with full access to Homebrew's Ruby environment
  • Examples: install, update, list

External Ruby Commands (Tap cmd/*.rb)

  • Located in tap directories: HOMEBREW_TAP_DIRECTORY/*/*/cmd/*.rb
  • Can be required without being run (v2 commands) or run by requiring (v1 commands)
  • Discovered via Commands.external_ruby_v2_cmd_path or Commands.external_ruby_cmd_path
  • Useful for extending Homebrew with custom logic

External Shell Commands (Tap brew-* executables)

  • Named brew-<command> and placed in PATH or tap directories
  • Executed via exec, replacing the current process
  • Lowest-level extension mechanism; can be any executable

AbstractCommand Pattern

New commands should subclass AbstractCommand:

module Homebrew
  module Cmd
    class InstallCmd < AbstractCommand
      cmd_args do
        description "Install a formula or cask"
        switch "--HEAD", description: "Install from HEAD"
        named_args :formula, min: 1
      end

      sig { override.void }
      def run
        args.named.each { |formula| install_formula(formula) }
      end
    end
  end
end

The cmd_args block defines the command's CLI interface. Arguments are automatically parsed and available via @args.

CLI Parsing

CLI::Parser uses Ruby's OptionParser to validate and parse arguments. It:

  • Defines switches (flags), options (with values), and named arguments
  • Generates type-safe argument classes via Sorbet
  • Supports environment variable defaults, conflicts, and dependencies
  • Produces CLI::Args objects with validated, type-checked attributes

Command Discovery

Commands module provides utilities for discovering and managing commands:

  • Commands.path(cmd) – Resolves a command name to its file path (checks aliases, internal, external)
  • Commands.internal_commands – Lists all built-in commands
  • Commands.external_commands – Lists all tap-provided commands
  • Commands.command_options(cmd) – Extracts CLI options for a command

Formula System & Package Definitions

Relevant Files
  • Library/Homebrew/formula.rb
  • Library/Homebrew/software_spec.rb
  • Library/Homebrew/formulary.rb
  • Library/Homebrew/api/formula.rb
  • Library/Homebrew/api/formula_struct.rb

Overview

A Formula is the core abstraction in Homebrew that describes how to install a piece of software. Every formula is a Ruby class that inherits from Formula and defines metadata (homepage, version, dependencies) and build instructions. The Formulary is the factory responsible for loading and instantiating formulas from various sources, while SoftwareSpec encapsulates version-specific installation details.

Core Components

Formula Class

The Formula class is the base for all package definitions. Each formula:

  • Defines a single software package with metadata like homepage, url, and sha256
  • Contains build logic in the install method
  • Specifies dependencies via depends_on
  • Supports multiple versions through specs (stable and HEAD)
class Wget < Formula
  homepage "https://www.gnu.org/software/wget/"
  url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
  sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"

  def install
    system "./configure", "--prefix=#{prefix}"
    system "make", "install"
  end
end

SoftwareSpec

SoftwareSpec encapsulates version-specific metadata for a formula. Each formula has two specs:

  • Stable: The default, released version with a URL and checksum
  • HEAD: Development version from version control (installed with --HEAD)

Specs contain:

  • Download URL and strategy (:git, :curl, etc.)
  • Version and checksum
  • Dependencies and patches specific to that version
  • Build options and compiler requirements

Formulary & Formula Loading

The Formulary module implements a strategy pattern for loading formulas from multiple sources. It tries loaders in this order:

  1. FromBottleLoader – Pre-compiled binary packages
  2. FromURILoader – Remote formula files via HTTP
  3. FromAPILoader – JSON API (fast, no Ruby evaluation)
  4. FromTapLoader – Tapped repositories
  5. FromPathLoader – Local filesystem paths
  6. FromNameLoader – Formula names (searches all taps)
  7. FromKegLoader – Installed keg metadata
  8. FromCacheLoader – Cached formula files
  9. NullLoader – Raises error if not found
Loading diagram...

API-Based Loading

The FromAPILoader loads formulas from JSON without evaluating Ruby code, improving performance. The Homebrew::API::Formula module:

  • Fetches formula metadata from formula.jws.json
  • Generates FormulaStruct objects with all formula attributes
  • Dynamically creates Formula classes from JSON data

This enables fast formula resolution without parsing Ruby files.

Factory Caching

Formulary maintains a platform-specific cache to avoid reloading the same formula:

  • Cache key: "#{ref}-#{spec}-#{alias_path}-#{from}-#{prefer_stub}"
  • Enabled via Formulary.enable_factory_cache!
  • Separate caches for API, path, and stub sources

Key Workflows

Installing a formula:

  1. User runs brew install wget
  2. Formulary.factory("wget") determines the best loader
  3. Loader returns a Formula instance
  4. Formula's install method is executed in a staging directory

Spec selection:

  • Default: stable spec (released version)
  • With --HEAD: HEAD spec (development version)
  • Formula determines active spec via active_spec_sym

Cask System & GUI Applications

Relevant Files
  • Library/Homebrew/cask/cask.rb
  • Library/Homebrew/cask/dsl.rb
  • Library/Homebrew/cask/installer.rb
  • Library/Homebrew/cask/artifact.rb
  • Library/Homebrew/cask/artifact/abstract_artifact.rb

Homebrew's Cask system extends package management beyond command-line tools to GUI applications and other macOS-specific software. Unlike formulas (which compile from source), casks install pre-built binaries, applications, and system extensions.

Core Architecture

The Cask system consists of three main components:

  1. Cask Definition (Cask class) — Represents a single installable application with metadata (token, version, URL, SHA256, dependencies)
  2. DSL (DSL class) — Domain-specific language for defining cask stanzas (app, binary, font, pkg, etc.)
  3. Installer (Installer class) — Orchestrates the download, staging, and installation lifecycle
cask "example-app" do
  version "1.0"
  sha256 "abc123..."
  url "https://example.com/app.dmg"
  app "Example.app"
  binary "Example.app/Contents/MacOS/example"
end

Artifact System

Artifacts are the core abstraction for what gets installed. Each artifact type handles a specific installation target:

Moved Artifacts (copy to destination):

  • app — macOS applications
  • font — System fonts
  • dictionary — Dictionary files
  • artifact — Generic files with custom targets

Symlinked Artifacts (link to destination):

  • binary — Executables (symlinked to binarydir)
  • manpage — Manual pages

System Extensions (macOS-specific):

  • pkg — Installer packages
  • installer — Manual or script-based installers
  • prefpane — System preference panes
  • qlplugin — Quick Look plugins
  • service — LaunchAgent/LaunchDaemon services
  • vst_plugin, vst3_plugin — Audio plugins
  • audio_unit_plugin, input_method, keyboard_layout — System plugins

Special Artifacts:

  • preflight / postflight — Ruby blocks executed before/after installation
  • uninstall_preflight / uninstall_postflight — Ruby blocks for uninstallation
  • stage_only — Extract but don't install (useful for dependencies)
  • zap — Deep cleanup stanza for complete removal

Installation Lifecycle

The installer follows a strict sequence:

prelude → caveats → fetch → stage → install_artifacts → save_metadata

Fetch Phase: Download and verify the cask file, check requirements and dependencies.

Stage Phase: Extract the downloaded archive to a temporary staging directory, process any rename operations, and save the caskfile for later reference.

Install Artifacts Phase: Execute artifacts in dependency order (preflight blocks first, then pkg/installer, then apps/binaries, then postflight blocks). If any artifact fails, all previously installed artifacts are rolled back.

Artifact Execution Order

Artifacts execute in a carefully defined order to handle dependencies:

  1. Preflight blocks
  2. Uninstall stanzas (for reinstalls)
  3. Installers and packages
  4. Applications and system extensions
  5. Binaries and symlinks
  6. Postflight blocks
  7. Zap stanzas (cleanup)

This ordering ensures that packages are installed before binaries that depend on them, and that preflight setup completes before main installation.

Configuration & Metadata

Each cask maintains a Tab file (similar to formulas) that tracks:

  • Installation timestamp and version
  • Runtime dependencies
  • Installed artifacts
  • Whether it was installed on request or as a dependency

Configuration is stored in JSON and can be customized per-user via ~/.config/Homebrew/cask_config.json.

macOS vs Linux Support

Most cask artifacts are macOS-only (apps, preference panes, plugins). However, fonts and generic artifacts support Linux. The system checks MACOS_ONLY_ARTIFACTS to determine platform compatibility.

Installation & Upgrade Workflows

Relevant Files
  • Library/Homebrew/formula_installer.rb
  • Library/Homebrew/cask/installer.rb
  • Library/Homebrew/build.rb
  • Library/Homebrew/install.rb
  • Library/Homebrew/upgrade.rb

Homebrew's installation and upgrade system is built around two main installer classes: FormulaInstaller for packages and Cask::Installer for applications. These handle the complete lifecycle from dependency resolution through post-installation configuration.

Installation Pipeline

The FormulaInstaller class orchestrates formula installation through distinct phases:

  1. Prelude - Validates deprecation status, resolves dependencies, and checks requirements
  2. Fetch - Downloads source code, patches, and bottles with optional attestation verification
  3. Build - Compiles from source in a sandboxed subprocess (if not using pre-built bottles)
  4. Pour - Extracts pre-built bottles into the Cellar
  5. Link - Creates symlinks in the Homebrew prefix for easy access
  6. Finish - Runs post-install scripts, manages services, and updates metadata

Each phase includes comprehensive error handling and cleanup. If any phase fails, the installation is rolled back by removing the partially-installed formula.

Bottle vs. Source Installation

The system intelligently chooses between pre-built bottles and source compilation:

  • Bottles (pre-built binaries) are preferred when available and compatible with the system
  • Source builds occur when bottles are unavailable, explicitly requested, or incompatible
  • The pour_bottle? method determines which path to take based on architecture, OS version, and user flags

Dependency Management

Dependencies are installed recursively before the main formula. The system:

  • Resolves the full dependency tree using topological sorting
  • Installs build-time dependencies separately from runtime dependencies
  • Handles keg-only formulae specially to avoid conflicts
  • Tracks which dependencies were installed on-request vs. as dependencies

Upgrade Workflow

Upgrades follow a similar pattern to fresh installs but with additional logic:

# Upgrade checks if formula is outdated and installs newer version
upgrade_outdated_formulae!(formulae)
# Cleanup removes old versions after successful upgrade
Cleanup.install_formula_clean!(formula)

The Upgrade module sorts formulae topologically and checks runtime dependencies to avoid unnecessary upgrades when dependencies are already satisfied.

Cask Installation

Cask::Installer handles application installation with similar phases:

  • Prelude - Validates cask, checks requirements, and handles migrations
  • Fetch - Downloads the application archive
  • Stage - Extracts and processes the archive
  • Install - Runs installation artifacts (pkg, dmg, app, etc.)
  • Finish - Manages quarantine attributes and post-install tasks

Key Features

Download Queue - Parallel downloads for multiple formulae/casks using DownloadQueue for efficiency

Sandbox Isolation - Build and post-install scripts run in sandboxes to prevent system modifications

Service Management - Automatic service start/restart for formulae that provide services

Attestation - Cryptographic verification of bottles from core taps for security

Metadata Tracking - Tab files record build options, dependencies, and installation context for future operations

Bundle Management & Brewfiles

Relevant Files
  • Library/Homebrew/bundle.rb
  • Library/Homebrew/bundle/dsl.rb
  • Library/Homebrew/bundle/installer.rb
  • Library/Homebrew/bundle/dumper.rb
  • Library/Homebrew/bundle/brewfile.rb
  • Library/Homebrew/bundle/checker.rb

Homebrew Bundle provides a declarative interface for managing packages and services through Brewfiles. Instead of running individual brew commands, users specify desired state, and Bundle ensures the system matches that state.

Core Architecture

The Bundle system consists of three main layers:

  1. DSL Parser (dsl.rb): Parses Brewfile syntax and creates Entry objects representing packages to install
  2. Installer/Checker (installer.rb, checker.rb): Executes installation and validates package state
  3. Dumper (dumper.rb): Generates Brewfiles from current system state
Loading diagram...

Brewfile Format & DSL

The DSL supports multiple package types through declarative syntax:

tap "homebrew/cask"
brew "git"
brew "postgresql@16", restart_service: true
cask "firefox"
mas "Refined GitHub", id: 1519867270
vscode "editorconfig.editorconfig"
go "github.com/charmbracelet/crush"
cargo "ripgrep"
flatpak "com.visualstudio.code"

Each entry type maps to a specific installer class. The Dsl class uses instance_eval to execute Brewfile content, collecting entries into an array for processing.

Installation Pipeline

The Installer.install! method orchestrates the installation process:

  1. Iterates through parsed entries
  2. Determines appropriate installer class for each entry type
  3. Calls preinstall! to check if installation is needed
  4. Executes install! with relevant options
  5. Tracks success/failure counts

Key options include no_upgrade (skip updates), force (override checks), and verbose (detailed output).

Checking & Validation

The Checker base class provides a template for validating package state:

  • installed_and_up_to_date?: Subclasses implement type-specific checks
  • find_actionable: Returns packages needing installation or updates
  • exit_early_check: Fast-fail mode for CI/scripts

Each package type (formulae, casks, mas, etc.) has a corresponding checker subclass.

Brewfile Discovery

Brewfile.path resolves the Brewfile location with this priority:

  1. HOMEBREW_BUNDLE_FILE_GLOBAL environment variable (global mode)
  2. HOMEBREW_BUNDLE_FILE environment variable
  3. ~/.Brewfile or $HOMEBREW_USER_CONFIG_HOME/Brewfile (global mode)
  4. ./Brewfile (current directory)

Dumping System State

The Dumper module generates Brewfiles from installed packages:

  • Collects state from each package type dumper
  • Supports selective dumping (formulae, casks, taps, etc.)
  • Handles file writing with overwrite protection
  • Useful for version control and environment reproduction

Utilities & Helper Modules

Relevant Files
  • Library/Homebrew/utils.rb
  • Library/Homebrew/download_strategy.rb
  • Library/Homebrew/download_queue.rb
  • Library/Homebrew/utils/curl.rb
  • Library/Homebrew/utils/tar.rb

Homebrew provides a comprehensive set of utility and helper modules that abstract common operations and provide reusable functionality across the codebase. These modules handle everything from string manipulation to complex download orchestration.

Core Utilities Module

The Utils module in utils.rb provides essential string manipulation and filename handling utilities:

  • String Inflection: Methods like underscore, demodulize, and deconstantize convert between naming conventions (CamelCase <-> snake_case, module paths, etc.)
  • Pluralization: The pluralize method intelligently handles English pluralization with custom rules for special cases like "formula" and "dependency"
  • Author Parsing: parse_author! extracts name and email from formatted author strings
  • Filename Safety: safe_filename and safe_filename? sanitize filenames by removing control characters and path separators

The Homebrew module extends these with system-level utilities:

  • Conditional Requires: require? safely loads Ruby files with warning suppression
  • System Execution: _system and system fork and execute external commands with optional verbose output
  • Performance Profiling: inject_dump_stats! dynamically wraps module methods to measure execution time

Download Strategy Architecture

The download system uses an abstract strategy pattern to support multiple source types. The hierarchy is:

Loading diagram...

Key Features:

  • Caching: Downloads are cached by SHA256 hash of the URL, with symlinks for user-friendly access
  • Staging: The stage method unpacks archives and optionally changes to extracted directories
  • Timeout Support: All strategies support configurable timeouts via Utils::Timer
  • Quiet Mode: Output can be suppressed for batch operations

Curl Helper Module

Utils::Curl provides a comprehensive wrapper around curl operations:

  • Executable Management: Supports both system curl and Homebrew-installed curl via curl_executable
  • Argument Building: curl_args constructs curl command-line arguments with timeouts, retries, headers, and cookies
  • HTTP Metadata: Methods extract headers, ETags, and content disposition information
  • Error Handling: Defines specific exit codes for different curl failure modes (network errors, HTTP errors, parsing errors)

Download Queue

DownloadQueue orchestrates parallel downloads with progress tracking:

  • Concurrency Control: Uses Concurrent::FixedThreadPool for parallel downloads based on HOMEBREW_DOWNLOAD_CONCURRENCY
  • Progress Display: Real-time TTY output shows download status, phase, and size information
  • Error Recovery: Handles checksum mismatches and manifest errors with detailed reporting
  • Context Isolation: Restores pre-parallel context after downloads to prevent state bleeding

Tar Utilities

Utils::Tar provides tar file validation and detection:

  • Executable Detection: Finds GNU tar (gtar) or system tar, with caching
  • File Validation: Verifies tar archives are valid before extraction
  • Extension Support: Recognizes multiple tar variants (.tar.gz, .tar.bz2, .tar.xz, etc.)

Testing & Development Infrastructure

Relevant Files
  • Library/Homebrew/test/spec_helper.rb
  • Library/Homebrew/dev-cmd/tests.rb
  • Library/Homebrew/dev-cmd/test-bot.rb
  • Library/Homebrew/test_bot.rb
  • Library/Homebrew/.rspec_parallel
  • Library/Homebrew/.simplecov
  • .github/workflows/tests.yml

Test Framework & Organization

Homebrew uses RSpec as its primary testing framework with comprehensive unit and integration tests. Tests are organized in Library/Homebrew/test/ with files following the *_spec.rb naming convention. The test suite includes OS-specific tests (macOS, Linux) and generic tests that run on all platforms.

Running Tests Locally

Use brew tests to execute the test suite with various options:

brew tests                    # Run all tests
brew tests --online          # Include network-dependent tests
brew tests --generic         # Run only OS-agnostic tests
brew tests --changed         # Test only files changed from main
brew tests --only=cmd/install  # Run specific test file
brew tests --coverage        # Generate code coverage reports
brew tests --no-parallel     # Run tests serially (default: parallel)

Test Configuration & Helpers

The spec_helper.rb file configures RSpec with:

  • Random test ordering to catch hidden dependencies
  • Strict error handling (deprecations, warnings treated as errors)
  • Timeout enforcement (60s default, 120s for integration tests)
  • Automatic cleanup between tests (environment, files, caches)
  • Test helpers for formulas, casks, fixtures, and temporary directories
  • Conditional skipping based on OS, network, CI environment, and tool availability

Test helpers include needs_macos, needs_linux, needs_network, needs_ci, needs_java, needs_python, and others to skip tests when prerequisites aren't met.

Parallel Testing & Performance

Tests run in parallel by default using parallel_rspec. The framework:

  • Distributes tests across CPU cores for faster execution
  • Tracks runtime per test file to balance load across processes
  • Stores logs in HOMEBREW_CACHE/parallel_runtime_rspec.log
  • Supports profiling with --profile N to identify slow tests
  • Uses --stackprof, --vernier, or --ruby-prof for detailed performance analysis

Coverage & CI Integration

SimpleCov generates code coverage reports when --coverage is passed. Coverage configuration:

  • Tracks both line and branch coverage
  • Merges results from parallel processes and integration tests
  • Outputs HTML and Cobertura XML formats
  • Filters test code, vendor code, and OS-specific files
  • Supports subprocesses via enable_for_subprocesses

GitHub Actions CI runs tests across multiple configurations:

- tests (online): Full test suite with network access
- tests (generic OS): Platform-agnostic tests
- tests (Linux): Linux-specific tests
- tests (macOS): macOS-specific tests

Test-Bot for Formula Validation

brew test-bot provides comprehensive formula testing in CI environments (GitHub Actions only):

  • Validates formula syntax and structure
  • Installs and tests formulas
  • Builds bottles (binary packages)
  • Tests dependent formulas
  • Generates JUnit XML reports
  • Supports dry-run mode for preview

Key options include --cleanup, --build-from-source, --skip-dependents, and --junit for detailed CI integration.

Environment Isolation

Each test runs in an isolated environment:

  • Temporary directories created in HOMEBREW_TEMP
  • Environment variables reset before and after each test
  • Stdin/stdout/stderr redirected to /dev/null (unless verbose)
  • File system state verified (detects file leaks)
  • Caches cleared between tests
  • Deprecation exceptions enabled to catch API misuse

This isolation ensures tests don't interfere with each other or the system.