Xcode でコマンドラインアプリを作って Homebrew でインストールできる様にする


## 対象

Xcode でコマンドラインアプリを作成し、オレオレ HomeBrew リポジトリを作って GitHub で公開するケースを想定しています。
利用している Homebrew のバージョンは `0.9.5` です。

## まずはアプリ作成

Xcode で Mac 用コマンドラインアプリを作成します。
`Archive` して export したアプリを、zip で固めて GitHub の Releases に登録します。

## リポジトリ作成

Prefix に `homebrew-` と付けたリポジトリがオレオレ Homebrew リポジトリとして利用できます。例えば GitHub に `homebrew-repo` といったリポジトリを作成します。

## Formula 作成

Homebrew でアプリをインストールさせる為のレシピである  `Formula` を作成します。

### インストールさせるアプリの URL を取得

まずは先ほど GitHub の Releases に登録したアプリの URL をコピーします。
https://github.com/yourname/yourtool/releases/download/0.1.0/yourtool-v-0.1.0.zip
の様な URL になっていると思います。

### Formula をテンプレートから生成

```terminal
$ brew create {url}
```

を実行すると、テンプレートから Formula を生成してくれます。
`{url}` には先ほどコピーしておいた URL を入力します。

```ruby
# Documentation: https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Formula-Cookbook.md
#                /usr/local/Library/Contributions/example-formula.rb
# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!

class yourtool < Formula
  desc ""
  homepage ""
  url "https://github.com/yourname/yourtool/releases/download/0.1.0/yourtool-v-0.1.0.zip"
  version "0.1.0"
  sha256 "e8fd4a24bc0cf69aead75c844ad080e5e26efc6db76357b226e182cbc27ae22a"

  # depends_on "cmake" => :build
  depends_on :x11 # if your formula requires any X11/XQuartz components

  def install
    # ENV.deparallelize  # if your formula fails when building in parallel

    # Remove unrecognized options if warned by configure
    system "./configure", "--disable-debug",
                          "--disable-dependency-tracking",
                          "--disable-silent-rules",
                          "--prefix=#{prefix}"
    # system "cmake", ".", *std_cmake_args
    system "make", "install" # if this fails, try separate make/make install steps
  end

  test do
    # `test do` will create, run in and delete a temporary directory.
    #
    # This test will fail and we won't accept that! It's enough to just replace
    # "false" with the main program this formula installs, but it'd be nice if you
    # were more thorough. Run the test with `brew test yourtool`. Options passed
    # to `brew install` such as `--HEAD` also need to be provided to `brew test`.
    #
    # The installed folder is not in the path, so use the entire path to any
    # executables being tested: `system "#{bin}/program", "do", "something"`.
    system "false"
  end
end

```

こんな感じの Formula が生成されます。

### Formula を編集

編集して、以下の様な感じにします。

```ruby
class yourtool < Formula
  desc "your tool description"
  homepage "your tool homepage url"
  url "https://github.com/yourname/yourtool/releases/download/0.1.0/yourtool-v-0.1.0.zip"
  version "0.1.0"
  sha256 "e8fd4a24bc0cf69aead75c844ad080e5e26efc6db76357b226e182cbc27ae22a"

  def install
    bin.install Dir["Contents/*"]
    bin.install_symlink "MacOS/yourtool"
  end
end

```

テンプレートから生成された状態から、変更するのはコメントの削除と、`def install` メソッド内の変更です。

`bin.install` メソッドは、zip の状態で Download されたアプリから、必要なファイルを `/usr/local/Cellar/yourtool/0.1.0/bin/` 以下に展開します。

export されたアプリのディレクトリ構成は以下の様になっていますので、

```
yourtool.app
└── Contents
    ├── Frameworks
    ├── Info.plist
    ├── MacOS
    │   └── yourtool
    ├── PkgInfo
    └── _CodeSignature
```

`bin.install Dir["Contents/*"]` と記述する事で、Contents 以下の動作に必要なファイルを全て `/usr/local/Cellar/yourtool/0.1.0/bin/` 配下に展開するという動作になります。

続く `bin.install_symlink "MacOS/yourtool"` では、`/usr/local/Cellar/yourtool/0.1.0/bin/` 配下に展開されたファイルのうち、指定したファイルの symlink を`/usr/local/bin` 配下に貼るという動作をします。

今回のケースではバイナリである `yourtool` をパスが通った場所に symlink します。

### Formula を push する

上記保存されますと、`/usr/local/Library/Formula/` 配下に `yourtool.rb` といった名前で配置されます。これを先ほど作成した `homebrew-repo` に commit して push します。

## brew install する

```terminal
$ brew install yourname/repo/yourtool
```

を実行すると、オレオレリポジトリを `brew tap` した後、続けて Install してくれます。
`which yourname` してパスが通っている事を確認、実行して問題無ければ成功です。

## 本家に登録してもらう

ある程度本気のアプリであれば、本家の Homebrew リポジトリを Fork して Formula を PullRequest して登録してもらうと良いと思います。

## 参考

[Swiftで書いたコマンドラインツールをHomebrewでインストールできるようにする](
http://blog.ishkawa.org/2015/02/18/1424261348/)
[HomeBrewで自作ツールを配布する](http://deeeet.com/writing/2014/05/20/brew-tap/)
[Formula Cookbook](https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Formula-Cookbook.md#formula-cookbook)