tl;dr
Xcode11が出て格段に使いやすくなったSwift Package Manager
ライブラリが基本的にDerivedData内にいくことや、別途の環境構築が不要なことからできるならどんどんとSPMに移行していきたい気持ちがあると思います。
その中でも今回はRun Scriptで実行したいライブラリ(コードを綺麗に管理するためのSwiftLintやSwiftFormatなど)をSPM導入するためにした工夫を紹介します。
注意
今回の記事はSwiftFormatをもとに説明します。
大前提としてSPMで落としてきたライブラリのファイルの中に実行ファイルが含まれることが必要となります。
SwiftLintは依存パッケージの一部がXcode11の最新バージョンに対応できていなかった上、実行ファイルがSPMで配信されるファイルに含まれていなかったのでこの方法は利用できません。
どうするか?
これらのツールをCocoaPodsで導入する場合 $PODS_ROOT
という環境変数がCocoaPodsのビルドフォルダを指していたのでそれを利用することができました。
ですがSPMの場合、このような環境変数が存在していません。なのでそれをどう用意するかが肝となります。
Swift Package Dependenciesから適当に右クリック>Finderで表示とすると、Xcode11におけるSPMであつかうライブラリ群はDerivedData/<AppName>-xxx/SourcePackages/checkouts
という場所に落とされてきていることがわかります。
ですので目標としてはこれを適当な名前でexportもしくは指定してあげることになります。
ですが場所がDerivedDataの中なので一度クリーンなどしてしまったり、環境が変わるとこのフォルダ名が変わってしまいます。そのためハードコーディングは好ましくありません。
そこで利用するのが$BUILD_ROOT
です。これはDerivedData/<AppName>-xxx/Build/Products/
を常に指している環境変数になります。
そしてこれにフルパスから親のディレクトリのフルパスを取り出せるdirname
というコマンドを使ってあげることで目的の環境変数を作ります。
すなわち最終的なコマンドはこうなります(SwiftFormatの場合)
export SPM_ROOT=$(dirname $(dirname $BUILD_ROOT))/SourcePackages/checkouts
"${SPM_ROOT}/SwiftFormat/CommandLineTool/swiftformat" . [YourOption]
これでSPMで導入したSwiftFormatをRun Script内から呼び出すことが出来ました。
まとめ
今回はSwiftFormatでの一例を示しましたが、SPMでとってきたライブラリの何かしらを使いたいということは今後出てくると思います。ぜひ参考にして、コンパクトでナウいプロジェクトを目指していきましょう!