ライブラリ作るの、楽しいですよね。
作ったからには、沢山の人に使ってもらいたいですよね。
そして、ソースコードをきれいに保つためにSwiftLintも使いたいですよね。
でも、環境によってSwiftLintがErrorを吐いて使われなくなる、とかは避けたいですよね。
というわけで、そのあたりをまとめてみました。
なぜまとめたか
今関わっているプロジェクトで以下の現象に遭遇したために、掘り下げてみました。
- mixpanel-swiftを導入
- SwiftLintを
0.13.2
>0.15.0
にアップデート -
carthage update --platform iOS --no-use-binaries
が通らなくなる - ふむ🤔
SwiftLintバージョン違い問題
上記の現象について詳しく調べてみたところ、
- mixpanel-swiftが想定するSwiftLintのバージョン:
- 0.13.2
- ローカルのSwiftLintのバージョン
- 0.15.0
と想定するSwiftのバージョンに差異があったために引き起こされていたことがわかりました。
つまり、いつものこいつによって、引き起こされていたのです。
どう解決できるか?
自分でもPlayListPlayerなどのライブラリを開発しているため、この件について色々と考えてみました。
例えば、
- SwiftLintのScriptを削除する
- SwiftLintが手軽に実行できなくなるため、ダメ🙅
- swiftlintに対してエイリアスを設定(上記の例であれば、
mixpanel-swiftlint
等)- 悪くはなさそう。
- ライブラリのリポジトリにswiftlintのバイナリを追加
- swiftlintのバージョンが固定されるのは良いが、そもそもライブラリのリポジトリに追加すべき?
などなど。
岸川さんからのアドバイス
ただ、何かしっくりこないなーと思いつつ、つぶやいたところ、
1. SwiftLintをリポジトリに追加して参照する
— Kohei Tabata (@nerd0geek1) February 1, 2017
2. SwiftLintにエイリアス切って参照する
やりたいことは、
- 開発中はSwiftLintでチェックしたい
- CI上ではチェックなくても良い
だから、2. かなー。1. だと想定外のケース出ないかな―?
岸川さんからアドバイスが!
@k_katsumi そうですよね。
— Kohei Tabata (@nerd0geek1) February 1, 2017
ただ、今回は
mixpanel-swiftの使っていたバージョン:0.13.2くらい?
自分のローカル環境:0.16.1
となっていて、ルールの変更があった故にcarthageでのインストールがコケる、といった感じでした。
SwiftLintを別ターゲットに分ける?なるほど、わからん🤔
@nerd0geek1 おお、そういうこともあるんですね。Carthageでエラーになるのはターゲットを分けるのがいいと思いますね。SwiftLintは別ターゲットにしてしまって、外部からBuildだけ、Testだけ、Build+Lintなどを制御するようにするのがいいと思います
— kishikawa katsumi (@k_katsumi) February 1, 2017
なるほど、SwiftLintのScript Phaseのみを含むターゲットを作ればよくて、
Realmプロジェクトにその実装があると。
@nerd0geek1 Realmのプロジェクト見てもらうのがいいと思いますけど、SwiftLintのターゲットはScript Phaseだけしか持ってないので、そういうことは起こらないです。メインのビルドなどと全く関係なく独立してるのでその方がスマートだと思います。
— kishikawa katsumi (@k_katsumi) February 1, 2017
Realmのプロジェクト構成を確認
普段あまり使わないような形でSwiftLintがターゲットとして独立して追加されていました。
調べてみたところ、ターゲットの追加 > Cross-platform
で選択できるAggregateというものを使っているようです。
Aggregateとは
Xcode Target Aggregate
で検索してみましたが、公式ドキュメントは見つけられませんでした。。。
他で探したところ、こちらが参考になりました。
要約すると以下のようになります。
- 直接、何かをビルドするものではない
- 他のターゲットのビルドステップを整理する手段として役に立つ
-
run scripts
やcopy files
などのような追加的なBuild phases
に対処する時に特に役に立つ。
SwiftLintではrun scripts
を追加することになりますので、ぴったりです。
実際に導入
PlayListPlayerに実際に導入してみました。
導入手順としては
-
ターゲットの追加 > Cross-platform > Aggregate
を選択 -
Run Script
を追加し、SwiftLint実行用のコードを追加
するだけです。
これによって、SwiftLintのBuild Schemeも追加され、独立してSwiftLintを実行できるようになります。
テスト時にのみ実行
以上の実装では、Lint用Targetを選択しないとLintが実行されないため、
メインターゲットの選択中、かつテスト時にのみ(🙅ビルド・アーカイブ時)実行されるように設定します。
以下のように設定するだけです。
まとめ
アプリのプロジェクトと違い、ライブラリでは効果的なLintの実行方法が異なることがわかって頂けたかと思います。
是非、ご自身のライブラリにも適用してみてください!