Swift 製の Mac ターミナルプログラムを Mint インストール対応しましょう！

# 初めに

この記事は [Swift Advent Calendar 2019](https://qiita.com/advent-calendar/2019/swift) 6 日目の記事です。本来は iPad アプリの [Swift Playgrounds](https://www.apple.com/jp/swift/playgrounds/) について何か書きたかったのですが、結局最近の私のお財布の都合で新しい iPad Pro の購入が断念され、そして所持している iPad が型落ちしすぎて Swift Playgrounds の実行が非常にカクカクするので、テーマを変更してみなさんが今ご覧になっているこの記事になりました。ただここで敢えて一言言っておくなら、今の Swift Playgrounds は本当にとても高機能で結構使える子になってきたのです。確かに iOS アプリの作成とかはできないですが、Mac で作った `.playground` ファイルを読み込んでリアルタイムでプレビューができるようになったので勉強会 iPad 持っていけば大体のこと足りるんじゃね？と思うようになりました。

さて、本題に入りましょう。

# Mint とは

Mac ユーザ、特に Mac を使うエンジニアなら、[Homebrew](https://brew.sh) はとてもお馴染みのあるツールかと思います。Ruby 製のパッケージマネージャーで、Carthage をはじめとした様々な開発に使うツールのインストールを劇的に楽にしてくれるツールです。

そして最近は [Mint](https://github.com/yonaskolb/Mint) というパッケージマネージャーが筆者の中で微妙にヒットしています。Mint 自体も Homebrew でインストールできます：

```bash
$ brew install mint
```

Homebrew と Mint の主な違いはこんな感じでしょうか

|   | Homebrew | Mint |
|--:|----------|------|
|自身の言語| Ruby | Swift |
|対象パッケージの言語| なんでも（特に制限なし）| Swift |
|パッケージバージョン指定| 不可[^brew_version_control] | 可能 |
|パッケージバージョン指定書式| -[^brew_version_control] | author/Package@version |
|パッケージ検索方式| 別途 tap ファイル | GitHub ユーザ名指定 |
|インストール方式| 別途 tap ファイル | swift ビルド |
|単体インストール| `brew install Package` | `mint install author/Package` |
|管理ファイルインストール| `brew bundle` | `mint bootstrap` |
|管理ファイル| Brewfile | Mintfile |
|管理ファイル書式| `brew "Package"` | `author/Package` |

簡単にまとめてみましたが、一番大きいのは Homebrew は特にツールの言語に制限はないに対し、Mint は Swift 製のツールにしか対応していない；その代わり、Homebrew は必ず独自で tap ファイルを作る必要がある（tap ファイル自体は Homebrew にマージしてもらってもいいですし、マージせずに自分の GitHub リポジトリーに公開するだけでもいいですが、後者の場合利用者は先に自分で手動 tap する必要がある）が、Mint はそもそも GitHub の `著者名/パッケージ名` の書式で探すので、特にツール以外の追加外部ファイルは必要ないという利便さがある感じですかね；何よりこの tap ファイルは非常に面倒で、ビルドコマンドだけでなく、最新リリースのアーカイブを取得する URL 及びそれの sha-256 ハッシュも書かなくてはいけないです。

また、Homebrew は特定のバージョンに指定するという機能がない（常に最新版をインストールする）[^brew_version_control]に対し、Mint は特定のバージョンをインストールできるという点も人やプロジェクトによっては大きなメリットなのかもしれません。

[^brew_version_control]: Formulae 側が対応していれば、一応 `Package@version` のような書式でバージョン指定も可能ですが、これはあくまで Formulae 側の対応であり Homebrew の機能ではありません；詳しくはコメント欄をご参照ください。

というわけで、こんな Mint ですが、せっかくなのでぜひご自分で作った Swift 製のツールを Mint 対応してみてはいかがでしょうか？

# じゃあどう対応するの？

実は Mint の対応はとても簡単です：SwiftPM に対応すれば終わり！これだけです。

え？と思うかもしれませんが、本当にそうです。自分が作ったツールを SwiftPM に対応させれば、それで終わりなのです。

なんのことか微妙にわかりにくいかもしれませんので、ここは私が作ったランダム文字列の生成ツール [hanako](https://qiita.com/lovee/items/23baf601ce83fb45ecb6) の [Mint 対応](https://github.com/el-hoshino/hanako/pull/3) を例に解説してみましょう。

1. 最初の最初に、ターミナルでリポジトリーのルートパスに遷移して、`$ swift package init` して、`$ swift package generate-xcodeproj` をします（もちろん `.xcodeproj` ファイルが既にあっても `swift package generate-xcodeproj` をする必要があります）。これでとりあえずこのリポジトリー自体が SwiftPM の対応ができます。このステップの実行結果は[こちらのコミット](https://github.com/el-hoshino/hanako/pull/3/commits/e3bef474abbbf035dcd27c8be05107eb86d8f1a3)になります。差分が大きいですが、内容は全部自動生成です。

2. SwiftPM 対応によって `Sources` と `Tests` のディレクトリーが作成されます（もし既存の作りがこうなっていなかった場合）。前者はプログラム本体のソースコードの置き場で、後者はユニットテストのコードの置き場です。なのでもし既存のソースコードが `Sources` 内になかった場合、それらのコードを `Sources` 内に持っていきましょう。これを対応したのが[こちらのコミット](https://github.com/el-hoshino/hanako/pull/3/commits/6d5781228fe51c8de0fa28b2991e457e244db7c2)です。

3. 実は 1. の段階で SwiftPM の自動生成によって作られた `Package.swift` ファイルはちょっと問題があります。そのまま実行するとライブラリーとしてみられちゃいますが、我々が作ってるツールはターミナルで実行されるプログラムですので、`products` の項目の `.library(` の行を `.executable(` に修正します。この対応が[こちらのコミット](https://github.com/el-hoshino/hanako/pull/3/commits/040e0aebedeee1b3177d11691eae744cfc6359da)になります。

4. 最後に、また 1. の段階で自動生成された .xcodeproj ファイルでは、余計な Scheme や target が生成されたりしますので、そこらへんの設定を確認しておきましょう；もし何か間違ったものがあったらそれらを直しましょう。これを対応したのが[この二つのコミット](https://github.com/el-hoshino/hanako/pull/3/files/040e0aebedeee1b3177d11691eae744cfc6359da..b4faa40cf41ccb963c6f41aeb1c061d16d82ea03)です。

5. ここまでできたら Mint 対応ができているはずなので、一旦 GitHub にこのブランチをあげておきましょう；そしてこれで Mint の便利さもまさにここで体験できます：とりあえずターミナル行って、`$ mint install myName/myToolName@branchName` で一回やってみると、実際 Mint を使って今あげたブランチを落としてきてインストールを試みるので、これで本当に Mint の対応ができたかどうかが確認できます；もしここで何か問題あったら、エラー読んで対応しましょう。

6. せっかく Mint 対応できたんだから、README.md ファイルとか CHANGELOG.md ファイルとかでアピールしましょう！これを対応したのが[こちらのコミット](https://github.com/el-hoshino/hanako/pull/3/commits/9095e9ef58e38f2c2be2464f4e25f801c4572865)です。

ね、簡単でしょ？

しかも Homebrew との比較で書いたとおり、Mint は別途のリリース説明を担当する tap ファイルが要らないので、バージョンアップとかする際も普通に GitHub でバージョンリリースのタグ打ちするだけで済むから非常に手軽です。

# 宣伝

せっかくここまで書きましたので、hanako のインストールも宣伝しておきますね：

```bash
$ mint install el-hoshino/hanako
```

利用イメージはだいたいこんな感じです：

```bash
mymac:~ me$ mint install el-hoshino/hanako
🌱  Finding latest version of hanako
🌱  Cloning hanako v1.0.4
🌱  Resolving package
🌱  Building package
🌱  Installed hanako v1.0.4
🌱  Linked hanako v1.0.4 to /usr/local/bin
mymac:~ me $ hanako
Generated string: zGlv4EDJPQ
Result has been copied to your clipboard, you can use cmd + v to paste it.
```

# 余談

hanako のコードベースが非常に古いので今絶賛リファクタリング中です…ｗ