LoginSignup
1
1

BOMモジュールを作成する方法

Posted at

複数のモジュールを持つ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にモジュールを追加します。

setting.gradle.kts
include(":hoge-bom")

build.gradle.ktsは以下のようになります。

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も追加します。

hoge-bom/.gitignore
/build

BOM掲載モジュールを自動で設定する

単に列挙するだけなので、一度書いてしまえばよいし、その後モジュールが増減したら都度追加削除すれば良いことではあります。しかし、追加を忘れていてもその時点でビルドエラーなどになるわけではないので、忘れたままpublishしてしまって〜ということも起こってしまいそうですね。
なので、何を掲載するかも自動化してしまいましょう。

以下のように記述すると、"org.gradle.maven-publish"プラグインを使っている=ライブラリとして公開するモジュールを自動的に追加することができます。
チョットしたハックですね。

build.gradle.kts
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プラグインを使っているものという条件で追加しても良いでしょう。

build.gradle.kts
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!」ってコメントしてますね。

以上です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1