外部指令

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 自有應用程式程式碼的目錄。
HOMEBREW_REPOSITORY Git 儲存庫目錄(即 Homebrew 的 .git 目錄所在位置)。通常與 HOMEBREW_PREFIX 相同,或為 Homebrew 子目錄。

提供 --help

所有內部和外部 Homebrew 指令都可以提供樣式化的 --help 輸出,方法是使用 Homebrew 的 引數剖析器,如 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 指令 以取得範例)。

傳遞一個整數給 numberminmax 參數的 named_args 以指定預期的命名參數數量。請參閱下列範例

# 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