メインコンテンツまでスキップ

Homebrewの用語を挙動を確認しながら理解する

tap

Homebrewにおける名前空間のこと。「tapを追加する」というように名詞で利用する。 brew installを実行したとき、対象のライブラリをインストール方法がtapに含まれており、ダウンロードできるようになる。

ユーザーが現在利用可能な名前空間はbrew tapで表示可能である。 ただし、homebrewのインストールした直後は表示されない。 homebrew/coreが存在しているが、省略されている。

$ brew tap
# 初期状態では何も帰ってこない

名前空間を追加するときはbrew tap [user]/[repo]を実行する。 実態はgit cloneが走っている。git cloneのホスティング先のデフォルトはgithub.comのが使用される。例えばpetere/postgresqlhttps://github.com/petere/postgresql)のtapを追加する。場合、次のような結果を得る。

$ brew tap petere/postgresql

==> Tapping petere/postgresql
Cloning into '/opt/homebrew/Library/Taps/petere/homebrew-postgresql'...
remote: Enumerating objects: 1385, done.
remote: Counting objects: 100% (147/147), done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 1385 (delta 132), reused 109 (delta 100), pack-reused 1238 (from 1)
Receiving objects: 100% (1385/1385), 254.04 KiB | 2.54 MiB/s, done.
Resolving deltas: 100% (1072/1072), done.
Tapped 18 formulae (32 files, 356.3KB).

/opt/homebrew/Library/Taps/petere/postgresqlがそのままcloneされていることがわかる。

brew tap petere/postgresqlの例

brew tapを実行するとtapが登録されていることがわかる。

$ brew tap
petere/postgresql

GitHub以外からcloneする場合

brew tapのリポジトリ名の後にリポジトリのURLを指定することができる。ここを調整すればGitHub EnterpriseやGitLab、Bitbucketも指定することが可能となる。

$ brew tap [user]/[repo] [url]

untap

追加したtapを削除することができる。

$ brew untap petere/postgresql
Untapping petere/postgresql...
Untapped 18 formulae (33 files, 356.6KB).

$ brew tap
# 表示されない

Formula

Rubyで記述されたHomebrewで管理されるパッケージの定義である。 brew installを実行した際にFormulaの定義が確認され、インストールが実施される。

wgetのFormula: https://github.com/Homebrew/homebrew-core/blob/master/Formula/w/wget.rb

実際に実行すると次のようなログが出力される。

$ brew install wget

==> Downloading https://formulae.brew.sh/api/formula.jws.json
==> Downloading https://formulae.brew.sh/api/cask.jws.json
==> Downloading https://ghcr.io/v2/homebrew/core/wget/manifests/1.25.0
######################################################################### 100.0%
==> Fetching dependencies for wget: libunistring, gettext and libidn2
==> Downloading https://ghcr.io/v2/homebrew/core/libunistring/manifests/1.3
######################################################################### 100.0%
==> Fetching libunistring
==> Downloading https://ghcr.io/v2/homebrew/core/libunistring/blobs/sha256:3cd26
######################################################################### 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/gettext/manifests/0.23.1
######################################################################### 100.0%
==> Fetching gettext
==> Downloading https://ghcr.io/v2/homebrew/core/gettext/blobs/sha256:9179f47309
######################################################################### 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/libidn2/manifests/2.3.7
######################################################################### 100.0%
==> Fetching libidn2
==> Downloading https://ghcr.io/v2/homebrew/core/libidn2/blobs/sha256:1da206a51b
######################################################################### 100.0%
==> Fetching wget
==> Downloading https://ghcr.io/v2/homebrew/core/wget/blobs/sha256:a93dd95c5d630
######################################################################### 100.0%
==> Installing dependencies for wget: libunistring, gettext and libidn2
==> Installing wget dependency: libunistring
==> Downloading https://ghcr.io/v2/homebrew/core/libunistring/manifests/1.3
Already downloaded: /Users/Himenon/Library/Caches/Homebrew/downloads/a570da63bc1839c7e217f203abd54d4d873ebd6b99f6e88994d0e79e2ebe987c--libunistring-1.3.bottle_manifest.json
==> Pouring libunistring--1.3.arm64_sequoia.bottle.tar.gz
🍺 /opt/homebrew/Cellar/libunistring/1.3: 59 files, 5.4MB
==> Installing wget dependency: gettext
==> Downloading https://ghcr.io/v2/homebrew/core/gettext/manifests/0.23.1
Already downloaded: /Users/Himenon/Library/Caches/Homebrew/downloads/a5b6ba6453cc31731ac67fb3d0075d98ab572a913f3e740b54a86d79906f360e--gettext-0.23.1.bottle_manifest.json
==> Pouring gettext--0.23.1.arm64_sequoia.bottle.tar.gz
🍺 /opt/homebrew/Cellar/gettext/0.23.1: 2,052 files, 22.2MB
==> Installing wget dependency: libidn2
==> Downloading https://ghcr.io/v2/homebrew/core/libidn2/manifests/2.3.7
Already downloaded: /Users/Himenon/Library/Caches/Homebrew/downloads/45d1d4d2930c4782bf53e761a1c0166cd8a40f4193ac8c44e86f0b6708e80354--libidn2-2.3.7.bottle_manifest.json
==> Pouring libidn2--2.3.7.arm64_sequoia.bottle.tar.gz
🍺 /opt/homebrew/Cellar/libidn2/2.3.7: 81 files, 1MB
==> Installing wget
==> Pouring wget--1.25.0.arm64_sequoia.bottle.tar.gz
🍺 /opt/homebrew/Cellar/wget/1.25.0: 92 files, 4.5MB
==> Running `brew cleanup wget`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

インストール時には、Formulaに記述された依存関係depends_onを解決するためにFetchが走っている。

Fetching dependencies for wget: libunistring, gettext and libidn2

これらの依存しているライブラリもhomebrewで管理されており、Formulaが確認できる。

LibraryURL
libunistringhttps://github.com/Homebrew/homebrew-core/blob/master/Formula/lib/libunistring.rb
gettexthttps://github.com/Homebrew/homebrew-core/blob/master/Formula/g/gettext.rb
libidn2https://github.com/Homebrew/homebrew-core/blob/master/Formula/lib/libidn2.rb

ただ、brew installで見えるログは直接依存しているライブラリのログだけで、階層化されたログまでは見えない。 --verboseオプションだけでも足りず、--debugオプションまでつけるのが確実である。

brew install wget --verbose --debug

tapの優先度

名前空間が衝突(コンフリクト)したさいはどういった挙動になるのか確認してみた。 brew install foobrew install some-user/fooのように同一のTapが存在した場合、次のような優先度になる。

  1. ローカルのFormula(/usr/local/Homebrew/Library/Taps/にあるもの)
  2. homebrew/core のFormula
  3. ユーザーが追加したTapのFormula

依存関係の依存関係先の名前空間が干渉するようなどうしようもないケースも存在する。 それを防ぐ機構がいくつかある。

conflicts_with

Formulaファイルに記述する宣言で、すでに先客(インストール済みのライブラリ)がいた場合、インストールに失敗するようになる。

ドキュメントによれば、このオプションは最終手段(a last-resort option)とのこと。

keg_only

/usr/local/Cellar/にインストールだけ済ませておくが、/usr/local/binに対してシンボリックリンクを張らないため、 既存のシステムに含まれるバージョンと干渉しないようにする仕組み。

例えば

brew link --force openssl@1.1

のようにユーザーが明示的に実行しない限りはPATHが通らない状態になる。