1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

株式会社ゆめみの23卒Advent Calendar 2023

Day 15

JUnit 5のビルドシステムを探る(その3)

Last updated at Posted at 2023-12-15
YUMEMI New Grad Advent Calendar 2023

前回はJUnit 5の各プロジェクトで共通に使用されているプラグインについてみました。今回は使用しているライブラリなどのバージョンの設定方法について見ていきます。

JUnit 5のライセンス Eclipse Public License - v 2.0

JUnit 5のリポジトリ

この記事は f5b78f68c6a90dfa63611c7a10027581c5d913ba での内容をベースにしています。
記事の中に出てくるコードはすべて上記のリポジトリや公式ドキュメントからの引用や一部改変です。

概要

前回の記事

前回は共通の設定を記述しているプラグインについてみていきました。

今回は使用されているライブラリのバージョンの記述についてみていきます。

Version Catalogについて

Gradleにはversion catalogを呼ばれるシステムがあり、複数のプロジェクトで依存関係を共有することができます。

settings.gradle.kts での設定方法

公式ドキュメントには以下の記述が例として挙げられています。この記述により、 build.gradle.kts 内で libs.groovy.core と参照することができます。libs.groovy.corelibrary("groovy-core", "org.codehaus.groovy:groovy:3.0.5") で定義されているgroovyのライブラリを表します。ライブラリの名前のハイフンやアンダースコアはドット(.)に変換されるルールになっています。
libs 以下の各ライブラリについて、IDEの補完が効きます。

kotlin 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")
            }
        }
    }
}

この方法であればサブプロジェクト間で依存しているバージョンが異なってしまうことを防ぎやすくなります。ドキュメントにもある通り、この方法は使用するバージョンを強制する方法ではないので、全てのバージョンを合わせるのであればバージョンの書き方を libs.groovy.core の形式で統一する必要があります。

kotlin build.gradle.kts
dependencies {
    implementation(libs.groovy.core)
    implementation(libs.groovy.json)
    // version catalogの書き方と今まで通りの書き方を併用することも可能
    implementation("org.codehaus.groovy:groovy-nio:3.0.5")
}

コメントにもある通り、これまで通りの書き方と混在させることも可能ですがバージョンの記述箇所が散在してしまうためおすすめされません。

libs.versions.toml での設定方法

さらに、以下の方法でtomlファイルを記述することでもversion catalogを使用できます。

toml gradle/libs.versions.toml
[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" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }

こちらの方法でも上記の settings.gradle.kts と同様に libs.groovy.core で参照ができます。
dependabotもRenovateもlibs.version.tomlを認識してバージョンのチェックをしてくれるようです。

Pluginのバージョン定義

tomlでは以下のようにPluginのバージョンを定義できます。

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

使用する場合にはpluginブロックの中に以下のように記述します。

kotlin build.gradle.kts
plugins {
    alias(libs.plugins.versions)
}

ただしこの記法はプラグインの定義内では使用できません。プロジェクトの定義でのみ使用できます。
各プロジェクトで共通に使用されているプラグインの中では別の方法での記述が必要です。

JUnit 5でのバージョン管理

JUnit 5では gradle/libs.versions.toml にバージョン定義を記述しています。

ファイルをよく見てみると [libraries][plugins] に一部重複して記述されているライブラリがあります。これは [libraries] をうまく使うことで、gradle/plugins 配下の、共通で使用しているプラグイン内で依存するプラグインのバージョンを統一しています。(プラグイン内でdependenciesにversion catalogを使うにはさらに工夫が必要です)

共通で使用しているプラグイン内でのバージョン管理

共通で使用しているプラグイン内でのバージョンを揃えるために、 gradle/plugins/settings.gradle.kts で以下の定義がされています。

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

この記述により gradle/libs.versions.toml からVersion Catalogを読み込んでいます。この方法についてはドキュメントにも記載があります。

またプラグインの中で依存しているプラグインを定義するために、gradle/plugins/common/build.gradle.kts で以下の記載があります。この記載によって libs.versions.toml で定義したバージョンのプラグインを使用するようにできます。

kotlin build.gradle.kts
dependencies {
	implementation(projects.buildParameters)
	implementation(kotlin("gradle-plugin"))
    // これ以下の部分がlibs.versions.tomlで定義されているプラグインです
	implementation(libs.gradle.bnd)
	implementation(libs.gradle.commonCustomUserData)
	implementation(libs.gradle.enterprise)
	implementation(libs.gradle.foojayResolver)
	implementation(libs.gradle.shadow)
	implementation(libs.gradle.spotless)
	implementation(libs.gradle.versions)
}

例えば junitbuild.shadow-conventions.gradle.kts のファイルではshadowプラグインを使用しています。

plugins {
	id("junitbuild.java-library-conventions")
	id("com.github.johnrengelman.shadow")
}

プラグイン内ではバージョンの記載はしませんが、これで build.gradle.kts でdependenciesに記述したバージョンが使用されます。

dependencies内の依存ライブラリを記述するための工夫として、JUnit 5では ProjectExtensions.kt のファイルを定義しています。

ここで定義されている dependencyFromLibs の関数を使うことで libs.versions.toml で定義したバージョン定義を使用しています。ただしライブラリ名の補完が効きません。junitbuild.testing-conventions.gradle.kts などのファイルで使用されています。

Gradleのドキュメントではこちらに書かれている内容になります。

各プロジェクトでのバージョン管理

個々のプロジェクトではドキュメント通り定義するだけです。例えば junit-jupiter-engine.gradle.kts のファイルでは以下のようにdependenciesを定義しています。

kotlin build.gradle.kts
dependencies {
	api(platform(projects.junitBom))
	api(projects.junitPlatformEngine)
	api(projects.junitJupiterApi)

	compileOnlyApi(libs.apiguardian)

	testImplementation(projects.junitPlatformLauncher)
	testImplementation(projects.junitPlatformSuiteEngine)
	testImplementation(projects.junitPlatformTestkit)
	testImplementation(testFixtures(projects.junitPlatformCommons))
	testImplementation(kotlin("stdlib"))
	testImplementation(libs.jimfs)
	testImplementation(libs.junit4)
	testImplementation(libs.kotlinx.coroutines)
	testImplementation(libs.groovy4)
	testImplementation(libs.memoryfilesystem)
	testImplementation(testFixtures(projects.junitJupiterApi))

	osgiVerification(projects.junitPlatformLauncher)
}

libs から始まるライブラリがVersion Catalogで定義されている依存関係です。

まとめ

今回はJUnit 5で使用しているライブラリなどのバージョンの設定方法についてみていきました。
他のプロジェクトを見ていくことで、Gradleを使ってどのような記述が可能か、何ができるのか、どのように工夫するかがわかるので大変参考になります。

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?