Gradle 7.4 で追加された バージョンカタログ

blog1.mammb.com


はじめに

最近の Gradle では、gradle init タスクでプロジェクトを生成すると、以下のような依存定義が生成される。

dependencies {
    testImplementation(libs.junit.jupiter)
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

libs.junit.jupiter./gradle/libs.versions.toml の定義を参照しており、以下のように定義されたもの。

[versions]
guava = "32.1.3-jre"
junit-jupiter = "5.10.1"

[libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }

これは、Gradle 7.4 で安定版として公開されたバージョンカタログであり、複数のサブプロジェクトを跨いで、ライブラリのバージョンを集中宣言できるもの。


バージョカタログ

バージョンカタログを利用することで、ビルドスクリプトに直接依存関係を宣言するより多くの利点がある。

  • Gradleは、カタログごとにタイプセーフなアクセサーを生成するため、IDEのオートコンプリートを活用できる
  • サブプロジェクトに適用されるバージョンを集中管理できる
  • カタログでは依存バンドルを定義できる(一緒に使われる依存関係のグループを宣言定義できる)
  • カタログは、依存関係のグループと名前を、実際のバージョンから切り離したバージョン参照を使用することができ、複数の依存関係間でバージョン宣言を共有することが可能

バージョンカタログの宣言は2種類の方法がある。

一つは settings.gradle.kts で宣言する方法。

dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            library("groovy-core", "org.codehaus.groovy:groovy:3.0.5")
            library("groovy-json", "org.codehaus.groovy:groovy-json:3.0.5")
            library("groovy-nio", "org.codehaus.groovy:groovy-nio:3.0.5")
            library("commons-lang3", "org.apache.commons", "commons-lang3").version {
                strictly("[3.8, 4.0[")
                prefer("3.9")
            }
        }
    }
}

もう一つは、ルートビルドのgradleサブディレクトリ内の libs.versions.toml で宣言するもの。

[versions]
groovy = "3.0.5"
checkstyle = "8.37"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

[plugins]
versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }

ここでは libs.versions.toml による宣言について紹介する。


TOML ファイルによるバージョンカタログ宣言

libs.versions.toml はデフォルトのバージョンカタログ宣言ファイル。 カタログ名を変更する場合は、settings.gradle.kts で以下のように変更できる。

dependencyResolutionManagement {
    defaultLibrariesExtensionName = "projectLibs"
}

この場合 projectLibs.versions.toml というファイルがバージョンカタログ宣言ファイルとなる。


TOML ファイルには4つのセクションがある。

  • [versions] 依存により参照されるバージョン宣言
  • [libraries] 依存ライブラリ参照のためのエイリアスを宣言
  • [bundles] 依存バンドルを宣言
  • [plugins] プラグイン宣言


バージョン宣言 [versions]

[versions] セクションで定義したバージョンは、[libraries] セクションや [plugins] セクションで、version.ref として参照できる。

[versions]
some = "1.4"
checkstyle = "8.37"

[libraries]
my-lib = { group = "com.mycompany", name="mylib", version.ref="some" }

バージョン定義には以下のようなメンバーがサポートされている。

  • require 必須
  • strictly 厳密
  • prefer 優先
  • reject 拒否リスト
  • rejectAll 全て拒否するかどうかのブール値

例えば以下のように宣言できる。

[versions]
my-lib = { strictly = "[1.0, 2.0[", prefer = "1.2" }

以下のようにバージョン番号を参照することもできる。

checkstyle {
    toolVersion = libs.versions.checkstyle.get()
}


ライブラリ宣言 [libraries]

ライブラリ宣言は以下のような定義が可能。

[libraries]
my-lib = "com.mycompany:mylib:1.4"
my-lib-no-version.module = "com.mycompany:mylib"
my-other-lib = { module = "com.mycompany:other", version = "1.4" }
my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" }
mylib-full-format = { group = "com.mycompany", name = "alternate", version = { require = "1.4" } }

定義したエイリアス名は build.gradle.kts で以下のような依存定義として利用できる。

dependencies {
    implementation(libs.my.lib)
    implementation(libs.my.lib.no.version.module)
}

エイリアス名には-_. をセパレーターとして使用できるが、生成されるカタログでは全て. に正規化されることに注意。

また、extensionsclassconvention という単語は利用できない。さらに bundlesversionsplugins という単語は、最初のサブグループ名として利用できない(versions-dependency は無効であり versionsDependencydependency-versions は有効)。


依存バンドル宣言 [bundles]

依存バンドルは、複数の依存に対してエイリアス名を定義する。

[versions]
groovy = "3.0.5"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

3つのライブラリを束ねた groovy というエイリアス名で依存を宣言できるようになる。

dependencies {
    implementation(libs.bundles.groovy)
}


プラグイン宣言 [plugins]

以下のようにプラグインを宣言し、

[plugins]
some = { id = "some.plugin.id", version = "1.4" }

以下のようにプラグインを導入できる。

plugins {
    `java-library`
    alias(libs.plugins.some)
}


TOMLファイルのインポート

バージョンカタログのTOMLファイルは settings.gradle.kts で以下とすることで、インポートすることができる。

dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

これにより、追加のバージョンカタログをインポートすることもできる。

dependencyResolutionManagement {
    versionCatalogs {
        create("testLibs") {
            from(files("gradle/test-libs.versions.toml"))
        }
    }
}

公開されたバージョンカタログをインポートすることもできる。

dependencyResolutionManagement {
    versionCatalogs {
        create("amendedLibs") {
            from("com.mycompany:catalog:1.0")
            version("groovy", "3.0.6")
        }
    }
}

上記例では公開されたバージョンカタログの groovy のバージョンを上書き設定している。