Homebrew で Mac 上のすべてのソフトウェアを管理する
Mac を使い始めてここ数年、ソフトウェアのインストールはどんどん乱れていった。公式サイトからダウンロードした dmg もあれば、App Store から入れたもの、Homebrew で入れたコマンドラインツール、さらにはどこかのインストーラがついでに放り込んでいったものまである。時間が経つうちに、自分のマシンに何が入っているのか、それぞれのソフトウェアがどこから来たのかも、自分では説明できなくなってしまった。
ソフトウェアの削除も面倒なものだ。Mac でアプリをアンインストールするとき、ほとんどの場合はゴミ箱にドラッグするだけだが、そのアプリが ~/Library 以下に残す設定、キャッシュ、各種サポートファイルは、一緒に削除されるわけではない。だからマシンを長く使っていると、~/Library の中に、もう長いこと使っていないソフトウェアが残したものが山のように溜まっていく。最終的には、法外に高い CleanMyMac のようなツールで掃除するか、自分で一つずつ探すしかなくなる。
さらに最近、環境を新しい Apple Silicon の Mac に移すことになり、以前のように一つずつ公式サイトからダウンロードして再インストールするのは、あまりに大変だった。そこで、これから Mac 上のソフトウェアは、Homebrew で入れられるものならすべて Homebrew で入れ、Brewfile にまとめて記録しておくことにした。
Apple Silicon に Homebrew をインストールする
Homebrew は 3.0 から Apple Silicon をネイティブサポートしており、インストールコマンドは以前と同じだ。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
ただし Intel の Mac と違う点が一つあり、Apple Silicon では Homebrew はデフォルトで /opt/homebrew に入り、従来の /usr/local ではない。そのため /opt/homebrew/bin はデフォルトでは PATH に入っていないので、インストール後は ~/.zprofile に次の一行を追加する。
eval "$(/opt/homebrew/bin/brew shellenv)"
brew shellenv は PATH、MANPATH などの環境変数をまとめて出力するので、eval で実行すれば、まとめて設定される。
formula と cask
Homebrew のソフトウェアは二種類に分かれる。formula はコマンドラインツールやライブラリで、たとえば git、ripgrep などがあり、cask はグラフィカルインターフェースを持つアプリケーションで、たとえば Chrome や VS Code だ。
brew install ripgrep
brew install --cask visual-studio-code
以前は cask を入れるのに brew cask install を使っていたが、昨年末の 2.6.0 から、すべての brew cask コマンドは廃止され、brew コマンドに --cask を付ける形に統一されたので、ネット上の古いチュートリアルにある書き方はもう使えない。
フォントも cask で入れられるが、その前に homebrew/cask-fonts という tap を追加する必要がある。
brew tap homebrew/cask-fonts
brew install --cask font-jetbrains-mono
よりきれいにアンインストールする
Homebrew で cask を管理する大きな利点はアンインストールだ。通常のアンインストールではアプリ本体が削除されるだけで、ゴミ箱にドラッグするのとほとんど変わらない。
brew uninstall --cask some-app
しかし --zap を付けると、Homebrew は cask に書かれた zap のルールに従って、そのアプリが ~/Library 以下に残した環境設定、キャッシュ、サポートファイルもまとめて削除する。
brew uninstall --zap --cask some-app
もちろん、すべての cask に zap ルールが書かれているわけではないが、よく使うソフトウェアの大半にはある。少なくとも自分で ~/Library の中を一つずつ探すよりは、はるかに確実だ。
Brewfile
Homebrew でソフトウェアを入れるだけでは、移行時に何を入れたかを自分で覚えておかなければならない。ありがたいことに、Homebrew には bundle というサブコマンドがあり、現在インストールしているものをすべて Brewfile にエクスポートできる。
brew bundle dump --describe --force --file=~/dotfiles/Brewfile
--describe は、各行にソフトウェアの短い説明を追加してくれる。後で見返したときに、見慣れない名前を見て、それが何をするものだったか思い出せない、という事態を避けられる。--force は既存のファイルを上書きする。エクスポートされた Brewfile はおおよそ次のようになる。
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-fonts"
tap "homebrew/core"
# Clone of cat(1) with syntax highlighting and Git integration
brew "bat"
# Modern replacement for 'ls'
brew "exa"
# Simple, fast and user-friendly alternative to find
brew "fd"
# Command-line fuzzy finder written in Go
brew "fzf"
# GitHub command-line tool
brew "gh"
# Search tool like grep and The Silver Searcher
brew "ripgrep"
# Mac App Store command-line interface
brew "mas"
# Password manager that keeps all passwords secure behind one password
cask "1password"
cask "font-jetbrains-mono"
# Web browser
cask "google-chrome"
# Terminal emulator as alternative to Apple's Terminal app
cask "iterm2"
# Control your tools with a few keystrokes
cask "raycast"
# Messaging app with a focus on speed and security
cask "telegram"
# Open-source code editor
cask "visual-studio-code"
mas "Xcode", id: 497799835
最後の行の mas は App Store のコマンドラインツールだ。Xcode のように App Store でしか配信されていないソフトウェアも、これで Brewfile に一緒に書き込める。後ろの数字は App Store での ID だ。
私はこの Brewfile を自分の dotfiles リポジトリに入れ、何かをインストールしたり削除したりするたびに dump し直してコミットしている。こうしておけば、リポジトリには常に現在のマシン上のソフトウェアの完全な一覧がある。
新しいマシンで復元する
新しいマシンでは、Homebrew を入れて dotfiles リポジトリをクローンし、あとはコマンド一つで Brewfile の中身をすべてインストールし直せる。
brew bundle --file=~/dotfiles/Brewfile
tap を追加し、formula と cask を順にインストールしていく。すでに入っているものはスキップされるので、途中で止まっても安心して再実行できる。cask が多くなると全体にはそれなりの時間がかかるが、その間は放っておけばよく、自分で一つずつダウンロードしてインストールするよりはるかに楽だ。
逆にクリーンアップする
Brewfile はインストールに使うだけでなく、逆にクリーンアップにも使える。brew bundle cleanup を実行すると、マシンに入っているが Brewfile に書かれていないものが一覧表示される。
# 只列出来,不删除
brew bundle cleanup --file=~/dotfiles/Brewfile
# 确认没问题之后再真的删除
brew bundle cleanup --force --file=~/dotfiles/Brewfile
だからときどき逆の手順を踏む。Brewfile から不要なソフトウェアを直接削除し、そのうえで cleanup をもう一度実行すると、マシン上からも一緒に削除される。こうして Brewfile とマシンの状態を常に一致させておける。
また brew leaves も便利だ。これは、ほかの formula の依存として入ったものではなく、自分が意識してインストールした formula だけを一覧表示する。自分がどのツールを入れたのか確認したいときには、brew list よりもずっと分かりやすい。
習慣にしていること
- cask で入れられるアプリは、もう公式サイトから dmg をダウンロードしない。
- App Store にしかないアプリは、
masで入れ、同じように Brewfile にも書く。 - ソフトウェアをインストールしたり削除したりするたびに、Brewfile を dump し直してコミットする。
- 更新のときは
brew upgradeに統一する。cask も一緒に更新され、自分で自動更新するアプリだけは追加で--greedy。
これを続けていれば、マシン上のソフトウェアにはすべて出所があり、マシンを乗り換えるときもリポジトリ一つとコマンド一つで済む。新しいマシンが届いた日、リポジトリをクローンしてからソフトウェアをすべて入れ終えるまで、ほぼダウンロードを待っているだけだった。