Homebrewのパッケージリストを管理するツールのHomebrew-file
でパッケージを管理する際に、main
というコマンドを使えるようにしました。
これによってより柔軟に複数の環境でのBrewfileの共有が出来るようになりました。
HomebrewのパッケージリストをBrewfileを使って管理するツール。
Homebrew自体にも公式にbundleというBrewfileファイルに書き出す機能がありますが、 Homebrew-fileにはGitHubとかと連携してBrewfileの履歴を管理したり他の環境と共有しやすくするための 機能だったり、Brewfileを自動的にアップデートする機能があったりします。
Brewfile
Homebrew-fileにおけるBrewfileは基本的には以下の様な感じになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Ref: Usage — Homebrew-file documentation
Brewfileの中でコマンドとして使えるものとしては上の様に主に
tap
: Tapするレポジトリbrew
: インストールするFormulaパッケージcask
: インストールするCaskパッケージappstore
: AppStoreからインストールするApp (mas
を利用。)
があります。
cask
に関してはHomebrew 3.0.0からbrew cask
というコマンドはなくなり、brew install ...
で同じようにインストールできるようになりましたが、
brew list --cask ...
の様に区別して見ることも出来る状態で
brew file init
とかでBrewfileに書き出す場合には区別して書き出しています。
Brewfileに手動でbrew iterm2
みたいにCaskなものを書いておいてもbrew file install
でインストールすることは出来ます。
file機能
上記の4つ以外にもいくつか使えるコマンドがありますが、
そのうちの一つにfile
というコマンドがあります。
1 2 3 4 5 6 |
|
の様に書くと、brew file install
をするとき、Brewfile.extに書いてある
パッケージも読み込んでインストールします。
brew file init
すると、Brewfile.extに元からあったパッケージはそちらに、
新たに加わったパッケージは親のBrewfileに追加される様になっています。
ファイルの指定方法として、上のように相対パスの様に書くと、親のBrewfileのある ディレクトリからの相対パスになります。 なので、上の場合はBrewfileと同じディレクトリにあるBrewfile.extを見に行きます。
/home/user/Brewfile.extの様に/
から開始すると絶対パスとして見に行きます。
もしファイルがない場合にはエラーにならずに無視されます。
したがって、特定のマシンにだけ入れたいパッケージ、というものがある場合、
file $HOME/Brewfile.ext
としておいて、必要な環境にだけ$HOME/Brewfile.extを置いておくと、
その環境にだけbrew file install
でBrewfile.extの中身をインストールしてくれます。
もしBrewfileとBrewfile.extに同じパッケージが書かれているかつ
そのパッケージが既にインストールされている状態でbrew file init
すると
Brewfile.extの方に優先して残すようになっています。
ファイル指定で使える変数
file
などで指定できるファイルに使える変数として、
~
でホームディレクトリを指定したり、$HOME
などの環境変数を使うことが出来ます。
加えて、
$HOSTNAME
、$HOSTTYPE
、$OSTYPE
、$PLATFORM
の4つの変数も使えます。
それぞれ
HOSTNAME
:os.uname().nodename
HOSTTYPE
:os.uname().machine
OSTYPE
: Bashのシェル変数(subprocess
で取得)PLATFORM
:sys.platform
です。HOSTNAME
、HOSTTYPE
はシェル変数の同名のものと同じです。
HOSTNAME
: マシン名(ドメインなし)HOSTTYPE
:x86_64
,arm64
などOSTYPE
:linux-gnu
、darwin20.3.0
などPLATFORM
:linux
、darwin
など
これを使うと、例えば特定のマシンにだけ入れたいパッケージがある場合、 親のBrewfileを
1 2 3 4 5 6 |
|
1
|
|
1
|
|
というファイルを用意しておくと、machine1では[email protected]
をインストールして
machine2では[email protected]
をインストールし、
その他の環境ではこれらをインストールしません。
OSなど環境毎に変えたい場合には
file ./Brewfile.$PLATFORM.$HOSTTYPE
が便利です。
OSTYPE
にはバージョン情報が入ってしまうため、
そこまで管理したい場合には便利ですが、大概の場合はそのバージョンは無視して良いことが多く
PLATFORM
を使ったほうが便利です。
あとはアーキテクチャの違いを$HOSTTYPE
で追加しておきます。
これは、特に最近でたM1 Macで使う際に便利です。
M1のarm64の環境だと使えないCUIツールはまだ結構あって、 Rosettaを使ったIntel環境も作っている人は多いかと思いますが、 両方で同じBrewfileを使おうと思うとIntel用に入れたものがarm64側でインストールに失敗してしまいます。
そこで、上の様なfile
設定をしておいて、
Brewfile.darwin.x86_64というファイルにIntel側にだけ入れるものを書いておけば 他のものはBrewfileで共有して使うことが出来ます。
mainコマンドの追加
上のfile
の場合、brew init
や、
brew-wrap
を使ったbrew install
時に追加されるパッケージは親のBrewfile側になります。
したがって、その環境特有のものをインストールした場合には手動で Brewfileから Brewfile.machine1とかに移して、他の環境では使わないようにする必要があります。
これはほとんどが共通で、ほんの一部だけが特別なパッケージの場合には便利です。
一方で、例えば仕事のチームで最低限必要なパッケージ群をまとめるBrewfileを作り、 他を個別に管理したい、という場合、自動でBrewfileを管理するのが難しくなります。
main
コマンドはこういった場合に使えるようにv8.5.0で追加しました。
通常、メインのファイルは最初に指定されているBrewfile本体になりますが、
main
コマンドで指定されたファイルがあるとそれに移ります。
メインのファイルは、新たなパッケージが加わったときなどに、
brew file init
や
brew-wrapを使ったbrew install
でパッケージが加えられるファイルになります。
main
の使い方はfile
と同じ様にファイルへのパスを書く形で、
1 2 3 4 5 6 |
|
と言った感じ。
この場合、新たなパッケージが加えられた場合、
brew file init
や
brew-wrapを使ったbrew install
では./Brewfile.$HOSTNAME
に追加されます。
もしファイルがない場合には自動的に作られます。
これを使うと、Brewfileの自動アップデートを使っても共有ファイルの管理が簡単になります。
例えば、MacとLinuxで共有しようと思うと、
1 2 3 |
|
としておけば、それぞれの環境でインストールしたものはそれぞれ、Brewfile.darwin、Brewfile.linuxに追加されます。
また、M1 Macでは
1 2 3 |
|
としておけば、 そのままのM1 (arm64)環境ならBrewfile.arm64、Rosetta使ったx86_64環境なら Brewfile.x86_64に追加されます。
たまに整理してあげて、共通しているものをBrewfileに移す作業をしてあげれば良いかと。 (この辺をうまくやる機能もそのうち実装したい。。。)
Brewfileとmain
で指定されてたBrewfile.$PLATFORM
などの両方に同じパッケージが書かれていた場合、
brew file init
するとmain
の場合はfile
と違い
親のBrewfileの方に優先して残すようになっています。
ちなみにmain
やfile
は入れ子が可能で、
1 2 3 |
|
として、
1 2 3 |
|
として、Brewfile.linuxの方ではmain
を追加しないままにしておくと、
- Linux環境: HOSTによらずBrewfile.linuxがメイン。
- Mac環境: HOST毎に別のものがメインに。
- Brewfileにあるパッケージは全環境共通。
- Brewfile.darwinにあるパッケージはMac環境だけで共通。
とすることが出来ます。
チーム共有Brewfileの運用
そこで、例えばチーム共有Brewfileみたいのを考えることが出来ます。
- まず、共有するBrewfileを作り、適当なGitHubのレポジトリで共有。
- Brewfileに
main ~/.Brewfile
という一行を加えておく。 - このレポジトリは管理者だけが書き込めるものでも構いません。
- Brewfileに
- 各個人で~/.Brewfileを用意。
- 最初の時点でとくに必要なものがなければ自分で用意しなくても良くて勝手に作ってくれる。
brew file set_repo
で共有レポジトリを指定してセットする。brew install
したり色々して~/.Brewfileをアップデート。- dotfilesなどで~/.Brewfileも管理すると良いかと。
- 管理者が共有のBrewfileをアップデートしてパッケージを追加したりする。
- 管理者以外でも便利で皆が使うべきものだと思えばPull Request出したり。
brew file update
によって共有Brewfileをアップデート。- 個人ごとの利用ではこのファイルを変更することは無いので、レポジトリ側のアップデートのみを撮ってくる形になる。
- 自分でインストールしたパッケージも共有Brewfileに追加されると~/.Brewfileからは消える。
と言った感じの運用が出ます。