GeekFactory

int128.hatenablog.com

JVMベースのコマンドラインツールをHomebrewで配布する

JavaVMで動くコマンドラインツールHomebrewで配布する方法を説明します.JavaScala,Groovyなどで書かれたツールMacユーザに配布する際に役立ちます.

Homebrewとは

Mac OS Xで使えるパッケージ管理システムの一つにHomebrewがあります.

Homebrewを使うと,ユーザは brew コマンドを実行するだけで新しいパッケージをインストールできます.また,デベロッパーはわざわざインストーラを用意する必要がなくなり,パッケージ本体とメタデータ(Formula)を公開するだけでソフトウェアを提供できるようになります.

例えば,OS Xopensslを使いたい場合は,下記のコマンドを実行するだけでパッケージのダウンロードやビルドを行ってくれます.

brew install openssl

また,開発中の最新版を使いたい場合は,--HEAD引数を渡すことでリポジトリからHEADを取得してビルドを行ってくれます.

brew install --HEAD openssl

Homebrewでパッケージを公開するには2つの方法があります.

  1. ビルド済みのバイナリを配布する.インストールが短時間で済む.
  2. ソースコードを配布する.インストール時にビルドを行うので時間がかかるが,マシンに合わせた最適化ができる.

JavaVMの場合はマシンに合わせた最適化を行う必要がないため,1のビルド済みバイナリを配布するとよいでしょう.

ここでは,GitHub ReleasesにAll-in-One Jar(Fat Jar)がリリースされている前提で話を進めます.

Formulaを作成する

HomebrewではFormulaと呼ばれるDSLメタデータを記述します.FormulaにはパッケージのURLやインストール手順を記述します.

テンプレートを生成する

Formulaを一から書くのは大変なので,Homebrewにはテンプレートを生成する機能があります.brew createコマンドの引数にパッケージのURLを渡して実行すると,テンプレートが生成された状態でエディタが起動します.

例えば,下記を実行すると,gsshという名前のFormulaが生成されます.

brew create https://github.com/int128/groovy-ssh/releases/download/v1.1.5/gssh.jar

brew createコマンドは,URLからFormulaの名前やバージョンを自動判別してテンプレートを生成してくれます.ただし,URLの形式によってはFormulaの名前やバージョンを明示的に指定する必要があります.

Formulaを書く

私が公開している Groovy SSH (SSH automation tool based on Groovy DSL) の例を示します.詳細はコメントを参照してください.

class Gssh < Formula
  # メタデータを書く
  homepage "https://github.com/int128/groovy-ssh"
  url "https://github.com/int128/groovy-ssh/releases/download/v1.1.5/gssh.jar"
  version "1.1.5"  # URLからバージョンを自動判別してくれないため明示的に指定している
  sha1 "c050c74b5d491e836d8210758369466162abf946"

  # リポジトリのHEADからビルドする場合のリポジトリ
  head "https://github.com/int128/groovy-ssh.git"

  # JavaVMの依存性を明示
  depends_on :java => "1.6+"

  # ビルド手順を書く
  def install
    if build.head?
      # リポジトリのHEADからビルドする場合の手順(git cloneの後にやることを書く)
      system "./gradlew", "shadowJar"
      libexec.install "build/libs/gssh.jar"
    else
      # ビルド済みバイナリを配置する場合の手順(ダウンロードの後にやることを書く)
      libexec.install "gssh.jar"
    end
    bin.write_jar_script libexec/"gssh.jar", "gssh"
  end

  # テストコードを書く
  test do
    system "gssh"  # ここではgsshコマンドが利用可能であることを検証している
  end
end

ここではFormulaのDSLを簡単に説明します.

まず,Formulaのメタデータを書きます.下記は必須です.また,URLからバージョンを自動判別できない場合はversionを明示的に指定する必要があります.

  • homepage - パッケージのWebサイトを指定します.これがないとPull Requestをacceptしてもらえません.
  • url - パッケージのダウンロード元URLを指定します.
  • sha1 - SHA-1ダイジェストを指定します.

実行に必要な依存関係は depends_on で指定できます.JavaVMを指定する方法は上記例の通りです.

ちなみに,sha1の計算にはbrew fetchコマンドが便利です.

brew fetch https://github.com/int128/groovy-ssh/releases/download/v1.1.5/gssh.jar

Formulaをテストする

まず,ローカル端末でFormulaをインストールして動作を確認します.

brew install gssh
gssh --version

問題なく動くことを確認したら,Formulaの検査とテストを行います.

brew audit --strict gssh
brew test gssh

以上で問題なければ,Formulaを公開できます.

Formulaを公開する

HomebrewはFormulaのセットをGitHubのリポジトリで管理しています.したがって,GitHubリポジトリにPull Requestを送ることで,自分のFormulaを世界に公開できます.

まず,GitHubのリポジトリをForkして自分のリポジトリを作ります.そして,ローカル端末にあるFormulaをコミットして,自分のリポジトリにpushします.

# リポジトリを最新にする
brew update

# 新しいブランチにFormulaをコミットする
cd "$(brew --cellar)"
git checkout -b something
git commit -a

# 自分のリポジトリにブランチをpushする
git origin add you https://github.com/you/homebrew
git push you something

ブランチをpushできたらPull Requestを作成します.Pull RequestのタイトルはFormulaの名前とバージョンにします.

Formulaに問題がなければ,コミットがmasterに取り込まれてPull Requestはクローズされます.何か問題があればコメントに書いてくれます.

まとめ

JavaVMで動くコマンドラインツールHomebrewで配布する手順を説明しました.カジュアルに登録できるので,気軽に公開してみてはいかがでしょうか.

なお,本稿では説明しませんでしたが,Homebrewでは指定したリポジトリからFormulaをインストールすることも可能です.この機能を使えば,本家のリポジトリにPull Requestを出さなくてよいので,さらにカジュアルにFormulaを公開できます.詳細はbrew tapで検索してみてください.

参考文献