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

<a href="https://qiita.com/advent-calendar/2023/yumemi-23-graduation">
  <img alt="YUMEMI New Grad Advent Calendar 2023" width="1240" height="112" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/6d8a7098-9aef-a19a-54fe-83a2d493e033.png">
</a>

前回はJUnit 5で使用されているライブラリのバージョン定義についてみました。今回は個々のプロジェクトの設定についてみていきます。

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

https://github.com/junit-team/junit5/blob/main/LICENSE.md

JUnit 5のリポジトリ

https://github.com/junit-team/junit5

この記事は [`f5b78f68c6a90dfa63611c7a10027581c5d913ba`](https://github.com/junit-team/junit5/tree/f5b78f68c6a90dfa63611c7a10027581c5d913ba) での内容をベースにしています。
記事の中に出てくるコードはすべて上記のリポジトリや公式ドキュメントからの引用や一部改変です。

# 概要

* [JUnit 5リポジトリの構成について](https://qiita.com/k-kojima-yumemi/items/f05aaf38b77abd45db41)
* [共通で使われている設定について](https://qiita.com/k-kojima-yumemi/items/e9a28a3849c3c5693a7d)
* [バージョンの記述について](https://qiita.com/k-kojima-yumemi/items/f76f8752d2d476a52c22)
* 個々のプロジェクトの設定について<この記事>

前回は使用されているライブラリのバージョンの記述についてみていきました。
今回は個々のプロジェクトでの設定についてみていきます。

# プロジェクトの設定ファイル

一般的にはプロジェクトの設定には `build.gradle(.kts)` を使用します。
Junit 5では以下のドキュメントのように設定ファイルの名称を変更し、`(プロジェクト名).gradle.kts` のファイルを使用しています。

https://docs.gradle.org/current/userguide/fine_tuning_project_layout.html#sub:modifying_element_of_the_project_tree

`project.buildFileName` を変更することで設定ファイルを変更できます。

## `junit-jupiter-api`

このプロジェクトではJUnit 5で使われるAPIを定義しています。`org.junit.jupiter.api` のパッケージの内容です。
大部分はJavaで書かれていますが、一部Assertionの定義にKotlinが使われている箇所があります。

このプロジェクトの定義は以下のとおりです。

https://github.com/junit-team/junit5/blob/main/junit-jupiter-api/junit-jupiter-api.gradle.kts

```kotlin junit-jupiter-api.gradle.kts
plugins {
	id("junitbuild.kotlin-library-conventions")
	`java-test-fixtures`
}

description = "JUnit Jupiter API"

dependencies {
	api(platform(projects.junitBom))
	api(libs.opentest4j)
	api(projects.junitPlatformCommons)

	compileOnlyApi(libs.apiguardian)

	compileOnly(kotlin("stdlib"))

	osgiVerification(projects.junitJupiterEngine)
	osgiVerification(projects.junitPlatformLauncher)
}

tasks {
	jar {
		bundle {
			val version = project.version
			bnd("""
				Require-Capability:\
					org.junit.platform.engine;\
						filter:='(&(org.junit.platform.engine=junit-jupiter)(version>=${'$'}{version_cleanup;${version}})(!(version>=${'$'}{versionmask;+;${'$'}{version_cleanup;${version}}})))';\
						effective:=active
			""")
		}
	}
}
```

プラグインの使用、プロジェクトの命名、依存関係の記述、OSGiの設定(`tasks.jar.bundle` の箇所)しかありません。
大部分の設定は `junitbuild.kotlin-library-conventions` のプラグインに書かれているとわかります。
`junit-jupiter-api` が依存しているプラグインを列挙してみます。`junitbuild` から始まっているのが共通のプラグインです。

* `junit-jupiter-api`
    * [`java-test-fixtures`](https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures)
    * [`junitbuild.kotlin-library-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.kotlin-library-conventions.gradle.kts)
        * `kotlin("jvm")`
        * [`junitbuild.java-library-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.java-library-conventions.gradle.kts)
            * `java-library`
            * `eclipse`
            * `idea`
            * `checkstyle`
            * [`junitbuild.base-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.base-conventions.gradle.kts)
                * `eclipse`
                * `idea`
                * [`junitbuild.java-toolchain-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.java-toolchain-conventions.gradle.kts)
                    * [`junitbuild.build-parameters`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/build-parameters/build.gradle.kts)
                * [`junitbuild.spotless-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.spotless-conventions.gradle.kts)
                    * `com.diffplug.spotless`
            * [`junitbuild.jacoco-java-conventions`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/common/src/main/kotlin/junitbuild.jacoco-conventions.gradle.kts)
                * `jacoco`
                * [`junitbuild.build-parameters`](https://github.com/junit-team/junit5/blob/main/gradle/plugins/build-parameters/build.gradle.kts)

つまり、junit-jupiter-apiのビルドの設定を確認したいとなったらこれらのプラグインの設定内容を確認すればいいということになります。

dependenciesはVersion Catelogで定義しているものの他に他プロジェクトへの参照もあります。マルチプロジェクトならではの構成です。

## 他プロジェクト

他のプロジェクトも似た構成になっています。共通のプラグインを使用して大部分の設定を行い、個々のプロジェクトでは依存するライブラリの定義やそれに付随する埋め込み(shadowプラグイン)の設定などが記述されています。

# まとめ

今回はJUnit 5の個々のプロジェクトの設定を、`junit-jupiter-api` のプロジェクトを例にしてみていきました。
大部分の設定を共通化し、各プロジェクトでの記述を少なくするようになっていることがわかります。
どこにどのような設定がされているのかはファイル名にまとまっているので探しやすいです。JUnit 5ではやっているけどGradleでどうやっているのかわからない時に、参考にしやすいと思いました。