From 238d5504d2f484d690f6c367d3dd1e7dcca836b0 Mon Sep 17 00:00:00 2001 From: "Alexander.Likhachev" Date: Tue, 30 Jan 2024 14:45:37 +0100 Subject: [PATCH] [Gradle] Add tests for KT-62921 --- .../kotlin/gradle/CompilerVersionChooseIT.kt | 110 ++++++++++++++++++ .../internals/ExposedForIntegrationTests.kt | 2 + 2 files changed, 112 insertions(+) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerVersionChooseIT.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerVersionChooseIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerVersionChooseIT.kt new file mode 100644 index 00000000000..659bae527fd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerVersionChooseIT.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle + +import org.gradle.testkit.runner.BuildResult +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.internals.KOTLIN_BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME +import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.DisplayName + +@DisplayName("Tests for compiler version choosing via the Build Tools API") +@JvmGradlePluginTests +class CompilerVersionChooseIT : KGPBaseTest() { + override val defaultBuildOptions = super.defaultBuildOptions.copy(runViaBuildToolsApi = true) + + @GradleTest + @DisplayName("Verify default compiler dependencies") + fun defaultClasspath(gradleVersion: GradleVersion) { + prepareProject(gradleVersion) { + build(printClasspathTaskName) { + assertCompilerVersion(buildOptions.kotlinVersion) + } + } + } + + @GradleTest + @DisplayName("Compiler version may be specified via the kotlin extension") + fun compilerVersionMayBeChanged(gradleVersion: GradleVersion) { + prepareProject(gradleVersion) { + chooseCompilerVersion(TestVersions.Kotlin.STABLE_RELEASE) + build(printClasspathTaskName) { + assertCompilerVersion(TestVersions.Kotlin.STABLE_RELEASE) + } + } + } + + @GradleTest + @DisplayName("Compiler version may be specified via the kotlin extension multiple times") + fun compilerVersionMayBeChangedMultipleTimes(gradleVersion: GradleVersion) { + prepareProject(gradleVersion) { + chooseCompilerVersion(buildOptions.kotlinVersion) + chooseCompilerVersion(TestVersions.Kotlin.STABLE_RELEASE) + build(printClasspathTaskName) { + assertCompilerVersion(TestVersions.Kotlin.STABLE_RELEASE) + } + } + } + + @GradleTest + @DisplayName("Manual adding dependencies to the classpath configuration does not change kotlin version") + fun manualAdding(gradleVersion: GradleVersion) { + prepareProject(gradleVersion) { + buildGradle.append( + //language=Gradle + """ + dependencies { + $KOTLIN_BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME("org.jetbrains.kotlin:kotlin-compiler-embeddable:${TestVersions.Kotlin.STABLE_RELEASE}") + } + """.trimIndent() + ) + build(printClasspathTaskName) { + assertCompilerVersion(buildOptions.kotlinVersion) + } + } + } + + private val printClasspathTaskName = "printBuildToolsApiClasspath" + + private fun BuildResult.assertCompilerVersion(version: String) { + val compilerDependencies = extractClasspathFromLogs() + .filter { "kotlin-compiler-embeddable" in it } + .toList() + assert(compilerDependencies.isNotEmpty()) { + "Expected dependencies to contain `kotlin-compiler-embeddable`" + } + val nonMatchingVersionDependencies = compilerDependencies + .filter { !it.endsWith("$version.jar") } + assert(nonMatchingVersionDependencies.isEmpty()) { + "Kotlin dependencies expected to be of version '$version', the following dependencies do not pass the check: $nonMatchingVersionDependencies" + } + } + + private val classpathLogLinePrefix = "kotlin classpath: " + + private fun BuildResult.extractClasspathFromLogs() = output.lineSequence() + .filter { it.startsWith(classpathLogLinePrefix) } + .map { it.replaceFirst(classpathLogLinePrefix, "") } + + private fun prepareProject(gradleVersion: GradleVersion, test: TestProject.() -> Unit = {}) { + project("simpleProject", gradleVersion) { + buildGradle.append( + //language=Gradle + """ + tasks.register("$printClasspathTaskName") { + FileCollection classpath = configurations.$KOTLIN_BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME + doFirst { + classpath.forEach { + println("$classpathLogLinePrefix" + it) + } + } + } + """.trimIndent() + ) + test() + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internals/ExposedForIntegrationTests.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internals/ExposedForIntegrationTests.kt index b4a0d7e24b7..15380d8c3fb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internals/ExposedForIntegrationTests.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internals/ExposedForIntegrationTests.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.internals import org.jetbrains.kotlin.compilerRunner.asFinishLogMessage +import org.jetbrains.kotlin.gradle.plugin.BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_INTERNAL_DIAGNOSTICS_USE_PARSABLE_FORMATTING import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE @@ -35,3 +36,4 @@ val KOTLIN_INTERNAL_DIAGNOSTICS_USE_PARSABLE_FORMATTING = KOTLIN_INTERNAL_DIAGNO val KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE = KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE val KOTLIN_DIAGNOSTIC_STACKTRACE_START = DIAGNOSTIC_STACKTRACE_START val KOTLIN_DIAGNOSTIC_STACKTRACE_END_SEPARATOR = DIAGNOSTIC_STACKTRACE_END_SEPARATOR +val KOTLIN_BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME = BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME