RustのソフトウェアをHomebrewのパッケージにする

# はじめに
「[RustのソフトウェアをSnapcraftのパッケージにする](https://qiita.com/dalance/items/c003f93b7f46713091d1)」に引き続き、Rustのパッケージ化記事第二弾です。前回紹介したSnapcraftは対応プラットフォームはそれなりに多いもののOSとしてはLinuxのみのパッケージマネージャでした。そのためmacOS向けに配布したいとなるとMacPorts/Fink/Homebrewあたりを考える必要があります。

このうち[Homebrew](https://brew.sh/index_ja)は先日2.0がリリースされ、macOSに加えてLinuxとWSL環境がサポートされました。Linux向けは元々Linuxbrewとして独立していたのが統合された形です。私はmacOSの実機を持っていないのですが、HomebrewであればLinux環境でスクリプトを作成してテストできるということで、Homebrewを選びました。

対象ソフトウェアは前回と同様に

[procs：新しいプロセス表示・検索ツール](https://qiita.com/dalance/items/388d98c99ae2857d73e6)
http://github.com/dalance/procs

です。

# 手順
## ビルドスクリプト作成

HomebrewはGitHubのプルリクエストでパッケージ追加や更新を受け付けています。なのでスクリプト作成からスタートです。

```procs.rb
class Procs < Formula
  desc "Modern replacement for ps written by Rust"
  homepage "https://github.com/dalance/procs"
  url "https://github.com/dalance/procs/archive/v0.8.5.tar.gz"
  sha256 "981ff89f8034616a86c4d8bef08a9d835d7d21e0681fd7a39fbf8fb83b7e015c"

  depends_on "rust" => :build

  def install
    system "cargo", "install", "--root", prefix, "--path", "."
  end

  test do
    output = shell_output("#{bin}/procs")
    count = output.lines.count
    assert count > 2depends_on "rust" => :build
    assert output.start_with?(" PID:")
  end
end
```

ビルドスクリプトはRubyのコードになっています。
GitHub上で公開しているソフトウェアであれば、`url`にはGitHubのリリースアーカイブを指定するといいでしょう。
`sha256`はこのアーカイブのSHA256ハッシュ値です。

Rustのソフトウェアであれば、`depends_on "rust" => :build`でRustのツールチェインを依存関係に追加すると`cargo`が使えるようになるので、`cargo install`するだけです。

テストは単にヘルプメッセージを表示するといったものではなく、ある程度実際の機能を試すテストにするようにドキュメントに書かれているので適宜工夫してください。他のソフトウェアのテストが参考になります。

また他のソフトウェアのスクリプトを見ると

```ruby
  bottle do
    cellar :any_skip_relocation
    sha256 "c85d47f451906c27a29220941d1616521bb61c50a43299551f889f62fac5739f" => :mojave
    sha256 "3529d7208c1343deff6ab969b98003c0cadbca1d8fdba41228c1a0dc5d64ecdc" => :high_sierra
    sha256 "ec5ecc9a0db3fcb83684fb49367713f36f485f038f5fc9e9b35720cd80cd3aba" => :sierra
  end
```

というようなブロックがあります。Homebrewはビルドスクリプトを配布して各ローカルでビルドする方式ですが、bottleといってビルド済みのバイナリを配布する方法にも対応しています。
いくつかのマシン向け（ここではmacOSのmojave/high_sierra/sierra）にはCIがバイナリを生成してこのハッシュ値を生成して書き込んでくれます。そのため初回のプルリクエスト時にはこのブロックは不要です（というかハッシュ値は不明なので書きようもないですが）。

## プルリクエスト

プルリクエストを出す先は以下のリポジトリです。
（Linuxで作業している人は間違ってlinuxbrewのリポジトリに出さないよう気を付けましょう）

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

[CONTRIBUTING.md](https://github.com/Homebrew/homebrew-core/blob/master/CONTRIBUTING.md)や[ドキュメント](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request)をよく読んでプルリクエストを作成します。
コミットメッセージやプルリクエストのタイトルも指定があるので慎重に。

実際に出したプルリクエストは以下です。

https://github.com/Homebrew/homebrew-core/pull/39584

## マージされるまで待つ
今回は1か月くらいかかりました。この部分は人力で回しているようなので、その時の担当者の忙しさや作業のタイミングで期間は変わると思います。
この段階でmacOSでは以下のコマンドでインストール可能になります。

```console
$ brew install procs
```

## macOS用bottleの生成
上で説明したbottle用のバイナリはCIが勝手に生成するので特に操作は不要です。
マージされた後しばらくするとBrewTestBotというビルドボットがハッシュ値を追加したコミットを生成してくれます。

## Linuxbrewへの反映
Linux向けのリポジトリはHomebrewの下に入ったのですが、リポジトリとしてはまだ分離しています。

https://github.com/Homebrew/linuxbrew-core

このリポジトリは1日1回くらいの頻度で本家リポジトリのコミットを取り込んでいて、これが取り込まれるとLinuxでもインストールできるようになります。

## Linux用bottleの生成
Linux向けのbottleもCIで生成しているのですが、どうも現時点ではCIをキックするためのPR作成を手動でやっている部分があるようです。
そのためメンテナの人が忘れていたりしてbottleの生成が行われないことがあります。

このあたりについてForumで聞いてみたところ、bottleが生成されないときはGitHub（https://github.com/Homebrew/linuxbrew-core の方）にIssueを立てればいいようです。

ここまで来れば全ての作業は完了です。macOS/Linuxともに`brew install`でインストールができるようになって、コンパイル済みのバイナリが使用できる環境であればそちらが使用されます。