外部命令

Homebrew 与 Git 类似,支持外部命令。这让你可以创建新命令,像这样运行

brew mycommand --option1 --option3 <formula>

而不修改 Homebrew 的内部内容。

命令类型

外部命令有两种类型:Ruby 命令和 shell 脚本。

在这两种情况下,命令文件都应该是可执行的(chmod +x),并且位于 PATH 中的某个位置。

外部命令可以添加到 tap 中,以便于分发。有关更多详细信息,请参见下方

Ruby 命令

作为 Ruby 命令实现的外部命令 extcmd 应命名为 brew-extcmd.rb。通过对完整路径名执行 require 来执行该命令。由于该命令是 require 的,因此它可以完全访问 Homebrew “环境”,即任何内部命令都可以访问的所有全局变量和模块。小心使用 Homebrew 内部内容;它们可能会在任何时候不经警告而发生更改。

该命令可以使用状态代码 Kernel.exit,如果需要的话;如果它没有显式退出,则 Homebrew 将返回 0

其他可执行脚本

名为 extcmd 的命令的可执行脚本应命名为 brew-extcmd。脚本本身可以使用任何合适的 shebang(#!)行,因此外部脚本可以用 Bash、Ruby 甚至 Python 编写。与 Ruby 命令不同,此文件不得以特定于语言的后缀(.sh.py)结尾。此文件将通过 exec 运行,其中一些 Homebrew 变量被设置为环境变量,并传递任何其他命令行参数。

变量 说明
HOMEBREW_CACHE Homebrew 将下载的 tarball 缓存到的位置,默认情况下为 ~/Library/Caches/Homebrew
HOMEBREW_PREFIX Homebrew 安装软件的位置。对于 macOS Intel,默认情况下为 /usr/local,对于 Apple Silicon,为 /opt/homebrew,对于 Linux,为 /home/linuxbrew/.linuxbrew
HOMEBREW_CELLAR Homebrew Cellar 的位置,其中对软件进行暂存。如果该目录存在,则此位置为 HOMEBREW_PREFIX/Cellar,否则为 HOMEBREW_REPOSITORY/Cellar
HOMEBREW_LIBRARY_PATH 包含 Homebrew 自有应用程序代码的目录。
自制软件存储库 Git 存储库目录(即 Homebrew 的 .git 目录所在位置)。通常与 HOMEBREW_PREFIX 相同,或为 Homebrew 子目录。

提供 --help

所有内部和外部 Homebrew 命令都可以使用 Homebrew 的 参数解析器 提供样式化的 --help 输出,如 brew services 命令 中所示;或通过包含以 #: 开头的行(在 Bash 和 Ruby 中为注释,后跟 : 字符),如 update.sh 的标头 中所示,该标头使用 brew update --help 打印。

非官方外部命令

这些命令由 Homebrew 用户贡献,但未包含在 Homebrew 主组织中,也未由安装程序脚本安装。您可以按照上述说明手动安装它们。

请注意,它们在很大程度上未经测试,并且一如既往,请小心在您的机器上运行未经测试的代码。

brew-gem

将任何 gem 包安装到独立的 Homebrew Cellar 位置:https://github.com/sportngin/brew-gem

请注意,也可以使用 brew install brew-gem 安装此命令。

tap 中的外部命令

外部命令可以托管在 tap 中,以便用户可以轻松地安装和使用它们。有关创建和维护 tap 的更多详细信息,请参阅 如何创建和维护 tap

外部命令应添加到 tap 中的 cmd 目录。作为 Ruby 命令实现的外部命令 extcmd 应位于 cmd/extcmd.rb 中(不要忘记 chmod +x)。

要轻松使用 Homebrew 的参数解析器,请为外部命令复制以下 Ruby 模板。您的实现必须包括以下内容

# frozen_string_literal: true

module Homebrew
  module Cmd
    class Foo < AbstractCommand
      cmd_args 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

      def run
        something if args.force?
        something_else if args.file == "file.txt"
      end
    end
  end
end

使用上述内容将生成适当的帮助文本

$ 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.

用法字符串会根据指定的命名参数的数量和类型自动生成(有关指定命名参数的更多详细信息,请参见下文)。可以通过将正确的用法字符串传递给 usage_banner 方法(放置在 description 方法之前)来覆盖生成的用法字符串。请参阅 brew tap 命令 以获取示例。

使用 named_args 方法指定预期的命名参数的类型和数量。传递一个符号以指示预期的参数类型,一个符号数组以指示应预期多个类型,或一个字符串数组以指定应预期哪些特定选项(请参阅 brew analytics 命令 以获取此示例)。

将一个整数传递给 named_argsnumberminmax 参数以指定预期的命名参数的数量。请参阅以下示例

# 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

可以通过调用 args.named 来访问命名参数。查看内部 命令开发人员命令 以获取更多用法示例。

Fork me on GitHub