Xcodegenとは
xcodegenはxcodeprojをymlから生成するcliコマンドです。
xcodegenを導入することで、
- yml -> 設定値
- ディレクトリ構造 -> ファイルツリー
という関係のxcodeprojを作ることができます。
結果、xcodeprojをgitで管理する必要がなくなりxcodeprojのコンフリクトを0にすることができます。
xcodeprojのコンフリクトはチームの規模が大きくなるにつれて課題になるのは明らかなので、先んじて手を打ったという形です。
PocochaでのXcodegenの導入
Pocochaでは、アプリケーションの各モジュールをxcodeprojで管理しておりそれらをworkspaceに入れて開発しています。
これらの各モジュールをxcodegenで生成しています。
とはいえ、毎回xcodegenのコマンドを叩くのはしんどいのでfastlaneのlaneにまとめています。
fastlaneでの実行はfastlane-plugin-xcodegenを使っています。
これ系の処理はfastlaneに寄せておくとCIでも簡単に処理できて楽ですb
移行のコツ
実際xcodegenを最初から導入できれば良いですが、xcodeprojから移行してくることがほとんどだと思います。
移行する際はいきなりxcodeprojをgit管理下から消さずに、作業した方が良いです。xcodeでの変更がどのようにxcodeprojに影響を与えるか見やすいからです。
差分からキー名を見つけてymlに書いていくこともできます。
また、xcodeのbuild settingsは変更されたところが太字になる特性があるのでこれまでデフォルト状態からいじった箇所を探すのに役立ちます。
あとはだいたいドキュメントに書いてあります。
複数モジュールに対応したymlを書く
複数モジュールがあると、他のxcodeprojで定義したframeworkを依存関係に追加させることがあります。その際はimplicitオプションを有効にすると余分にビルドが走らなくなります。
また通常開発時も同様ですが、独自にフラグを立てている場合やビルドコンフィグを追加している場合は各モジュールにも設定を書き忘れないように注意しましょう。
OTHER_SWIFT_FLAGS: $(inherited) -D DEBUG
とか。Stagingとか追加してる時とか。
トレードオフへの対策
xcodegenのメリットは大きいですが、トレードオフもあります。
それは、各開発者のローカル環境でxcodegenを使ってxcodeprojを生成する必要がある点です。
主に他のコミットでファイルが追加された時にxcodegenを実行し忘れると、xcodeprojに認識されなくなってしまうので困ってしまいます。
そこでgit pullの処理にxcodegenをhookして毎回実行するようにしています。
#!/bin/sh
echo “#!/bin/sh
make xcode” > .git/hooks/post-merge
chmod u+x .git/hooks/post-merge
.git/hooks/post-mergeに処理を書いておくと、マージ時に処理を実行できます。
何かおかしいぞ
xcodegenへの移行期間の間で、元々あったxcodeprojをxcworkspaceなどが参照していたりするとビルドが通らなくなることがあります。
何かおかしい時はxcodeprojとxcworkspaceをまるっと消せるように雑なワンライナーをMakefileに書いています。
find . -type d \( -name \*.xcodeproj -or -name \*.xcworkspace \) ! -path “./Carthage/*” ! -path “./vendor/*” ! -path “./Pods/*” | xargs rm -rf
考えていること
xcodegenは複数モジュールを生成する事に最適化されている訳では無いので、workspaceの生成や複数のymlの基底ymlを作れないのが現在の悩み。
余裕があればこの辺りのPR投げたい。(無い)
Xcodegenがもたらした副作用
xcodegenでxcodeprojをガンガン生成できるようになった事で、嬉しい副作用があったため2点紹介します。
1つはディレクトリ構成の変更が容易になった点です。
通常の開発では、サブモジュールとアプリのディレクトリ構成がネストすることがほとんどだと思います。つまり、App.xcodeprojとApp.xcworkspaceは同じ階層にいて他のモジュールはそこの1つ深い階層に配置されているという状態です。
これは最初にテンプレートから生成される構造にcocoaframeworkを追加するとそうなるからなのですが、これがxcodegenを使うことで容易にAppディレクトリも1段深くすることができrootにxcworkspaceしか無いという構成にできます。
見栄えが良いです。
2つ目は、サブモジュールを雑に複製しやすくなった点です。1つのアプリに複数のバージョンのライブラリを入れる際にソースコードを丸ごとxcodegenで生成したxcodeprojで包むと名前の変更も容易でした。この辺りは面白い成果が出そうなので今度記事書きます。