複数のモジュールを持つMavenライブラリではBOM(bill of materials)を提供するものも多くなってきました。
例えばFirebaseの場合、以下のように使います。
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-auth")
implementation("com.google.firebase:firebase-firestore")
BOMをplatformで指定しておくと、ライブラリごとのバージョンを個別で指定する必要がなくなり、複数のモジュールに分かれたライブラリでバージョンを統一することができます。特に、モジュールごとにバージョンが同一でない場合、バージョンの組み合わせを管理できて便利です。
複数のモジュールを持つライブラリを作成する場合は、BOMも提供することを検討すると良いでしょう。
BOMモジュールを作成する方法は簡単で以下のように作ります。
BOMモジュールを作成する
前提として複数のモジュールを持つライブラリなので、すでにマルチモジュールの構成ができていると思います。
追加でBOMのためのモジュールを作成します。ルートプロジェクト直下にモジュールディレクトリを作成し、build.gradle.kts
ファイルを作成します。
そして、setting.gradle.kts
にモジュールを追加します。
include(":hoge-bom")
build.gradle.kts
は以下のようになります。
plugins {
id("org.gradle.java-platform")
id("org.gradle.maven-publish")
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["javaPlatform"]) // javaPlatformの構成を指定
// publishに必要な設定諸々
groupId = "com.example.hoge"
artifactId = "hoge-bom"
version = "1.0.0"
}
}
}
dependencies {
constraints {
// BOMに掲載するモジュールを列挙する
api(project(":core"))
api(project(":api"))
}
}
maven-publishに関する設定は通常のモジュールとほぼ同じです。これに関する解説は省略、最低限publishToMavenLocalが動く記述にしているので適宜補完してください。
BOMを作成するためにはjava-platform
プラグインを使います。
そして、dependencies.constraintsの中に掲載するモジュールを列挙するだけです。
これでpublishするとBOMが作成されます。
ついでに、buildディレクトリは作成されるので、必要に応じて.gitignoreも追加します。
/build
BOM掲載モジュールを自動で設定する
単に列挙するだけなので、一度書いてしまえばよいし、その後モジュールが増減したら都度追加削除すれば良いことではあります。しかし、追加を忘れていてもその時点でビルドエラーなどになるわけではないので、忘れたままpublishしてしまって〜ということも起こってしまいそうですね。
なので、何を掲載するかも自動化してしまいましょう。
以下のように記述すると、"org.gradle.maven-publish"
プラグインを使っている=ライブラリとして公開するモジュールを自動的に追加することができます。
チョットしたハックですね。
dependencies {
val thisProject = project
constraints {
rootProject.subprojects {
if (this@subprojects != thisProject) {
plugins.withId("org.gradle.maven-publish") {
api(this@subprojects)
}
}
}
}
}
Gradle Version Catalogを使っている場合はpublishプラグインのIDもそこから取るのが良いですね。build-logicでまとめたpublishプラグインを使っているものという条件で追加しても良いでしょう。
dependencies {
val thisProject = project
val publishPluginId = libs.plugins.build.logic.mavenPublish.get().pluginId
constraints {
rootProject.subprojects {
if (this@subprojects != thisProject) {
plugins.withId(publishPluginId) {
api(this@subprojects)
}
}
}
}
}
retrofitのbomでこの手法が使われていて、Jakeが「Very nice!」ってコメントしてますね。
以上です。