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를 추가로 붙인다.
이렇게 꾸준히 해 두면 컴퓨터의 소프트웨어에는 모두 출처가 생기고, 컴퓨터를 바꿀 때도 저장소 하나와 명령 한 줄만 있으면 된다. 새 컴퓨터가 도착한 날, 나는 저장소를 클론한 뒤 소프트웨어가 전부 설치될 때까지 거의 다운로드만 기다리고 있었다.