[Gradle] Migrate metadata caches to new persistent location

^KT-58223 In Progress
This commit is contained in:
Yahor Berdnikau
2023-08-14 22:33:44 +02:00
committed by Space Team
parent 0d57436bce
commit ce695de84d
6 changed files with 53 additions and 33 deletions
@@ -168,25 +168,32 @@ open class CommonizerIT : KGPBaseTest() {
@DisplayName("Commonize Curl Interop copy CommonizeCInterop for Ide")
@GradleTest
fun testCommonizeCurlInteropcopyCommonizeCInteropForIde(gradleVersion: GradleVersion) {
fun testCommonizeCurlInteropcopyCommonizeCInteropForIde(
gradleVersion: GradleVersion,
@TempDir tempDir: Path,
) {
nativeProject("commonizeCurlInterop", gradleVersion) {
configureCommonizerTargets()
val expectedOutputDirectoryForIde = projectPath.resolve(".kotlin/commonizer")
fun expectedOutputDirectoryForIde(): Path = tempDir
.resolve("projects-1")
.findInPath("commonizer") ?: throw IllegalStateException("Failed to find 'commonizer' directory!")
val expectedOutputDirectoryForBuild = projectPath.resolve("build/classes/kotlin/commonizer")
build(":copyCommonizeCInteropForIde") {
build(":copyCommonizeCInteropForIde", "-Pkotlin.user.home=${tempDir.absolutePathString()}") {
assertTasksExecuted(":cinteropCurlTargetB")
assertTasksExecuted(":commonizeCInterop")
assertDirectoryExists(expectedOutputDirectoryForIde, "Missing output directory for IDE")
val commonizerIdeOutput = expectedOutputDirectoryForIde()
assertDirectoryExists(commonizerIdeOutput, "Missing output directory for IDE")
assertDirectoryExists(expectedOutputDirectoryForBuild, "Missing output directory for build")
assertEqualDirectories(expectedOutputDirectoryForBuild.toFile(), expectedOutputDirectoryForIde.toFile(), false)
assertEqualDirectories(expectedOutputDirectoryForBuild.toFile(), commonizerIdeOutput.toFile(), false)
}
build(":clean") {
assertDirectoryExists(expectedOutputDirectoryForIde, "Expected ide output directory to survive cleaning")
build(":clean", "-Pkotlin.user.home=${tempDir.absolutePathString()}") {
assertDirectoryExists(expectedOutputDirectoryForIde(), "Expected ide output directory to survive cleaning")
assertFileNotExists(expectedOutputDirectoryForBuild, "Expected output directory for build to be cleaned")
}
}
@@ -535,23 +542,28 @@ open class CommonizerIT : KGPBaseTest() {
@DisplayName("KT-58223 test commonized libraries for IDE can be stored in different data dir")
@GradleTest
fun testCommonizedLibrariesForIDECanBeStoredInDifferentDir(gradleVersion: GradleVersion) {
fun testCommonizedLibrariesForIDECanBeStoredInDifferentDir(
gradleVersion: GradleVersion,
@TempDir tempDir: Path,
) {
nativeProject("commonizeCurlInterop", gradleVersion) {
gradleProperties.append("kotlin.persistent.gradle.data.dir=.kotlin_custom")
gradleProperties.append("kotlin.persistent.gradle.data.dir=${tempDir.absolutePathString()}")
configureCommonizerTargets()
val expectedOutputDirectoryForIde = projectPath.resolve(".kotlin_custom/commonizer")
fun expectedOutputDirectoryForIde(): Path = tempDir
.resolve("projects-1")
.findInPath("commonizer") ?: throw IllegalStateException("Failed to find 'commonizer' directory!")
build(":copyCommonizeCInteropForIde") {
assertTasksExecuted(":cinteropCurlTargetB")
assertTasksExecuted(":commonizeCInterop")
assertDirectoryExists(expectedOutputDirectoryForIde, "Missing output directory for IDE")
assertDirectoryExists(expectedOutputDirectoryForIde(), "Missing output directory for IDE")
}
build(":clean") {
assertDirectoryExists(expectedOutputDirectoryForIde, "Expected ide output directory to survive cleaning")
assertDirectoryExists(expectedOutputDirectoryForIde(), "Expected ide output directory to survive cleaning")
}
}
}
@@ -189,8 +189,15 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
}
@GradleTest
fun `test cinterops - are stored in root gradle folder`(gradleVersion: GradleVersion) {
project(projectName = "cinteropImport", gradleVersion = gradleVersion) {
fun `test cinterops - are stored in root gradle folder`(
gradleVersion: GradleVersion,
@TempDir tempDir: Path,
) {
project(
projectName = "cinteropImport",
gradleVersion = gradleVersion,
buildOptions = defaultBuildOptions.copy(kotlinUserHome = tempDir)
) {
resolveIdeDependencies("dep-with-cinterop") { dependencies ->
/* Check behaviour of platform cinterops on linuxX64Main */
@@ -198,12 +205,12 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
.filter { !it.isNativeDistribution && it.klibExtra?.isInterop == true }
.ifEmpty { fail("Expected at least one cinterop on linuxX64Main") }
val persistentCInteropsCache = tempDir.inProjectsPersistentCache("kotlinCInteropLibraries")
cinterops.forEach { cinterop ->
if (cinterop.classpath.isEmpty()) fail("Missing classpath for $cinterop")
cinterop.classpath.forEach { cinteropFile ->
/* Check file was copied into root .gradle folder */
val expectedParent = projectPath.toFile().resolve(".gradle/kotlin/kotlinCInteropLibraries").canonicalFile
assertEquals(expectedParent, cinteropFile.parentFile.canonicalFile)
assertEquals(persistentCInteropsCache.toFile().canonicalFile, cinteropFile.parentFile.canonicalFile)
/* Check crc in file name */
val crc = CRC32()
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.gradle.api.file.ProjectLayout
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.utils.compositeBuildRootProject
import org.jetbrains.kotlin.gradle.utils.kotlinMetadataDir
import java.io.File
private const val kotlinTransformedMetadataLibraries = "kotlinTransformedMetadataLibraries"
@@ -18,23 +18,20 @@ private const val kotlinTransformedCInteropMetadataLibraries = "kotlinTransforme
internal fun ProjectLayout.kotlinTransformedMetadataLibraryDirectoryForBuild(sourceSetName: String): File =
buildDirectory.get().asFile.resolve(kotlinTransformedMetadataLibraries).resolve(sourceSetName)
internal val Project.kotlinGradleDataDirCompat
get() = kotlinPropertiesProvider.kotlinPersistentGradleDataDir ?: ".kotlin"
internal val Project.kotlinTransformedMetadataLibraryDirectoryForIde: File
get() = compositeBuildRootProject.rootDir
.resolve(project.kotlinGradleDataDirCompat)
get() = compositeBuildRootProject
.kotlinMetadataDir
.resolve(kotlinTransformedMetadataLibraries)
internal fun ProjectLayout.kotlinTransformedCInteropMetadataLibraryDirectoryForBuild(sourceSetName: String): File =
buildDirectory.get().asFile.resolve(kotlinTransformedCInteropMetadataLibraries).resolve(sourceSetName)
internal val Project.kotlinCInteropLibraryDirectoryForIde: File
get() = compositeBuildRootProject.rootDir
.resolve(project.kotlinGradleDataDirCompat)
get() = compositeBuildRootProject
.kotlinMetadataDir
.resolve(kotlinCInteropLibraries)
internal val Project.kotlinTransformedCInteropMetadataLibraryDirectoryForIde: File
get() = compositeBuildRootProject.rootDir
.resolve(project.kotlinGradleDataDirCompat)
get() = compositeBuildRootProject
.kotlinMetadataDir
.resolve(kotlinTransformedCInteropMetadataLibraries)
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
import org.jetbrains.kotlin.compilerRunner.addBuildMetricsForTaskAction
import org.jetbrains.kotlin.gradle.report.GradleBuildMetricsReporter
import org.jetbrains.kotlin.gradle.utils.kotlinMetadataDir
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinGradleDataDirCompat
import java.io.File
import javax.inject.Inject
@@ -33,8 +33,7 @@ internal abstract class CopyCommonizeCInteropForIdeTask @Inject constructor(
commonizeCInteropTask.map { it.allOutputDirectories }
@get:OutputDirectory
override val outputDirectory: File = project.rootDir
.resolve(project.kotlinGradleDataDirCompat)
override val outputDirectory: File = project.kotlinMetadataDir
.resolve("commonizer")
.resolve(project.path.removePrefix(":").replace(":", "/"))
@@ -15,6 +15,7 @@ private const val PROJECTS_CACHE_VERSION = 1
private const val PROJECTS_CACHE_NAME_FULL = "$PROJECTS_CACHE_NAME-$PROJECTS_CACHE_VERSION"
private const val SESSIONS_DIR_NAME = "sessions"
private const val METADATA_DIR_NAME = "metadata"
internal val Project.basePersistentDir
get() = kotlinPropertiesProvider.kotlinPersistentGradleDataDir?.let { File(it) }
@@ -23,6 +24,11 @@ internal val Project.basePersistentDir
internal val Project.kotlinSessionsDir
get() = basePersistentDir.resolve(PROJECTS_CACHE_NAME_FULL).resolve(rootDir.absolutePathMd5Hash()).resolve(SESSIONS_DIR_NAME)
internal val Project.kotlinMetadataDir
get() = basePersistentDir.projectSpecificCache(rootDir).resolve(METADATA_DIR_NAME)
private val md5Digest by lazy { MessageDigest.getInstance("MD5") }
private fun File.absolutePathMd5Hash(): String = md5Digest.digest(absolutePath.toByteArray()).toHexString()
private fun File.projectSpecificCache(projectRootDir: File) = resolve(PROJECTS_CACHE_NAME_FULL).resolve(projectRootDir.absolutePathMd5Hash())
@@ -11,6 +11,7 @@ import org.gradle.api.Project
import org.gradle.api.internal.TaskInternal
import org.gradle.testfixtures.ProjectBuilder
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinTransformedCInteropMetadataLibraryDirectoryForIde
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrRegisterCInteropMetadataDependencyTransformationTask
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrRegisterCInteropMetadataDependencyTransformationTaskForIde
@@ -135,14 +136,12 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
nativeMain as DefaultKotlinSourceSet
) ?: fail("Expected transformation task registered for '$nativeMain'")
val cinteropTransformationTask = cinteropTransformationTaskProvider.get()
val projectRootDir = rootDir
return cinteropTransformationTask
.outputs
.files
.map { it.relativeTo(projectRootDir) }
.toSet()
// common root directory where all transformations stored
.minus(File(".kotlin/kotlinTransformedCInteropMetadataLibraries"))
// Shared output directory itself is always present in every task output
.minus(kotlinTransformedCInteropMetadataLibraryDirectoryForIde)
}
suspend fun assertTasksOutputsDoesntIntersect(a: Project, b: Project) {