はじめに
with で Android エンジニアをしている 石田 です。with の Android チーム(以下 with-android) では build.gradle
を Groovy DSL で記述しており、Dependencies の記述もベタで行っていました。先日の Gradle 7.4.1 のリリースで Version Catalog が安定になったことを受け、以前より検討していた Version Catalog への移行を実施しました。
従来の課題
各 build.gradle
に Dependencies をベタ書きしていたため、同じライブラリへの依存の記述が重複して冗長でした。ライブラリのアップデートには Dependabot を使用していましたが、1つのライブラリの更新でも複数の build.gradle
が書き換わるためコンフリクトが起きやすい状態でもありました。
また with-android ではマルチモジュール化を現在進めており、20個程度のモジュール数を50個程度にする計画です。このままいけば冗長な部分をさらに増やしてしまうことになるため、そうなる前に共通化しておきたいと考えておきました。
Version Catalog の登場
Version Catalog は Gradle 7.0 で登場したライブラリ管理の方法です。ライブラリバージョンの一元管理やライブラリのグループ化 (Bundle)といった機能があります。詳しくはドキュメントをご覧ください。
共通化についてはこれまでも Kotlin DSL + buildSrc を使う方法があったかと思いますが、with-android では採用を見送っていたため、Version Catalog は待望の新機能でした🙌
Version Catalog への移行準備
念のため Gradle 7.4.1 でアプリを問題なくビルドできるか確認します。また、Dependabot を使用している場合は Renovate への移行を検討します。記事執筆時点で Dependabot は Version Catalog に対応していないためです。
Version Catalog への移行
まず考えることは Version Catalog へ手動で書き換えることですが、with-android の場合はそこそこプロジェクトの規模が大きいため既存の記述を手動で書き換えるという方針は取らない方がよいと考えました。手動でやると時間がかかりますし、ミスが起きやすくなるためです。
そこで Version Catalog への移行スクリプトを作成することにしました。以下では重要な部分について説明します。
Version Catalog の構造を観察する
- 「バージョン名」 と 「バージョン値」
coil = "1.4.0"
- 「ライブラリ名」 と 「ライブラリのモジュールとバージョン名のペア」
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
これらをクラス図風に描くと以下のようになります。LibDefinition.versionRef
は VersionDefinition.name
に一致します。
従来の Dependencies の構造を観察する
- 「コンフィグレーション」、「モジュール(パッケージと名前)」、「バージョン」
implementation 'io.coil-kt:coil:1.4.0'
これをクラス図風に描くと以下のようになります。
Version Catalog への変換ロジック
-
build.gradle
の Dependencies をパースしてDependencies
にする -
Dependencies
をVersionCatalog
に変換する。このとき以下のルールに従う。-
Dependency.configuration
はそのまま -
Dependency.name
→LibDefinition.name
-
Dependency.package
とDependency.name
→LibDefinition.module
-
Dependency.package と Dependency.version
→VersionDefinition
とLibDefinition.versionRef
-
パッケージが同じライブラリは LibDefinition.versionRef
も同じであると見なしています。パッケージと VesionDefinition.name
の紐付けは以下のように自分でいい感じに定義したものを使います。
"io.coil-kt" to "coil",
"io.insert-koin" to "koin",
"io.realm" to "realm",
"androidx.compose.ui" to "compose",
"androidx.compose.foundation" to "compose",
"androidx.compose.material" to "compose",
上記の変換を各 build.gradle
に対して行うので複数の VersionCatalog
が出来ます。これを1つの VersionCatalog
に変換するには単にマージして VersionDefinition
と LibDefinition
の重複を除けばOKです。
仕上げ
移行スクリプトの適用により、だいたいの移行は完了するはずです。あとはビルドをしてみてエラーになった部分があれば手直しをして完了です🎉
Renovate の導入
Version Catalog に対応している Renovate の導入についても少しだけ紹介します。
GitHub App にある Renovate をインストールすると Renovate 導入のための Pull Request が自動で作成されます。それをマージすることですぐに Renovate が使えるようになります。
Renovate の導入後、例えば Flipper の更新があった場合は以下のような Pull Request を作成してくれます。Version Catalog 上で flipper
と flipper-network-plugin
が同じバージョンであることが定義されているれば Renovate でもしっかりと認識されます。
Pull Request | Files changed (差分は1行のみ) |
---|---|
ちなみに Dependabot は Version Catalog を認識することができないので、特に何もしなくても何もしなくなります。将来的に Dependabotが Version Catalog に対応する日を待ちつつ dependabot.yml
は消さずにそのまま置いておくでもよいかもしれません。
まとめ
本記事では スクリプトを使って Version Catalog へラクに移行する方法を紹介しました。Version Catalog により依存ライブラリの記述が一元化され管理が圧倒的に楽になりました。特に with-android にとって Version Catalog 登場のインパクトは大きなものでした。 Version Catalog は Groovy DSL、Kotlin DSL 問わず気軽に導入できます。ぜひこの記事をヒントに検討してみてください😉