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().nodenameHOSTTYPE:os.uname().machineOSTYPE: 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からは消える。
と言った感じの運用が出ます。
