Skip to content

Commit

Permalink
* move test framework configuration into an action run directly befor…
Browse files Browse the repository at this point in the history
…e the tests run, to avoid to early dependency resolution (#30)

* move JavaPlugin configuration outside `afterEvaluate` to enable the user to manipulate those settings
* fix KotlinConfigurePlugin configuring the JavaToolchain.languageVersion Property to use itself as a provider
* add check to Kotlin tests, to ensure the JDK of the JavaToolchain is used during Kotlin compilation

Signed-off-by: Clemens Grabmann <[email protected]>
  • Loading branch information
cgrabmann authored May 13, 2022
1 parent 864bfec commit dc268e8
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.gradle.api.tasks.testing.Test
import org.gradle.jvm.tasks.Jar
import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.testing.jacoco.plugins.JacocoPlugin
import org.jetbrains.kotlin.gradle.plugin.statistics.ReportStatisticsToElasticSearch.user
import org.slf4j.LoggerFactory

private const val GRADLE_VERSION = "Gradle-Version"
Expand All @@ -34,21 +35,26 @@ class JavaConfigurePlugin : Plugin<Project> {
val extensions = project.extensions
val tasks = project.tasks

extensions.create(EXTENSION_NAME, JavaConfigurePluginExtension::class).apply {
val javaConfigureExtension = extensions.create(EXTENSION_NAME, JavaConfigurePluginExtension::class).apply {
languageVersion.convention(JAVA_LANGUAGE_VERSION)
encoding.convention(JAVA_ENCODING)
vendorName.convention(VENDOR_NAME)
applicationBuild.convention(false)
}

project.afterEvaluate {
val javaPluginExtension = extensions.getByType(JavaPluginExtension::class)
javaPluginExtension.modularity.inferModulePath.set(true)
javaPluginExtension.toolchain.languageVersion.set(javaConfigureExtension.languageVersion)

val javaConfigureExtension = extensions.getByType(JavaConfigurePluginExtension::class)
tasks.named(JavaPlugin.JAR_TASK_NAME, Jar::class).configure {
it.doFirst(PopulateManifestAction)
}

val javaPluginExtension = extensions.getByType(JavaPluginExtension::class)
tasks.named(JavaPlugin.TEST_TASK_NAME, Test::class).configure {
it.doFirst(ConfigureUnitTestFrameworkAction)
}

javaPluginExtension.modularity.inferModulePath.set(true)
javaPluginExtension.toolchain.languageVersion.set(javaConfigureExtension.languageVersion)
project.afterEvaluate {

if (!javaConfigureExtension.applicationBuild.get()) {
javaPluginExtension.withSourcesJar()
Expand All @@ -63,35 +69,34 @@ class JavaConfigurePlugin : Plugin<Project> {
compileTest.configure {
it.options.encoding = javaConfigureExtension.encoding.get()
}
}
}

val jar = tasks.named(JavaPlugin.JAR_TASK_NAME, Jar::class).get()
jar.doFirst(PopulateManifestAction)

val testTask = tasks.named(JavaPlugin.TEST_TASK_NAME, Test::class)
testTask.configure {
val testRuntimeDependencies =
project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME)
val useJunit =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == JUNIT_4_ARTIFACT_GROUP }
val useJunitPlatform =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == JUNIT_PLATFORM_ARTIFACT_GROUP }
val useTestNG =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == TESTNG_ARTIFACT_GROUP }

if (arrayOf(useJunit, useJunitPlatform, useTestNG).filter { enabled -> enabled }.size > 1) {
LOG.warn("Multiple testing frameworks detected in runtime dependencies. No framework enabled automatically. junit4: $useJunit, junit5: $useJunitPlatform, testNg: $useTestNG")
} else if (useJunit) {
it.useJUnit()
LOG.info("Enabled Junit4 as test platform")
} else if (useJunitPlatform) {
it.useJUnitPlatform()
LOG.info("Enabled Junit5 as test platform")
} else if (useTestNG) {
it.useTestNG()
LOG.info("Enabled TestNG as test platform")
} else {
LOG.warn("No testing framework detected in runtime dependencies. No framework enabled automatically")
}
private object ConfigureUnitTestFrameworkAction : Action<Task> {
override fun execute(t: Task) {
val test = t as Test
val testRuntimeDependencies =
t.project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME)
val useJunit =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == JUNIT_4_ARTIFACT_GROUP }
val useJunitPlatform =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == JUNIT_PLATFORM_ARTIFACT_GROUP }
val useTestNG =
testRuntimeDependencies.allDependencies.contains { dep -> dep.group == TESTNG_ARTIFACT_GROUP }

if (arrayOf(useJunit, useJunitPlatform, useTestNG).filter { enabled -> enabled }.size > 1) {
LOG.warn("Multiple testing frameworks detected in runtime dependencies. No framework enabled automatically. junit4: $useJunit, junit5: $useJunitPlatform, testNg: $useTestNG")
} else if (useJunit) {
test.useJUnit()
LOG.info("Enabled Junit4 as test platform")
} else if (useJunitPlatform) {
test.useJUnitPlatform()
LOG.info("Enabled Junit5 as test platform")
} else if (useTestNG) {
test.useTestNG()
LOG.info("Enabled TestNG as test platform")
} else {
LOG.warn("No testing framework detected in runtime dependencies. No framework enabled automatically")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ class KotlinConfigurePlugin : Plugin<Project> {
)
}

// https://kotlinlang.org/docs/gradle.html#gradle-java-toolchains-support
val javaPluginExtension = extensions.getByType(JavaPluginExtension::class)
kotlin.jvmToolchain {
(it as JavaToolchainSpec).languageVersion.set(javaPluginExtension.toolchain.languageVersion)
}

project.afterEvaluate {
val kotlinVersion = kotlinConfigureExtension.kotlinVersion.get()
val kotlinMajorMinor = kotlinVersion.toMajorMinor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,9 @@ dependencies {
}
}

tasks.getByName(JavaPlugin.COMPILE_JAVA_TASK_NAME).doLast {
def javaPluginExtension = project.extensions.getByType(JavaPluginExtension)
def inferModulePath = javaPluginExtension.hasProperty("modularity") ? javaPluginExtension.modularity.inferModulePath.get() : false
logger.quiet("javaPluginExtension.modularity.inferModulePath: {}", inferModulePath)
logger.quiet("javaPluginExtension.sourceCompatibility: {}", javaPluginExtension.sourceCompatibility)
logger.quiet("javaPluginExtension.targetCompatibility: {}", javaPluginExtension.targetCompatibility)
logger.quiet("compileJava.options.encoding: {}", options.encoding)
}

tasks.getByName(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME).doLast {
logger.quiet("compileTestJava.options.encoding: {}", options.encoding)
tasks.compileKotlin.doLast {
def compiler = javaToolchains.compilerFor {
languageVersion.set(project.javaConfigure.languageVersion)
}
logger.quiet("javaToolchain.jdkHome: {}", compiler.get().metadata.installationPath.asFile.absolutePath)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,9 @@ kotlinConfigure {
kotlinVersion = "1.5.20"
}

tasks.getByName(JavaPlugin.COMPILE_JAVA_TASK_NAME).doLast {
def javaPluginExtension = project.extensions.getByType(JavaPluginExtension)
def inferModulePath = javaPluginExtension.hasProperty("modularity") ? javaPluginExtension.modularity.inferModulePath.get() : false
logger.quiet("javaPluginExtension.modularity.inferModulePath: {}", inferModulePath)
logger.quiet("javaPluginExtension.sourceCompatibility: {}", javaPluginExtension.sourceCompatibility)
logger.quiet("javaPluginExtension.targetCompatibility: {}", javaPluginExtension.targetCompatibility)
logger.quiet("compileJava.options.encoding: {}", options.encoding)
}

tasks.getByName(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME).doLast {
logger.quiet("compileTestJava.options.encoding: {}", options.encoding)
tasks.compileKotlin.doLast {
def compiler = javaToolchains.compilerFor {
languageVersion.set(project.javaConfigure.languageVersion)
}
logger.quiet("javaToolchain.jdkHome: {}", compiler.get().metadata.installationPath.asFile.absolutePath)
}
16 changes: 5 additions & 11 deletions src/test/fixtures/kotlin/single-kotlin-module-server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,9 @@ dependencies {
}
}

tasks.getByName(JavaPlugin.COMPILE_JAVA_TASK_NAME).doLast {
def javaPluginExtension = project.extensions.getByType(JavaPluginExtension)
def inferModulePath = javaPluginExtension.hasProperty("modularity") ? javaPluginExtension.modularity.inferModulePath.get() : false
logger.quiet("javaPluginExtension.modularity.inferModulePath: {}", inferModulePath)
logger.quiet("javaPluginExtension.sourceCompatibility: {}", javaPluginExtension.sourceCompatibility)
logger.quiet("javaPluginExtension.targetCompatibility: {}", javaPluginExtension.targetCompatibility)
logger.quiet("compileJava.options.encoding: {}", options.encoding)
}

tasks.getByName(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME).doLast {
logger.quiet("compileTestJava.options.encoding: {}", options.encoding)
tasks.compileKotlin.doLast {
def compiler = javaToolchains.compilerFor {
languageVersion.set(project.javaConfigure.languageVersion)
}
logger.quiet("javaToolchain.jdkHome: {}", compiler.get().metadata.installationPath.asFile.absolutePath)
}
16 changes: 5 additions & 11 deletions src/test/fixtures/kotlin/single-kotlin-module/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@ javaConfigure {
vendorName = "Cloudflight XYZ"
}

tasks.getByName(JavaPlugin.COMPILE_JAVA_TASK_NAME).doLast {
def javaPluginExtension = project.extensions.getByType(JavaPluginExtension)
def inferModulePath = javaPluginExtension.hasProperty("modularity") ? javaPluginExtension.modularity.inferModulePath.get() : false
logger.quiet("javaPluginExtension.modularity.inferModulePath: {}", inferModulePath)
logger.quiet("javaPluginExtension.sourceCompatibility: {}", javaPluginExtension.sourceCompatibility)
logger.quiet("javaPluginExtension.targetCompatibility: {}", javaPluginExtension.targetCompatibility)
logger.quiet("compileJava.options.encoding: {}", options.encoding)
}

tasks.getByName(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME).doLast {
logger.quiet("compileTestJava.options.encoding: {}", options.encoding)
tasks.compileKotlin.doLast {
def compiler = javaToolchains.compilerFor {
languageVersion.set(project.javaConfigure.languageVersion)
}
logger.quiet("javaToolchain.jdkHome: {}", compiler.get().metadata.installationPath.asFile.absolutePath)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import io.cloudflight.gradle.autoconfigure.test.util.ProjectFixture
import io.cloudflight.gradle.autoconfigure.test.util.normalizedOutput
import io.cloudflight.gradle.autoconfigure.test.util.useFixture
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.ThrowingConsumer
import org.gradle.testkit.runner.BuildResult
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.Arguments.arguments
Expand Down Expand Up @@ -56,6 +58,12 @@ class KotlinConfigurePluginTest {

assertThat(result.normalizedOutput).contains("--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:${options.kotlinVersion}")

// validate that Kotlin uses the jdk configured by the java toolchain
val jdkHome = result.extractJavaToolchainJdkHome()
val kotlinJdkLines = result.normalizedOutput.lines().filter { it.startsWith("[KOTLIN]") }
val validateJdkHome = ThrowingConsumer<String> { input -> assertThat(input).contains(jdkHome) }
assertThat(kotlinJdkLines).isNotEmpty.allSatisfy(validateJdkHome)

println(result.output)
}

Expand Down Expand Up @@ -119,6 +127,11 @@ class KotlinConfigurePluginTest {
}
}

private fun BuildResult.extractJavaToolchainJdkHome(): String {
val prefix = "javaToolchain.jdkHome: "
return this.normalizedOutput.lines().first { it.startsWith(prefix) }.removePrefix(prefix)
}

private val KOTLIN_FIXTURE_PATH = Paths.get("kotlin")
private fun <T : Any> javaFixture(fixtureName: String, gradleVersion: String?, testWork: ProjectFixture.() -> T): T =
useFixture(KOTLIN_FIXTURE_PATH, fixtureName, gradleVersion, testWork)

0 comments on commit dc268e8

Please sign in to comment.