Swift製コマンドラインツールのパッケージ管理ツール「Mint」のセットアップ&操作方法


はじめに

もともと気になっており、Mockoloのインストールを機に導入することにしました。

「Mint」とは?

Swift製コマンドラインツールのインストールと実行を管理するツールです。

BundlerのSwift版と考えるとわかりやすいです。

メリット

基本的に、Ruby製ライブラリをBundlerで管理するメリットと同様です。

  • プロジェクト内でSwift製コマンドラインツールのバージョンを簡単に揃えられる
  • プロジェクトごとに異なるバージョンのSwift製コマンドラインツールを使える

環境

  • OS:macOS Catalina 10.15
  • Mint:0.13.0

セットアップ

Mintのインストール

Homebrewからインストールします。

$ brew install mint

MakeやSwiftPMでインストールするには、公式ドキュメントをご参照ください。
https://github.com/yonaskolb/Mint#installing

Mintのバージョン確認

Mintのバージョンを確認します。

$ mint version
Version: 0.13.0

操作方法

Mintfileの作成

Mintfile という名前のファイルを作成し、使いたいパッケージを記述します。
Mintfileを作成しなくてもパッケージを管理できますが、プロジェクト内でパッケージのバージョンを揃える場合、Mintfileがあれば簡単です。

{ユーザー名}/{リポジトリ名}@{バージョン} の形式で記述します。

パッケージのインストール

mint bootstrap コマンドを実行することで、 Mintfile に記述した全パッケージを ローカル にインストールします。

$ mint bootstrap

--verbose オプションを付けるとログを詳細に出力します。
パッケージのインストールに失敗する場合に付けるといいです。

インストール済のパッケージはスキップされるので、 Mintfile の一部を編集しても効率よくインストールできます。

追記
0.16.0で --overwrite オプションが追加されました。
https://github.com/yonaskolb/Mint/releases/tag/0.16.0

--overwrite y を指定すると、バイナリがすでに存在する場合に y を自動で入力します。
CI時に付けるべきオプションです。

インストール済パッケージの一覧

mint list コマンドを実行することで、インストール済パッケージの一覧を出力できます。

$ mint list
🌱  Installed mint packages:
  mockolo
    - 1.1.1
  SwiftLint
    - 0.38.0

パッケージの実行

mint run {パッケージ名} {コマンド} で指定したパッケージのコマンドを実行できます。

$ mint run {パッケージ名} {コマンド}

$ mint run swiftlint swiftlint version
🌱  Using realm/SwiftLint 0.38.0 from Mintfile.
🌱  SwiftLint 0.38.0 already installed
🌱  Running swiftlint 0.38.0...
0.38.0

Mintの特徴として、パッケージの実行時にインストールされていない場合は自動でインストールします。
CI/CD環境では mint bootstrap せず、必要なときに必要なパッケージのみインストールすると、1つのMintfileで複数のワークフローを効率よく使えます。

パッケージのアンインストール

mint uninstall {パッケージ名}@{バージョン} で、指定したパッケージをアンインストールします。

$ mint uninstall {パッケージ名}@{バージョン}

パッケージは複数のバージョンをインストールできるため、基本的にはバージョンを指定してアンインストールしてください。
バージョンを指定しない場合、 全バージョンをアンインストールします

パッケージのバージョンアップ

Mintfile 内のバージョンを変更して mint bootstrap するのみです。
古いバージョンも残るため、不要なら mint uninstall {パッケージ名}@{バージョン} してください。

おまけ:ローカルのインストールパス

パッケージはプロジェクトフォルダ内でなく、デフォルトで /usr/local/lib/mint にインストールされます。
そのため、CocoaPodsやCarthageのように .gitignore へインストールフォルダを追記しなくてもバージョン管理外になります。

インストールフォルダ内をざっと確認したところ、パッケージをプロジェクト名で管理していないようでした。
異なるプロジェクト間で同じバージョンのパッケージを使う場合、同じフォルダを参照すると思われます。

CIでは使いづらいので、 MINT_PATHmint/libMINT_LINK_PATHmint/bin などを指定するといいです。

ローカルでは以下のように設定するといいです。

.bash_profile
if which mint >/dev/null; then
  export MINT_PATH="${HOME}/.mint/lib"
  export MINT_LINK_PATH="${HOME}/.mint/bin"
fi

注意:Xcode 11.5以上のRun Script Phaseで使うにはワークアラウンドが必要

Xcode 11.5以上のRun Script PhaseでMintを使う場合、以下のビルドエラーが発生します。

スクリプトの先頭で unset SDKROOT を実行すると回避できますが、副作用があるかもしれません。
やはり副作用がありました。R.swiftをMintで管理している場合、「Missing value for SDKROOT 」エラーが発生しました。
MintでビルドするコマンドラインツールはmacOSで実行するため、 mint run の直前に xcrun --sdk macosx を付けて明示的にSDKを指定するのがよさそうです。

Mint + Carthage + XcodeGenを使っている場合、以下のように設定します。
Carthageで管理しているライブラリの種類によっては不要なので、上記のエラーが発生したら対応してもいいかもしれません。

project.yml
options:
  carthageExecutablePath: xcrun --sdk macosx mint run Carthage/Carthage carthage

参考

おわりに

Swift製コマンドラインツールを簡単に管理することができました!
iOSアプリ開発では、SwiftLintやCarthage、XcodeGen、Mockoloなどを管理するといろいろ捗ります。

参考リンク