Homebrew, like Git, supports external commands. This lets you create new commands that can be run like:
brew mycommand --option1 --option3 <formula>
without modifying Homebrew’s internals.
External commands come in two flavours: Ruby commands and shell scripts.
In both cases, the command file should be executable (
chmod +x) and live somewhere in
External commands can be added to a tap to allow easy distribution. See below for more details.
An external command
extcmd implemented as a Ruby command should be named
brew-extcmd.rb. The command is executed by doing a
require on the full pathname. As the command is
required, it has full access to the Homebrew “environment”, i.e. all global variables and modules that any internal command has access to. Be wary of using Homebrew internals; they may change at any time without warning.
The command may
Kernel.exit with a status code if it needs to; if it doesn’t explicitly exit then Homebrew will return
An executable script for a command named
extcmd should be named
brew-extcmd. The script itself can use any suitable shebang (
#!) line, so an external script can be written in Bash, Ruby, or even Python. Unlike the ruby commands this file must not end with a language-specific suffix (
.py). This file will be run via
exec with some Homebrew variables set as environment variables, and passed any additional command-line arguments.
||Where Homebrew caches downloaded tarballs to, by default
||Where Homebrew installs software.
||The location of the Homebrew Cellar, where software is staged. This will be
||The directory containing Homebrew’s own application code.|
||The Git repository directory (i.e. where Homebrew’s
All internal and external Homebrew commands can provide styled
--help output by using lines starting with
#: (a comment then
: character in both Bash and Ruby) which are then output by
For example, see the header of
brew-services.rb which is output with
brew services --help.
These commands have been contributed by Homebrew users but are not included in the main Homebrew organisation, nor are they installed by the installer script. You can install them manually, as outlined above.
Note they are largely untested, and as always, be careful about running untested code on your machine.
gem package into a self-contained Homebrew Cellar location: https://github.com/sportngin/brew-gem
Note this can also be installed with
brew install brew-gem.
External commands should be added to a
cmd directory in the tap. An external command
extcmd implemented as a Ruby command should live in
cmd/extcmd.rb (don’t forget to
To easily use Homebrew’s argument parser, follow the following Ruby template for external commands (replacing all instances of
foo with the name of the command):
# frozen_string_literal: true module Homebrew module_function def foo_args Homebrew::CLI::Parser.new do description <<~EOS Do something. Place a description here. EOS switch "-f", "--force", description: "Force doing something in the command." flag "--file=", description: "Specify a file to do something with in the command." comma_array "--names", description: "Add a list of names to the command." named_args [:formula, :cask], min: 1 end end def foo args = foo_args.parse something if args.force? something_else if args.file == "file.txt" end end
Using the above will generate appropriate help text:
$ brew foo --help Usage: brew foo [options] formula|cask [...] Do something. Place a description here. -f, --force Force doing something in the command. --file Specify a file to do something with in the command. --names Add a list of names to the command. -d, --debug Display any debugging information. -q, --quiet Make some output more quiet. -v, --verbose Make some output more verbose. -h, --help Show this message.
The usage string is automatically generated based on the specified number and type of named arguments (see below for more details on specifying named arguments). The generated usage string can be overridden by passing the correct usage string to the
usage_banner method (placed just before the
description method). See the
brew tap command for an example.
named_args method to specify the type and number of named arguments that are expected. Pass either a symbol to indicate the type of argument expected, an array of symbols to indicate that multiple types should be expected, or an array of strings to specify which specific options should be expected (see the
brew analytics command for an example of this).
Pass an integer to the
max parameter of
named_args to specify the number of named arguments that are expected. See the following examples:
# Accept no named args named_args :none # Accept any number (including none) of formula arguments named_args :formula # Accept exactly one of the specified options as an argument named_args %w[state off on], number: 1 # Accept at least one argument that is either a formula or a cask named_args [:formula, :cask], min: 1 # Accept no more than one argument that is a tap named_args :tap, max: 1 # Accept between one and two named args named_args min: 1, max: 2