Homebrew vs Boxen を比較して、brewproj に着手

·1 分で読めます

前の投稿で書いたとおり、連休中、開発環境を整理しながら、同僚の開発環境を構築している Boxen から Homebrew へ移行できないかと、技術検証していました。

結論、それぞれ Pros. / Cons. があり、まだ Homebrew で構築するには足りないものがあるなぁ、と思った次第です。

Package 管理は Brewfile だけでやるのが楽。

例えば、Boxen で VMWare Fusion と tree をインストールしたい場合、

  • Puppetfilegithub "vmware_fusion","1.1.0" を追加
  • modules/people/manifests/$USER.pp に以下を追加:
    • include vmware_fusion
    • package { 'tree': ; }

の2工程を踏み、boxen スクリプトを実行します。

script/boxen

さらに VMWare Fusion がアップデートした場合には、Puppetfile を更新します。

それをせずに、手動で VMWare Fusion をアップデートし、boxen スクリプトを再度実行した場合、init.pp に宣言されているバージョンにデグレードしてしまいます。

それに対して、Homebrew は Brewfile に以下の4行を書き、

update
upgrade
install tree
cask install vmware-fusion

brew bundle コマンドを実行するだけで、常に最新のソフトウェアをインストールしてくれます。

brew bundle

定義ファイルとバージョンの管理は Homebrew に軍配があがります。

Ruby vs Puppet

Boxen は Puppet です。Ruby と違って、システムの自動管理の目的にできたものなので、プログラミング言語としての機能はそこまで高度ではありません。

ライブラリを Ruby 書いて、拡張していくことができます。

Puppet の定義ファイルはシンプルに書けるのですが、構築で躓くと、結局 Puppet の Ruby のソースを読まざるを得なくなります。

これを扱う同僚のほとんどがインフラではなく、アプリケーションエンジニアなので、Puppet を学習してもらうのは、多少コストが高いです。

Homebrew の Formula も DSLできれいな定義ファイルが書けるので、特に Puppet が優位でもないと思います。

# 前に Chef でプログラマティックに recipe を書きすぎて注意されたので、Ruby 乱用厳禁ですが。

では、Boxen はオワコンでおk?

いいえ。

Boxen はバイナリをキャッシュする

Boxen は、sync コマンドで Homebrew の Celler 配下、rbenv でインストールした Ruby をそれぞれ tarball にしてアップロードし、次にセットアップする人は、ビルドする必要がありません。

https://github.com/boxen/our-boxen/blob/master/script/sync

Ruby, Homebrew は Boxen が独自に拡張している機能です: rubybuild.rb, boxen-bottle-hook

NodeJS は nodenv に元々その機能があるみたいです: nodenv-install

Project で開発環境構築

この機能が一番大きくて、Project Manifests を書いたら、ソースコードをチェックアウトし、依存しているモジュール、DB 設定など、諸々面倒を見てくれます。

ということで、Homebrew 拡張に着手します。

前述の様に Boxen にも良い所があり、とはいえ、Puppet が面倒臭い、設定が複雑など、超えられない壁があるので、Homebrew を拡張して、それらの足りない機能を補うモジュールを開発しようと思います。

ProjectFormula

まずは、Project Manifests と同じ様なことをできるようにしました。

1. 個人、組織で Tap を作成する。

  • リポジトリを作成。 例:kaizenplatform/homebrew-kaizenplatform
  • 基礎クラス ProjectFormula: lib/project_formula.rb
  • プロジェクト Formula

こんな感じで Formula を書くと、

  • 依存モジュールをインストール (Homebrew標準機能)
  • プロジェクトコードのチェックアウト
  • config/database.yml をインストール
  • .ruby-version に入っている Ruby を rbenv でインストール
  • Bundler のインストール、bundle install の実行
  • MySQL 起動
  • Rake タスク: DB 作成+マイグレーション

を行ってくれます。

lib/project_formula.rb:

2. brew tap コマンドで Tap をインストール。

brew tap kaizenplatform/kaizenplatform

3. brew install でプロジェクト環境構築

brew install planbcd

使ってみていい感じだったので、Homebrew Cask みたいにしたい。

上記で、必要最低限の環境構築はできました。

さらにこれをワークフロー化するために、Homebrew Cask みたいにサブコマンドを作って、サクサク Formula を作成できるようにしたいです。

とりあえず、組織とリポジトリだけ作りました。 brewproj/homebrew-proj

ちゃんと OSS プロジェクトとしてやっていければと思います。