diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/BrokenLazyConfigurationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/BrokenLazyConfigurationIT.kt index 8493cdd7ec8..931a5230964 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/BrokenLazyConfigurationIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/BrokenLazyConfigurationIT.kt @@ -7,15 +7,22 @@ package org.jetbrains.kotlin.gradle.mpp import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.condition.OS +import kotlin.io.path.absolutePathString +import kotlin.io.path.appendText +import kotlin.io.path.readText +import kotlin.test.assertEquals -@MppGradlePluginTests @DisplayName("Broken task configuration avoidance doesn't lead to build failures at least with simple setups") class BrokenLazyConfigurationIT : KGPBaseTest() { + @JvmGradlePluginTests @GradleTest @DisplayName("works in JVM") fun testBrokenTcaInJvm(gradleVersion: GradleVersion) { project("kotlinJavaProject", gradleVersion) { + assert("sourceSets {" in buildGradle.readText()) buildGradle.modify { it.replace( "sourceSets {", @@ -29,13 +36,16 @@ class BrokenLazyConfigurationIT : KGPBaseTest() { } } + @MppGradlePluginTests @GradleTest @DisplayName("works in JS") fun testBrokenTcaInJs(gradleVersion: GradleVersion) { project("kotlin-js-browser-project", gradleVersion) { val subprojects = listOf("app", "base", "lib") for (subproject in subprojects) { - subProject(subproject).buildGradleKts.modify { + val subprojectBuildScript = subProject(subproject).buildGradleKts + assert("dependencies {" in subprojectBuildScript.readText()) + subprojectBuildScript.modify { it.replace( "dependencies {", """ @@ -49,10 +59,12 @@ class BrokenLazyConfigurationIT : KGPBaseTest() { } } + @MppGradlePluginTests @GradleTest @DisplayName("works in MPP") // aka KT-56131 fun testBrokenTcaInMpp(gradleVersion: GradleVersion) { project("new-mpp-lib-with-tests", gradleVersion) { + assert("apply plugin: 'kotlin-multiplatform'" in buildGradle.readText()) buildGradle.modify { it.replace( "apply plugin: 'kotlin-multiplatform'", @@ -65,4 +77,49 @@ class BrokenLazyConfigurationIT : KGPBaseTest() { build("build") } } -} \ No newline at end of file + + @Disabled + @MppGradlePluginTests + @GradleTest + @DisplayName("Changing build directory after task configuration doesn't lead to failures") + fun changingBuildDirInMpp(gradleVersion: GradleVersion) { + project("new-mpp-lib-with-tests", gradleVersion) { + buildGradle.appendText( + """ + tasks.whenTaskAdded {} // break lazy initialization of all tasks + + project.layout.buildDirectory.set(project.layout.projectDirectory.dir("build2")) + """.trimIndent() + ) + build("build") { + try { + assertDirectoryInProjectDoesNotExist("build") + assert(false) // The assertion above now fails. This line is to ensure try-catch is removed after fixing related issues + } catch (e: AssertionError) { + val expectedTopLevelSubdirectoriesMapping = mapOf( + "js" to "KT-61294", + "reports" to "KT-61295", + ) + val expectedTopLevelSubdirectories = expectedTopLevelSubdirectoriesMapping.keys + val actualTopLevelDirectories = + e.message?.lines()?.filter { it.startsWith(" ") }?.map { it.replace("\\", "").trim() }?.toSet() ?: emptySet() + + val fixed = expectedTopLevelSubdirectories - actualTopLevelDirectories + val new = actualTopLevelDirectories - expectedTopLevelSubdirectories + if (fixed.isNotEmpty()) { + throw Exception( + "Please remove the tests workaround for ${ + fixed.map(expectedTopLevelSubdirectoriesMapping::get).joinToString(" and ") + } as seems like it's not anymore required", e + ) + } + if (new.isNotEmpty()) { + throw Exception("Unexpected new top level files and/or directories are found: ${new.joinToString(",")}", e) + } + } + + assertDirectoryInProjectExists("build2") + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt index 40b35c6ab95..38c6839640d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.testbase import com.google.gson.JsonObject import com.google.gson.JsonParser +import java.lang.StringBuilder import java.nio.file.Files import java.nio.file.Path import java.util.zip.ZipFile @@ -159,6 +160,43 @@ fun assertDirectoriesExist( } } +private const val appendIndentationIncrement = 2U +private fun StringBuilder.appendDirectory(dirPath: Path, indentation: UInt = 0U) { + Files.newDirectoryStream(dirPath).use { stream -> + for (entry in stream) { + append("${"–".repeat(indentation.toInt())} ${entry.fileName}") + val isDirectory = Files.isDirectory(entry) + appendLine(if (isDirectory) " \\" else " (file)") + if (isDirectory) { + appendDirectory(entry, indentation + appendIndentationIncrement) + } + } + appendLine() + } +} + +fun GradleProject.assertDirectoryInProjectDoesNotExist( + dirName: String, +) { + assertDirectoryDoesNotExist(projectPath.resolve(dirName)) +} + +fun assertDirectoryDoesNotExist( + dirPath: Path, +) { + assert(!Files.exists(dirPath)) { + buildString { + append("Directory $dirPath is expected to not exist. ") + if (Files.isDirectory(dirPath)) { + appendLine("The directory contents: ") + appendDirectory(dirPath) + } else { + append("However, it is not even a directory.") + } + } + } +} + /** * Asserts file under [pathToFile] relative to the test project exists and contains all the lines from [expectedText] */