kagamihogeの日記

kagamihogeの日記です。

gradleのversion catalogでsubprojectで共通のバージョンを定義

JJUG CCC 2023 Spring で最近のGradleにはversion catalogというmultiple projectでバージョン定義を共有する仕組みがあるのを知った。その時に講演していた方のプレゼン資料は Gradleと仲良くなる第一歩 ~小規模PJから大規模PJへ~ にある。

https://docs.gradle.org/current/userguide/platforms.html 公式ドキュメントとしてはこのあたりを参照している。

ソースコードなど

以下の記述においてdependencyResolutionManagementsettings.gradleに記述する。

version

  • java 17
  • gradle 8.1.1

library - バージョン定義のエイリアス

settings.gradle にライブラリのバージョン定義にエイリアスをつけられる。各multiple projectのbuild.gradleはそのエイリアスでバージョン定義を参照できる。

以下はgroovyとcommon-lang3のエイリアスを作成している。

dependencyResolutionManagement {
    versionCatalogs {
        libs {
            library('groovy-core', 'org.apache.groovy:groovy:4.0.12')
            library('commons-lang3', 'org.apache.commons', 'commons-lang3').version('3.12.0')
        }
    }
}

build.gradleでは以下のようにエイリアスを使用する。ハイフン("-"), アンダースコア(".")はドットに読み替えの必要がある。公式ドキュメント的にはセパレータはハイフンを推奨している。

  implementation(libs.groovy.core)
  implementation libs.commons.lang3

セパレータで分かりやすく区切るかどうかは任意で、お気に召さなければgroovyCoreでも良いよ、と公式ドキュメントには書いてある。

version, versionRef - バージョン番号のエイリアス

バージョン番号のみのエイリアスversionを使用する。

以下のようにgroovy関連がすべて同一のバージョン番号の場合はversionでそのバージョン番号を定義してversionRefで参照する。

dependencyResolutionManagement {
    versionCatalogs {
        libs {
            version('groovy', '4.0.12')
            version('java-version', '17')
            
            library('groovy-core', 'org.apache.groovy', 'groovy').versionRef('groovy')
            library('groovy-json', 'org.apache.groovy', 'groovy-json').versionRef('groovy')
            library('groovy-nio', 'org.apache.groovy', 'groovy-nio').versionRef('groovy')
        }
    }
}

build.gradleでの使用方法はlibraryと変わらない。

  implementation(libs.groovy.core)
  implementation(libs.groovy.json)
  implementation(libs.groovy.nio)

また、dependencies以外でもversionは参照できる。以下はsettings.gradle に定義したjavaのversionをbuild.gradleで参照している。

sourceCompatibility = libs.versions.java.version.get()

bundle - 複数の定義をまとめる

複数のバージョン定義をまとめたグループに対してエイリアスを作れる。以下はspring-bootのjdbcとwebをspring-bundleというbundleにまとめている。この場合バージョンは不要なのでwithoutVersion()を付与している。

dependencyResolutionManagement {
    versionCatalogs {
        libs {
            library('spring-boot-starter-jdbc', 'org.springframework.boot', 'spring-boot-starter-jdbc').withoutVersion()
            library('spring-boot-starter-web', 'org.springframework.boot', 'spring-boot-starter-web').withoutVersion()
            
            bundle('spring-bundle', ['spring-boot-starter-jdbc', 'spring-boot-starter-web'])
        }
    }
}

build.gradleでは以下で参照する。

implementation libs.bundles.spring.bundle

pluginのエイリアス

pluginは以下のようにエイリアスを作成する。以下はpluginでspring-bootのバージョンのエイリアスを作成している。

dependencyResolutionManagement {
    versionCatalogs {
        libs {
            plugin('spring-boot-version', 'org.springframework.boot').version('3.1.0')
        }
    }
}

build.gradleでは以下のように使用する。

plugins {
  id 'java'
  // id 'org.springframework.boot' version '3.1.0' // これと同じ結果になる。
  alias(libs.plugins.spring.boot.version)
  id 'io.spring.dependency-management' version '1.1.0'
}

複数カタログ

基本的にはlibsを使用するが自前定義のカタログを作成できる。以下はspringLibsという自前定義のカタログを追加している。

dependencyResolutionManagement {
    versionCatalogs {
        libs {
          // (省略)
        }
        springLibs {
            library('spring-boot-starter-jdbc', 'org.springframework.boot', 'spring-boot-starter-jdbc').withoutVersion()
            library('spring-boot-starter-web', 'org.springframework.boot', 'spring-boot-starter-web').withoutVersion()
            
            bundle('spring-bundle', ['spring-boot-starter-jdbc', 'spring-boot-starter-web'])
        }
    }
}

自前定義のカタログは以下のように使用する。

implementation springLibs.bundles.spring.bundle

tomlファイル

ちゃんと試してないのだけど以下のような形式のファイルでversion catalogを定義できるらしい。別ファイルに切り出して、別プロジェクトでもバージョン定義を共有したい、場合に有用らしい。

[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" }

プロジェクト間のversion catalog共有の方法については https://docs.gradle.org/current/userguide/platforms.html#sec:version-catalog-plugin に自前のpluginを書いてgitにアップという方法も紹介している。