macOSでのパッケージ管理

しばらく前にMacbook Proを入手したので、有名っぽいアプリをどんどんインストールしていたのですが、Homebrewというパッケージ管理システムを知ったので、そちらでの管理に切り替えることにしました。

## パッケージ管理システムを使うメリット
* ターミナルからインストール、アンインストールができる
* アップデートをまとめて行える
* OSの再インストール時など環境移行時に一括でインストールできる

## 使用ツール
正確には違うのかもしれませんが、下記の考え方をするとわかりやすかったです。

|ツール|管理対象|
|---|---|
|Homebrew|CUIアプリ|
|Homebrew Cask|GUIアプリ|
|mas-cli|Mac App Storeにあるアプリ|
※Homebrew Caskとmas-cliでは、同じアプリが含まれる場合があるので、その場合どちらで管理するか決めておくと良いです。

## パッケージマネージャーのインストール

### Xcodeのインストール
意識して使うわけではないため使用ツールには記載していませんが、Homebrewを使うにはXcodeが必要です。
普通にApp Storeからインストールすると時間もかかり、消費する容量もかなり使ってしまうので、Xcodeのコマンドラインツールだけ入れます。

ターミナルを起動し、下記を実行します。

```
$ xcode-select --install
```
ダイヤログが表示されインストールするか聞かれるので、インストールを押します。


### Homebrewのインストール

```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
 上記は変更になる場合があるので、[Homebrew](https://brew.sh/index_ja)から最新のものをコピーして実行します。


Homebrewをインストールする場所に権限が無いと表示される場合は、下記を実行します。

```
//intel Macの場合
 $ sudo chown -R $(whoami):admin /usr/local

Apple Siliconの場合
 $ sudo chown -R $(whoami):admin /opt/homebrew
```
 whoamiは現在のユーザーという意味です。


### Homebrew Caskのインストール
Homebrew CaskはHomebrewのインストールに含まれるので、インストール不要です。

### mas-cliのインストール
Homebrewのパッケージとしてインストールします。

```
$ brew install mas
```

## パッケージマネージャーの使用

### インストールするパッケージを探す
[Homebrew](https://formulae.brew.sh/formula/)
パッケージ名を記録しておきます。

[Homebrew Cask](https://formulae.brew.sh/cask/)
パッケージ名を記録しておきます。

[Mac App Store](https://apps.apple.com/jp/genre/mac/id39?mt=12)
IDを記録しておきます。
IDは、URL末尾の「id406056744?mt=12」のような文字列のidと?の間の数字です。

### パッケージのインストール


```
$ brew install (package name)
$ brew cask install (package name)
$ mas install (package ID)
```
mas-cliでのインストールは、Apple IDと紐付けるため一度App Storeから入手しておく必要があります。
Affinity DesignerなどのようにApp Storeと販売元が併売している場合、販売元から直接購入するとmasでのインストールはできません。(Affinity製品はbrew --caskでのインストールに対応したようです)


#### インストール時にディレクトリが存在しないというエラーが出る場合
フォルダを作成し、権限を付けます。

```
$ sudo mkdir /usr/local/(directory name)
$ sudo chown -R $(whoami) /usr/local/(directory name)
```

### パッケージのアンインストール

```
$ brew uninstall (package name)
$ brew cask uninstall (package name)
$ mas uninstall (package ID)
```

### アップデートがあるパッケージ一覧

```
$ brew outdated
$ brew outdated --cask
$ mas outdated
```

### パッケージのアップデート
パッケージマネージャーの管理下から外れてしまうため、パッケージ側のアップデート機能や、Mac App Storeでのアップデートはせず、パッケージマネージャー側でアップデートします。

※ ~~Catalinaにアップデートしたところ、mas outdatedやmas upgradeが動作していないようなので、少し面倒ですが一度アンインストールして再インストールして対応しています。~~　mas1.8.1で動くようになったようです。

```
$ brew upgrade
$ brew upgrade --cask
$ mas upgrade
```
Caskでアップデートしない設定になっているパッケージもアップデートするには、--greedyオプションをつけます。```brew upgrade --cask --greedy```
ugradeの後にパッケージ名やIDを付けると、パッケージを個別にアップデートできます。


### インストール済みパッケージ一覧

```
$ brew list
$ brew list --cask
$ mas list
```
### 診断
インストールしたパッケージの管理状態を診断します。

```
$ brew doctor
```
You have unlinked kags in your Cellarと表示されたらリンクを修正します。
  
```
$ brew unlink (package name)
$ brew link (package name)
$ brew cleanup
```

## 環境移行
### Brewfileの生成
新しい環境に引っ越す前に、インストール済みのパッケージを Brewfileに残します。

```
$ brew bundle dump
```
カレントディレクトリ内に Brewfile が生成されるので、ファイルの中を除くと、brew、cask、masが一括で保存されています。

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

新しい環境にBrewfileをコピーし、同じディレクトリ内に移動して下記を実行

```
$ brew bundle 
```


## Brewfileサンプル

https://github.com/takeshisakuma/brewfile

### brew
|アプリ名  |パッケージ名  |
|---|---|
|Ansible|ansible|
|bat|bat|
|carthage|carthage|
|chezmoi|chezmoi|
|Deno|deno|
|exa|exa|
|FFmpeg|ffmpeg|
|GitHub command-line tool|gh|
|ghq|ghq|
|gibo|gibo|
|Git|git|
|ImageMagick|imagemagick|
|lazydocker|lazydocker|
|lazygit|lazygit|
|mas-cli|mas|
|MySQL|mysql|
|peco|peco|
|procs|procs|
|pyenv|pyenv|
|Python|python|
|ripgrep|ripgrep|
|Sketchybar|sketchybar|
|starship|starship|
|tig|tig|
|tmux|tmux|
|tree|tree|
|vim|vim|
|WebP|webp|
|Yabai|yabai|

### cask
|アプリ名  |パッケージ名  |
|---|---|
|Ableton Live Lite|ableton-live-lite|
|Adobe Creative Cloud|adobe-creative-cloud|
|Adobe Creative Cloud Cleaner Tool|adobe-creative-cloud-cleaner-tool|
|Affinity Designer|affinity-designer|
|Affinity Photo|affinity-photo|
|Affinity Pubblisher|ffinity-publisher|
|Alfred|alfred|
|Almighty|almighty|
|AltTab|alt-tab|
|Android Studio|android-studio|
|AppCleaner|appcleaner|
|Arc Browser|arc|
|Authy|authy|
|Battery Buddy|battery-buddy|
|Blender|blender|
|BestRes|bestres|
|Boostnote|boostnote|
|CotEditor|coteditor|
|CheatSheet|cheatsheet|
|Chromium|Chromium|
|claude|claude|
|Clipy|clipy|
|Cron|cron|
|cursor|cursor|
|Cyberduck|cyberduck|
|Dash|dash
|Deckset|deckset|
|Diffmerge|diffmerge|
|Discord|discord|
|Docker|docker|
|Docker toolbox|docker-toolbox|
|draw.io|drowio|
|Dropbox|dropbox|
|Dynalist|dynalist|
|Eagle|ogdesign-eagle|
|edge|microsoft-edge|
|eqMac|eqmac|
|Fantastical|fantastical|
|Figma|figma|
|Firefox|firefox|
|Firefox Nightly|firefox-nightly|
|FontBass|fontbase|
|Free Ruler |free-ruler|
|Ricty Diminished|font-ricty-diminished|
|Funter|funter|
|GitHub|github|
|Google Chrome|google-chrome|
|Google Chrome Canary|google-chrome-canary|
|Google Drive File Stream|google-drive-file-stream|
|Google 日本語入力|google-japanese-ime|
|Google Web Designer|google-web-designer|
|Gyazo|gyazo|
|He3|he3-app/he3/he3|
|HyperSwitch|hyperswitch|
|ImageAlpha|imagealpha|
|ImageOptim|imageoptim|
|iTerm2|iterm2|
|Kap|kap|
|keyclu|keyclu|
|Krita|krita|
|macwinzipper|macwinzipper|
|magicavoxel|magicavoxel|
|MySQL Workbench|mysqlworkbench|
|ngrok|ngrok|
|Notion|notion|
|Obsidian|obsidian|
|OnlySwitch|only-switch|
|Onyx|onyx|
|pg-commander|pg-commander|
|pixelsnap|pixelsnap|
|postman|postman|
|Prepros|prepros|
|processing|processing|
|Proxyman|proxyman|
|Quick Look Plugin for WebP Files|WebPQuickLook|
|Raycast|raycast|
|rectangle|rectangle|
|Responsively|responsively
|Screen Studio|screen-studio|
|Scroll Reverser|scroll-reverser|
|Sequel Ace|sequel-ace|
|setapp|setapp|
|SketchBook|sketchbook|
|Skitch|skitch|
|Skype|skype|
|Shupapan|shupapan|
|Slack|slack|
|slate|slate|
|Sourcetree|sourcetree|
|Spotify|spotify|
|tableplus|tableplus|
|The Unarchiver|the-unarchiver|
|tor|tor-browser|
|TimeMachineEditor|timemachineeditor|
|Turbo Boost Switcher|turbo-boost-switcher|
|Twitch|twitch|
|Unity|unity|
|Unity Hub|unity-hub|
|VitalSigns|vitalsigns|
|VirtualBox|virtualbox|
|Visual Studio Code|visual-studio-code|
|VLC|vlc|
|WezTerm|wezterm|
|zen browser|zen-browser|

※Adobe Creative Cloudは、インストーラーを下記にダウンロードするだけです。
/usr/local/Caskroom/adobe-creative-cloud/latest/




### mas
|アプリ名  |ID  |
|---|---|
|1Password 7|1333542190|
|Amazon Prime Video|545519333|
|Amphetamine|937984704|
|Any.do|944960179|
|Blurred|1497527363|
|BrowseShot|615916400|
|Contrast|1254981365|
|Dropover|1355679052|
|Feedly|865500966|
|Focus To-Do|1258530160|
|ForkLift|412448059|
|Gifski|1351639930|
|iMage Tools|493949693|
|Keynote|409183694|
|HEIC Converter|1294126402|
|Hidden Bar|1452453066|
|LINE|539883307|
|MenubarX|1575588022|
|Micro Sniff|1504024265|
|Microsoft To-Do|1274495053|
|meeter|1510445899|
|Monosnap|540348655|
|motion|434290957|
|Numbers|409203825|
|Model 15 Modular Synthesizer|1041465860|
|Pages|409201541|
|Parallels Desktop|1085114709|
|PDF Converter & Reader|1459989579|
|PicGIF Lit‪e|844918735|
|Playgrounds|1496833156|
|Pocket|568494494|
|QaLL|480452005|
|Quip|1003160018|
|Quiver|866773894|
|RunCat|1429033973|
|Shazam|897118787|
|Spark|1176895641|
|Things|904280696|
|Todoist|585829637|
|Trello|1278508951|
|TweetDeck|485812721|
|Twitter|1482454543|
|Unsplash Wallpapers|1284863847|
|Vector Q|1448103717|
|WebP Converter|1522368690|
|WebToLayers|1458124010|
|Xcode|497799835|
|XMind|1327661892|
|Yoink|457622435|

## インストールしたアプリが起動できないとき
Homebrewに限ったことではないのですが、Mac App Store以外からインストールしたアプリを起動しようとすると、「悪質なソフトウェアか確認できないため開けません」と表示される場合があります。

その場合はControlキーを押しながら起動すると、再度「悪質な～」のウィンドウが表示されますが、「開く」ボタンが追加されているので、クリックすると開けます。
一度起動すると、次からは最初から開けるようになります。