ソフトウェアエンジニアの雑記

日々思ったことをまとめます

GradleのVersion Catalogが面倒なので、extでそれっぽく済ませる方法

GradleのVersion Catalogがあっち書いて、こっち書いてが面倒なので、extで簡単に済ませる方法を書いておく。Version CatalogだとIDEの支援があるので便利なのだが、toml形式なのと、tomlだと-(ハイフン)でbuild.gradleだと.(ドット)なので統一感がないし、あんまりメリットを見いだせないので代替手段をメモ。

Version Catalogで解決したいこと

Version Catalogで主に解決したいことは下記になる。

  • ライブラリ、プラグインのバージョン管理
  • バンドル機能
    • ライブラリのグループ化みたいなもの

Version Catalog

Version Catalogはlibs.version.tomlを設置する。形式は最近流行りのTOML形式になります。

[versions]
spring-boot = "3.2.0"
spring-dependency-management = "1.1.4"
mysql = "8.0.33"
testcontainers = "1.19.3"
lombok = "1.18.30"
mapstruct = "1.5.5"

[libraries]
# Spring Boot
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" }
spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation" }
spring-boot-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" }

# 開発ツール
lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" }

[bundles]
spring-web = ["spring-boot-starter-web", "spring-boot-starter-validation"]
spring-data = ["spring-boot-starter-data-jpa", "mysql-connector"]

dev-tools = ["lombok", "mapstruct"]

[plugins]
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
spring-dependency-management = { id = "io.spring.dependency-management", version.ref = "spring-dependency-management" }

利用するときは下記のようになります。(省略しています。)

plugins {
    id 'java'
    alias(libs.plugins.spring.boot)
    alias(libs.plugins.spring.dependency.management)
}

dependencies {
    // ライブラリを設置
    annotationProcessor libs.lombok
    annotationProcessor libs.mapstruct.processor

    // バンドルを使用してまとめて追加
    implementation libs.bundles.spring.web
    implementation libs.bundles.spring.data
    compileOnly libs.bundles.dev.tools
}

build.gradleのext でやる方法

extでやる方法だと下記になります。ext内でgroovyのMap構造に値を詰めて、 dependencies {}ブロックで取り出す形です。配列の順番に気を使いますが、versionsで宣言したものは、librariesで使用できます。

ext {
     versions = [
         mysql: '8.1.0'
     ]

    libraries = [
            spring: [
                    web    : 'org.springframework.boot:spring-boot-starter-web',
                    dataJpa: "org.springframework.boot:spring-boot-starter-data-jpa"
            ],
            mysql_jdbc: "com.mysql:mysql-connector-j:${rootProject.ext.versions.mysql}" 
    ]
}

dependencies {
    implementation rootProject.ext.libraries.spring.web
    runtimeOnly rootProject.ext.libraries.mysql_jdbc
}

メリット・デメリット

Version Catalog

  • メリット

    • IDEの支援がある
    • OpenRewriteなどのmigrationツールのサポートはきっとある
    • バンドル機能は便利そう
    • プラグイン管理もできるのは便利
  • デメリット

    • 管理するファイルが増える
    • TOMLだと-なのが、build.gradleだと.になって検索とかしづらい

build.gradleのext

  • メリット

    • 古いバージョンでも動作する
    • バージョン管理用のファイルを作らなくていい
    • 記法はある程度自由(Groovyスクリプトも動作させられる)
  • デメリット

    • IDEの支援はない(AIはある程度支援してくれる)
    • OpenRewriteなどのmigrationツールのサポートはなし
    • プラグインの管理はできない(プラグインにも同じ記法を入れる必要がある)

まとめ

Version CatalogはIDE支援やGradle公式がサポートしている機能なので今後の拡張性を期待したいところです。現時点では巨大プロジェクトでない限りはbuild.gradleまわりの依存関係を触る頻度なども多くないので、IDE支援はないですがextで対応しても良いかなと思います。