HomebrewでFormulaにない任意のバージョンのパッケージをインストールする

Today I Learned

Homebrewでは、バージョンを指定しなければ、Homebrew Formulaの最新バージョンがインストールされる。
過去バージョンがHomebrew Formulaに存在する場合は、@以降にバージョンを指定すると、指定したバージョンでインストールできる。

# 指定できるバージョンを調べる
# 例は postgresql
$ brew search postgresql@

==> Formulae
postgresql@10       postgresql@12       postgresql@14       postgresql@9.4      qt-postgresql
postgresql@11       postgresql@13       postgresql@15       postgresql@9.5      postgrest
==> Casks
navicat-for-postgresql

# @ 以降にインストールしたいバージョンを指定する
$ brew install postgresql@14

Homebrew Formulaに過去バージョンが残されていない場合、上記の方法ではインストールできない。
そのため、インストールするバージョンのスクリプトを指定したFormulaをローカルに作成することで、任意のバージョンをインストールする。
ただし、インストールスクリプトを実行するため、Rubyの実行環境が必要である。

動作を確認した環境

Homebrew v3.6.15

Homebrew 公式で提供されているパッケージをインストールする場合

Homebrew公式で提供されているパッケージは、Homebrew/homebrew-coreで管理されている。

1. ローカルにオリジナルの Formula を作成する

brew tap-new ユーザー名/Formula 名で新規のFormulaを作成する。
Formula 名は、brew installするときに指定するパッケージ名となる。

たとえば、Go v1.18.5をインストールしたいとする。

# Go の場合
$ brew tap-new $USER/go

Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/chick-p/homebrew-go/.git/
[main (root-commit) b435276] Create chick-p/go tap
...省略...
==> Created chick-p/go
/usr/local/Homebrew/Library/Taps/chick-p/homebrew-go
...省略...

brew extract --version=インストールするバージョン Formla名で、過去バージョンのインストールスクリプトを特定する。

$ brew extract --version=1.18.5 go $USER/go

==> Searching repository history
==> Writing formula for go from revision fad51b0 to:
/usr/local/Homebrew/Library/Taps/chick-p/homebrew-go/Formula/go@1.18.5.rb

2. オリジナルの Formula を指定してインストールする

brew installでインストールするパッケージ名に、オリジナルのFormulaを指定する。

$ brew install $USER/go/go@1.18.5

==> Fetching chick-p/go/go@1.18.5
...省略...
==> Downloading from https://dl.google.com/go/go1.18.5.src.tar.gz
######################################################################## 100.0%
==> Installing go@1.18.5 from chick-p/go
...省略...

brew tap Formula で追加するパッケージをインストールする場合

Homebrew公式で提供されていないパッケージをインストールする場合brew tapしてFormulaを追加してからインストールする必要がある。
こういったパッケージで特定のバージョンをインストールする場合も、公式で提供されているパッケージをインストールする方法と同じである。
ただし、brew extractで指定するFormula名には、tapに必要だったパスも記載する必要がある。

たとえば、dart-sass-embbedの場合、brew extractでsass/sass/dart-sass-embeddedを指定する。

# dart-sass-embbed v1.56.1 をインストールする例
$ brew tap-new $USER/dart-sass-embedded
$ brew extract --version=1.56.1 sass/sass/dart-sass-embedded $USER/dart-sass-embedded
$ brew install $USER/dart-sass-embedded/dart-sass-embedded@1.56.1

インストールできたことを確認する。

$ dart-sass-embedded --version

{
  "protocolVersion": "1.2.0",
  "compilerVersion": "1.56.1",
  "implementationVersion": "1.56.1",
  "implementationName": "Dart Sass",
  "id": 0
}