rcmdnk's blog

味の加久の屋 brew プレミアムおつまみ ウニ入りホタテマヨ 70g

Homebrewのパッケージリストを管理するツールのHomebrew-file でパッケージを管理する際に、mainというコマンドを使えるようにしました。

これによってより柔軟に複数の環境でのBrewfileの共有が出来るようになりました。

Homebrew-file

HomebrewのパッケージリストをBrewfileを使って管理するツール。

Homebrew自体にも公式にbundleというBrewfileファイルに書き出す機能がありますが、 Homebrew-fileにはGitHubとかと連携してBrewfileの履歴を管理したり他の環境と共有しやすくするための 機能だったり、Brewfileを自動的にアップデートする機能があったりします。

Brewfile

Homebrew-fileにおけるBrewfileは基本的には以下の様な感じになります。

Brewfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
tap homebrew/core
brew neovim
brew node
brew [email protected]

tap rcmdnk/file
brew brew-file

tap rcmdnk/file
brew brew-file

tap homebrew/cask
cask bettertouchtool
cask google-japanese-ime
cask hyperswitch
cask iterm2
cask karabiner-elements

appstore 408981434   iMovie        (10.2.5)
appstore 409183694   Keynote       (11.1)
appstore 409203825   Numbers       (11.1)
appstore 409201541   Pages         (11.1)

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というコマンドがあります。

Brewfile
1
2
3
4
5
6
tap homebrew/core
brew neovim

...

file ./Brewfile.ext

の様に書くと、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 installBrewfile.extの中身をインストールしてくれます。

もしBrewfileBrewfile.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

です。HOSTNAMEHOSTTYPEはシェル変数の同名のものと同じです。

  • HOSTNAME: マシン名(ドメインなし)
  • HOSTTYPE: x86_64, arm64など
  • OSTYPE: linux-gnudarwin20.3.0など
  • PLATFORM: linuxdarwinなど

これを使うと、例えば特定のマシンにだけ入れたいパッケージがある場合、 親のBrewfile

Brewfile
1
2
3
4
5
6
tap homebrew/core
brew neovim

...

file ./Brewfile.$HOSTNAME
Brewfile.machine1
Brewfile.machine2

というファイルを用意しておくと、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と同じ様にファイルへのパスを書く形で、

Brewfile
1
2
3
4
5
6
tap homebrew/core
brew neovim

...

main ./Brewfile.$HOSTNAME

と言った感じ。

この場合、新たなパッケージが加えられた場合、 brew file initや brew-wrapを使ったbrew installでは./Brewfile.$HOSTNAME に追加されます。

もしファイルがない場合には自動的に作られます。

これを使うと、Brewfileの自動アップデートを使っても共有ファイルの管理が簡単になります。

例えば、MacとLinuxで共有しようと思うと、

Brewfile
1
2
3
...

main ./Brewfile.$PLATFORM

としておけば、それぞれの環境でインストールしたものはそれぞれ、Brewfile.darwinBrewfile.linuxに追加されます。

また、M1 Macでは

Brewfile
1
2
3
...

main ./Brewfile.$HOSTTYPE

としておけば、 そのままのM1 (arm64)環境ならBrewfile.arm64、Rosetta使ったx86_64環境なら Brewfile.x86_64に追加されます。

たまに整理してあげて、共通しているものをBrewfileに移す作業をしてあげれば良いかと。 (この辺をうまくやる機能もそのうち実装したい。。。)

Brewfilemainで指定されてたBrewfile.$PLATFORM などの両方に同じパッケージが書かれていた場合、 brew file initするとmainの場合はfileと違い 親のBrewfileの方に優先して残すようになっています。

ちなみにmainfileは入れ子が可能で、

Brewfile
1
2
3
...

main ./Brewfile.$PLATFORM

として、

Brewfile.darwin
1
2
3
...

main ./Brewfile.$HOSTNAME

として、Brewfile.linuxの方ではmainを追加しないままにしておくと、

  • Linux環境: HOSTによらずBrewfile.linuxがメイン。
  • Mac環境: HOST毎に別のものがメインに。
  • Brewfileにあるパッケージは全環境共通。
  • Brewfile.darwinにあるパッケージはMac環境だけで共通。

とすることが出来ます。

チーム共有Brewfileの運用

そこで、例えばチーム共有Brewfileみたいのを考えることが出来ます。

  • まず、共有するBrewfileを作り、適当なGitHubのレポジトリで共有。
    • Brewfilemain ~/.Brewfileという一行を加えておく。
    • このレポジトリは管理者だけが書き込めるものでも構いません。
  • 各個人で~/.Brewfileを用意。
    • 最初の時点でとくに必要なものがなければ自分で用意しなくても良くて勝手に作ってくれる。
  • brew file set_repoで共有レポジトリを指定してセットする。
  • brew installしたり色々して~/.Brewfileをアップデート。
    • dotfilesなどで~/.Brewfileも管理すると良いかと。
  • 管理者が共有のBrewfileをアップデートしてパッケージを追加したりする。
    • 管理者以外でも便利で皆が使うべきものだと思えばPull Request出したり。
  • brew file updateによって共有Brewfileをアップデート。
    • 個人ごとの利用ではこのファイルを変更することは無いので、レポジトリ側のアップデートのみを撮ってくる形になる。
    • 自分でインストールしたパッケージも共有Brewfileに追加されると~/.Brewfileからは消える。

と言った感じの運用が出ます。

Sponsored Links
Sponsored Links

« Evernoteのショートカットキーの変更 Windowsネイティブな環境でのtar.gzファイルの解凍 »