🎃

brew install --caskの"cask"ってなんなのか

に公開

TL;DR

brew install --caskの「cask」は、macOSのGUIアプリケーションをHomebrew流で管理するためのRuby DSL(Domain Specific Language)ベースの仕組みです。従来の「.dmgをダウンロード→ドラッグ&ドロップ」を自動化し、コマンドライン一発でアプリをインストール・管理できる優れものです。

はじめに

macOSでアプリをインストールするとき、brew install gitのように"cask"を指定せずにインストールすることもあれば、brew install --cask google-chromeのように"cask"を指定してインストールすることもあります。

今まで、ライブラリのインストールセクションの案内に従っているだったのですが、不思議に思ったので調べてみました。

Homebrew Caskとは何か

Homebrew Caskは、HomebrewをベースにしたmacOSのGUIアプリケーション管理ツールです。2012年に独立したプロジェクトとして開始され、2014-2015年頃にHomebrew本体に統合されました。

https://linuxcommandlibrary.com/man/brew-cask

https://github.com/Homebrew/homebrew-cask

基本的な使い方はこんな感じです。

# Google Chromeをインストール
brew install --cask google-chrome

# インストールされたcaskの一覧表示
brew list --cask

# アンインストール
brew uninstall --cask google-chrome

従来の手動インストールと比べて、以下のような利点があります。

  • ダウンロード、チェックサム検証、インストールが自動化
  • アンインストールもクリーンに実行
  • バージョン管理とアップデートの統一
  • Brewfileによる環境の再現性

これ以前は、Mac Storeに存在しないGUIアプリケーションは手動でのインストールが必要だったのだとか。

技術的な仕組みとアーキテクチャ

「cask」の語源と意味

「cask」は元々「樽」を意味する英単語です。Homebrewが「brewery(醸造所)」をテーマにしているため、パッケージを「formula(醸造レシピ)」、バイナリパッケージを「bottle(ボトル)」、外部リポジトリを「tap(蛇口)」と呼んでいます。

その流れで、GUIアプリケーションを格納する「樽」として「cask」という名前が採用されました。技術的にはRuby DSLで記述された設定ファイルのことです。

https://stackoverflow.com/questions/46403937/what-is-the-difference-between-brew-install-x-and-brew-cask-install-x

HomebrewとHomebrew Caskの違い

https://stackoverflow.com/questions/46403937/what-is-the-difference-between-brew-install-x-and-brew-cask-install-x

通常のHomebrewとCaskの大きな違いは、インストール対象とインストール方法にあります。

通常のHomebrew(formula)の場合

  • 主にコマンドラインツールやライブラリ
  • ソースコードからビルド、またはバイナリ(bottle)を使用
  • /opt/homebrew/Cellar(Apple Silicon)または/usr/local/Cellar(Intel)にインストール
  • シンボリックリンクで/opt/homebrew/binにバイナリを配置

Homebrew Cask(cask)の場合

  • macOSのGUIアプリケーション、フォント、プラグイン
  • 配布済みの.dmg、.pkg、.appファイルを使用
  • /Applicationsフォルダにアプリを配置
  • チェックサム検証

インストールプロセスの詳細

Caskでアプリをインストールする際の内部処理はこんな感じになってます。

  1. caskファイル(Ruby DSL)の解析
  2. URLからアプリケーションファイルのダウンロード
  3. SHA256チェックサムによる完全性検証
  4. macOSの隔離属性(quarantine)の処理
  5. .dmgのマウントまたは.pkgの展開
  6. アプリケーションの/Applicationsへの移動
  7. 必要に応じて追加的なセットアップ処理

この一連の流れが、従来の手動作業を完全に自動化しています。

caskファイルの構造とRuby DSL

Google Chromeを例に、実際のcaskファイルを見てみます。

https://github.com/Homebrew/homebrew-cask/blob/master/Casks/g/google-chrome.rb

cask "google-chrome" do
  version "138.0.7204.184"
  sha256 :no_check

  url "https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
  name "Google Chrome"
  desc "Web browser"
  homepage "https://www.google.com/chrome/"

  livecheck do
    url :url
    strategy :extract_plist do |versions|
      versions.values.filter_map(&:short_version).first
    end
  end

  auto_updates true
  depends_on macos: ">= :big_sur"

  app "Google Chrome.app"
end

この構造の意味をそれぞれ以下から見ていきます。

https://docs.brew.sh/Cask-Cookbook

基本メタデータ

  • version でバージョン指定(:latestで最新版を自動取得)
  • sha256 でファイル整合性の検証(セキュリティ対策)
  • url でダウンロード元の指定
  • namedesc でアプリケーションの説明

自動更新チェック(livecheck)

livecheckブロックは、新しいバージョンが公開されたかを自動チェックする仕組みです。ここではGoogle Chrome の公式APIから最新バージョン情報を取得しています。

アーティファクト指定

app "Google Chrome.app"で、インストールするアプリケーションバンドルを指定。これにより、.dmgファイル内のアプリが/Applicationsフォルダに移動されます。

完全削除(zap)

zapブロックで、アンインストール時に削除する関連ファイルやフォルダを指定できます。これにより、手動では見つけにくい設定ファイルやキャッシュも含めて、クリーンな削除が可能になります。

https://github.com/Homebrew/homebrew-cask/blob/master/Casks/a/alfred.rb

Google Chromeのファイルでは指定されていませんでしたが、以下のように記載可能なようです。

cask "alfred" do
  version "5.7,2302"
  sha256 "aa74fb1c861749e6c6600f506f092edc05849cbeba49dd11aabbf47d071607c3"

  url "https://cachefly.alfredapp.com/Alfred_#{version.csv.first}_#{version.csv.second}.tar.gz"
  name "Alfred"
  desc "Application launcher and productivity software"
  homepage "https://www.alfredapp.com/"

  livecheck do
    url "https://www.alfredapp.com/app/update#{version.major}/general.xml"
    strategy :xml do |xml|
      version = xml.elements["//key[text()='version']"]&.next_element&.text
      build = xml.elements["//key[text()='build']"]&.next_element&.text
      next if version.blank? || build.blank?

      "#{version.strip},#{build.strip}"
    end
  end

  auto_updates true

  app "Alfred #{version.major}.app"

  uninstall quit:       "com.runningwithcrayons.Alfred",
            login_item: "Alfred#{version.major}"

  zap trash: [
    "~/Library/Application Support/Alfred",
    "~/Library/Caches/com.runningwithcrayons.Alfred",
    "~/Library/Cookies/com.runningwithcrayons.Alfred.binarycookies",
    "~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist",
    "~/Library/Preferences/com.runningwithcrayons.Alfred.plist",
    "~/Library/Saved Application State/com.runningwithcrayons.Alfred-Preferences.savedState",
  ]
end

まとめ

brew install --caskの「cask」は、単なる樽の比喩ではなく、macOSのGUIアプリケーション管理に特化した技術的な仕組みでした。Ruby DSLベースの柔軟な設計により、複雑なインストール要件にも対応できる優秀なパッケージ管理システムです。

特に印象的だったのは、セキュリティ機能との統合や、完全削除機能(zap)の存在。macOS環境での実用性を徹底的に考慮した設計になってます。

macOSでの開発環境構築で何も考えずに、brew install --caskのコマンドを叩いていましたが、少し解像度が上がりスッキリしました。
(※今までnpm install --save-devみたいにインストール場所の指定の亜種かなにかだと思っていたのは秘密です)

参考文献

Discussion