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