Closed7

dotfileでBrewfileをクロスプラットフォーム化したい

ピン留めされたアイテム
あーるあーる

結論

BrewfileはHomebrewだけでなくLinuxbrewでも動作し、クロスプラットフォームに動作する

また環境ごとにHomebrew Caskやmas-cliを使用している場合はBrewfile内で条件分岐させて必要なものだけ読み込む工夫が有効的。

それぞれの環境で必要なものだけOSによる条件分岐で分けることでBrewfileは本領を発揮できそう。

あーるあーる

Brewfileとは

Homebrew(Linxubrew)で使用されるパッケージリストファイル。

リポジトリ
https://github.com/Homebrew/homebrew-bundle

Homebrewでのパッケージ管理をしやすくしてくれる。

# Homebrew/bundleを有効化
$ brew tap Homebrew/bundle

# パッケージリストを新規作成する
$ brew bundle dump

以上のコマンドでユーザーディレクトリに Brewfile というファイルが生成される。
このファイルにはBrewで管理しているパッケージの依存関係がリスト形式で記述されている。

# Brewfileからパッケージをインストール
$ brew bundle

とすることで新しい環境でもリストから一括でパッケージをインストールしてくれる優れもの。
Nodeでいうpackage.jsonのようなイメージ。

あーるあーる

LinuxでもBrewは使える

Homebrewと調べるとmacOS向けのパッケージ管理ツールである、macOSでの環境構築方法が多くヒットするが実はLinuxでもLinuxBrewとして使用することができる。

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

LinuxBrewとHomebrewは同じワンライナーでインストール可能となっておりm上のスクリプトでOSの判定を行い、Homebrew or Linuxbrewを環境に応じて構築してくれる。

LinuxbrewについてはWSL2等でも使用可能。

詳しくは以前投稿した 今更ながら重い腰を上げてWSL2へHomebrewをインストールした を参照。

あーるあーる

【本題】dotfilesでBrewfileを有効活用できないか

環境構築をする際にdotfilesを使用することがある。たdotfilesとはファイルの先頭に「.(ドット)」がつく隠しファイルや設定ファイルの総称である。

この隠しファイル・設定ファイル群を効率的に管理し新しい環境にデプロイしやすくするスクリプト等をdotfilesと呼ぶことがある。

https://github.com/topics/dotfiles

実際にdotfilesを構築する中でBrewfileを使用してWSL2(Ubuntu)とmacOSの環境構築を効率的にできないかとふと思った。すでにそれぞれの環境でHomebrew・Linuxbrewを使用してパッケージ管理を行っているのでBrewfileをクロスプラットフォーム化できるなら楽になりそう。

あーるあーる

Brewfile内に条件分岐を設ける

Brewfileの実態はRubyで書かれたスクリプトファイルなので、構文内でRubyの条件分岐が使用できるらしい。

以下のDotfileリポジトリに含まれるBrewfileでOSの判定を行っていたので参考にやってみる。

https://github.com/nicknisi/dotfiles

if OS.mac?でmacOS、elsif OS.linux?でLinuxの環境を判定している模様。

Brewfileに組み込んでテスト。
環境で判定したいので、MacAppStoreからアプリをインストールしてくれるパッケージマネージャmas-cliでのインストールで判定する。

mas-cli
https://github.com/mas-cli/mas

Linuxではmas-cliを使用できないためエラー回避のために読み込まないよう制御する。

Brewfile
# mas
# Bitwarden(パスワード管理ソフト)をAppStoreからインストール
if OS.mac?
  mas "Bitwarden", id: 1352778147
end

上の条件でOSがmacOSのときだけmasを使用してAppStoreからID指定されたアプリをインストールするようになる。

あーるあーる

デバッグしてみる

うまく条件分岐が機能するか、この状態でデバッグを行ってみる。

# --fileでDotfilesの中のBrewfileを指定 --debugでデバッグ
$ brew bundle --file '~/dotfiles/Brewfile' --debug

デバッグを実行すると依存関係をBrewfileをもとに調べてくれる。実行するとログが流れるのでここでうまくBrewfilleを読み込めているか判定する。

Homebrew Bundle complete! Brewfile dependencies now installed.と表示されれば完了。

Macでデバッグを実行した場合、masが読み込まれBitwardenの依存関係が解決している旨のログが出力された。

Using zoom
Using Bitwarden
...

正しくインストールされていることが確認できた。本当に条件分岐しているか確かめるために条件をLinuxにしてmacOS上で実行してみる。

if OS.linux?
  mas "Bitwarden", id: 1352778147
  ...
end

条件をLinuxにしているため、macOS上では読み込まれない。

Using zoom
/opt/homebrew/Library/Homebrew/shims/shared/git --version
Homebrew Bundle complete! 80 Brewfile dependencies now installed.

条件分岐が正しく動作していることが確認できた。

あーるあーる

WSL2(Ubuntu)でBrewfileを動かしてみた

先程、条件分岐したBrewfileをWSL2(Ubuntu)の環境で実行してみる。
UbuntuはLinuxなので条件分岐の結果としてMac向けのBottle tap、brew install、mas install が動作しないようになっている。

上述したmas-cli等は除外しているのでインストールされることはない。またBrewfileにLinux用のbottleが存存在しないもの、blueutilやlibiconvはスキップされた。

Skipping blueutil (no bottle for Linux)
...
Skipping libiconv (no bottle for Linux)

Homebrew Bundle complete! 32 Brewfile dependencies now installed.

ここでCaskやmasが含まれていた場合には同じようにスキップされるようになっている。
試しに条件分岐を全部はずしてbrew bundleしてみたところtap "homebrew/cask"tap "homebrew/cask-versions"が実行された。しかし、CaskはLinuxでサポートされていないためスキップされる。

# Spotifyがスキップされたところ
Skipping cask spotify (on Linux)
このスクラップは2022/01/30にクローズされました