From 070de9cc851eb36f66211afd619ad10c8f61bd37 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Tue, 24 Oct 2023 15:33:47 +0200 Subject: [PATCH] [Gradle] Split global and project persistent caches Now for project persistent caches plugin will use '/.kotlin' directory. Global persistent cache has stayed in the '/.kotlin' directory. ^KT-58223 Fixed --- .../jetbrains/kotlin/gradle/BuildReportsIT.kt | 17 ++++------- .../jetbrains/kotlin/gradle/CommonizerIT.kt | 23 ++++++--------- .../gradle/MppIdeDependencyResolutionIT.kt | 4 +-- .../kotlin/gradle/SimpleKotlinGradleIT.kt | 10 +++---- .../kotlin/gradle/testbase/pathHelpers.kt | 19 +++---------- .../plugin/KotlinGradleBuildServices.kt | 12 +++----- .../gradle/plugin/KotlinPluginWrapper.kt | 2 +- .../gradle/plugin/PropertiesProvider.kt | 12 +++++++- .../mpp/KotlinMetadataLibraryDirectories.kt | 9 ++---- ...yCInteropCommonizerTaskOutputForIdeTask.kt | 2 +- .../kotlin/gradle/utils/persistentCaches.kt | 28 ++++++++----------- 11 files changed, 55 insertions(+), 83 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt index 76eaee46ddf..8312ae4bf42 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt @@ -17,7 +17,6 @@ import kotlin.io.path.* import kotlin.test.assertTrue import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.testbase.TestVersions.ThirdPartyDependencies.GRADLE_ENTERPRISE_PLUGIN_VERSION -import org.junit.jupiter.api.io.TempDir @DisplayName("Build reports") @JvmGradlePluginTests @@ -271,16 +270,14 @@ class BuildReportsIT : KGPBaseTest() { @GradleTest fun testErrorsFileSmokeTest( gradleVersion: GradleVersion, - @TempDir tempDir: Path, ) { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(kotlinUserHome = tempDir) ) { val lookupsTab = projectPath.resolve("build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab") - fun kotlinErrorPath() = tempDir.inProjectsPersistentCache("errors") + val kotlinErrorPath = projectPersistentCache.resolve("errors") buildGradle.appendText( """ @@ -293,14 +290,14 @@ class BuildReportsIT : KGPBaseTest() { ) build("compileKotlin") { - assertTrue { kotlinErrorPath().listDirectoryEntries().isEmpty() } + assertTrue { kotlinErrorPath.listDirectoryEntries().isEmpty() } assertOutputDoesNotContain("errors were stored into file") } val kotlinFile = kotlinSourcesDir().resolve("helloWorld.kt") kotlinFile.modify { it.replace("ArrayList", "skjfghsjk") } buildAndFail("compileKotlin", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) { assertOutputContains("errors were stored into file") - val files = kotlinErrorPath().listDirectoryEntries() + val files = kotlinErrorPath.listDirectoryEntries() assertTrue { files.first().exists() } files.first().bufferedReader().use { reader -> val kotlinVersion = reader.readLine() @@ -324,24 +321,22 @@ class BuildReportsIT : KGPBaseTest() { @GradleTest fun testErrorsFileWithCompilationError( gradleVersion: GradleVersion, - @TempDir tempDir: Path, ) { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(kotlinUserHome = tempDir) ) { - fun kotlinErrorPath() = tempDir.inProjectsPersistentCache("errors") + val kotlinErrorPath = projectPersistentCache.resolve("errors") build("compileKotlin", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) { assertOutputDoesNotContain("errors were stored into file") - assertTrue { kotlinErrorPath().listDirectoryEntries().isEmpty() } + assertTrue { kotlinErrorPath.listDirectoryEntries().isEmpty() } } val kotlinFile = kotlinSourcesDir().resolve("helloWorld.kt") kotlinFile.modify { it.replace("ArrayList", "skjfghsjk") } buildAndFail("compileKotlin", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) { assertOutputDoesNotContain("errors were stored into file") - assertTrue { kotlinErrorPath().listDirectoryEntries().isEmpty() } + assertTrue { kotlinErrorPath.listDirectoryEntries().isEmpty() } } } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt index 5eeb08a3f23..eca2d62ea29 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt @@ -170,28 +170,26 @@ open class CommonizerIT : KGPBaseTest() { @GradleTest fun testCommonizeCurlInteropcopyCommonizeCInteropForIde( gradleVersion: GradleVersion, - @TempDir tempDir: Path, ) { - nativeProject("commonizeCurlInterop", gradleVersion, buildOptions = defaultBuildOptions.copy(kotlinUserHome = null)) { + nativeProject("commonizeCurlInterop", gradleVersion) { configureCommonizerTargets() - fun expectedOutputDirectoryForIde(): Path = tempDir.inProjectsPersistentCache("commonizer") + val commonizerIdeOutput: Path = projectPersistentCache.resolve("metadata").resolve("commonizer") val expectedOutputDirectoryForBuild = projectPath.resolve("build/classes/kotlin/commonizer") - build(":copyCommonizeCInteropForIde", "-Pkotlin.user.home=${tempDir.absolutePathString()}") { + build(":copyCommonizeCInteropForIde") { assertTasksExecuted(":cinteropCurlTargetB") assertTasksExecuted(":commonizeCInterop") - val commonizerIdeOutput = expectedOutputDirectoryForIde() assertDirectoryExists(commonizerIdeOutput, "Missing output directory for IDE") assertDirectoryExists(expectedOutputDirectoryForBuild, "Missing output directory for build") assertEqualDirectories(expectedOutputDirectoryForBuild.toFile(), commonizerIdeOutput.toFile(), false) } - build(":clean", "-Pkotlin.user.home=${tempDir.absolutePathString()}") { - assertDirectoryExists(expectedOutputDirectoryForIde(), "Expected ide output directory to survive cleaning") + build(":clean") { + assertDirectoryExists(commonizerIdeOutput, "Expected ide output directory to survive cleaning") assertFileNotExists(expectedOutputDirectoryForBuild, "Expected output directory for build to be cleaned") } } @@ -542,24 +540,21 @@ open class CommonizerIT : KGPBaseTest() { @GradleTest fun testCommonizedLibrariesForIDECanBeStoredInDifferentDir( gradleVersion: GradleVersion, - @TempDir tempDir: Path, ) { - nativeProject("commonizeCurlInterop", gradleVersion, buildOptions = defaultBuildOptions.copy(kotlinUserHome = null)) { - gradleProperties.append("kotlin.user.home=${tempDir.absolutePathString()}") - + nativeProject("commonizeCurlInterop", gradleVersion) { configureCommonizerTargets() - fun expectedOutputDirectoryForIde(): Path = tempDir.inProjectsPersistentCache("commonizer") + val commonizerIdeOutput: Path = projectPersistentCache.resolve("metadata").resolve("commonizer") build(":copyCommonizeCInteropForIde") { assertTasksExecuted(":cinteropCurlTargetB") assertTasksExecuted(":commonizeCInterop") - assertDirectoryExists(expectedOutputDirectoryForIde(), "Missing output directory for IDE") + assertDirectoryExists(commonizerIdeOutput, "Missing output directory for IDE") } build(":clean") { - assertDirectoryExists(expectedOutputDirectoryForIde(), "Expected ide output directory to survive cleaning") + assertDirectoryExists(commonizerIdeOutput, "Expected ide output directory to survive cleaning") } } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MppIdeDependencyResolutionIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MppIdeDependencyResolutionIT.kt index 9c3f0d8bf73..c39a5d8b817 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MppIdeDependencyResolutionIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MppIdeDependencyResolutionIT.kt @@ -191,12 +191,10 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() { @GradleTest 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 -> @@ -205,7 +203,7 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() { .filter { !it.isNativeDistribution && it.klibExtra?.isInterop == true } .ifEmpty { fail("Expected at least one cinterop on linuxX64Main") } - val persistentCInteropsCache = tempDir.inProjectsPersistentCache("kotlinCInteropLibraries") + val persistentCInteropsCache = projectPersistentCache.resolve("metadata").resolve("kotlinCInteropLibraries") cinterops.forEach { cinterop -> if (cinterop.classpath.isEmpty()) fail("Missing classpath for $cinterop") cinterop.classpath.forEach { cinteropFile -> diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/SimpleKotlinGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/SimpleKotlinGradleIT.kt index c5091b2f9f5..02aa6d51573 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/SimpleKotlinGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/SimpleKotlinGradleIT.kt @@ -5,6 +5,7 @@ import org.gradle.api.logging.configuration.WarningMode import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.io.TempDir import java.nio.file.Path @@ -293,6 +294,7 @@ class SimpleKotlinGradleIT : KGPBaseTest() { } } + @Disabled("KT-58223: Currently is not used and we should start using it after working on followup issues") @DisplayName("Possible to override kotlin.user.home location") @GradleTest fun overrideKotlinUserHome( @@ -307,19 +309,15 @@ class SimpleKotlinGradleIT : KGPBaseTest() { gradleProperties.appendText( """ | - |kotlin.user.home=${tempDir.absolutePathString().normalizePath()} + |kotlin.user.home=${tempDir.resolve("kotlin-cache").absolutePathString().normalizePath()} """.trimMargin() ) build("compileKotlin") { assertTasksExecuted(":compileKotlin") - val baseProjectsDir = tempDir.resolve("projects-1") + val baseProjectsDir = tempDir.resolve("kotlin-cache") assertDirectoryExists(baseProjectsDir) - val projectsDirs = baseProjectsDir.listDirectoryEntries() - assertEquals(1, projectsDirs.size, message = "More then 1 child! Actual content ${projectsDirs.joinToString { it.pathString }}") - assertDirectoryExists(projectsDirs.first().resolve("sessions")) - assertDirectoryExists(projectsDirs.first().resolve("errors")) } } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt index d829d1950d5..b3c4fb3b2c1 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt @@ -121,20 +121,9 @@ fun Path.getSingleFileInDir(relativePath: String): Path { } /** - * Get a path for per-project persistent cache directory from this base persistent cache directory. - */ -fun Path.projectsPersistentCache() = resolve("projects-1") - -/** - * Searches for the specified directory in the projects persistent cache. + * Get Gradle project Kotlin persistent cache. * - * @param directoryName The name of the directory to search for. - * @return The path of the directory if found. - * - * @throws IllegalStateException if the directory does not exist in the projects cache. Usually they are populated after some build. + * **Note**: if a test project is using composite build - [GradleProject] should point to the root project in this composite build. */ -fun Path.inProjectsPersistentCache( - directoryName: String -) = projectsPersistentCache().findInPath(directoryName) - ?: throw IllegalStateException("$directoryName does not exist in the projects cache under ${this.absolutePathString()}") - +val GradleProject.projectPersistentCache: Path + get() = projectPath.resolve(".kotlin") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt index fbb9cd95ad4..6077b8a008b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project -import org.gradle.api.invocation.Gradle import org.gradle.api.logging.Logging import org.gradle.api.provider.Property import org.gradle.api.provider.Provider @@ -14,6 +13,7 @@ import org.gradle.api.services.BuildService import org.gradle.api.services.BuildServiceParameters import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.utils.kotlinSessionsDir +import org.jetbrains.kotlin.gradle.utils.registerClassLoaderScopedBuildService import java.io.File internal abstract class KotlinGradleBuildServices : BuildService, AutoCloseable { @@ -71,14 +71,10 @@ internal abstract class KotlinGradleBuildServices : BuildService = - gradle.sharedServices.registerIfAbsent( - "kotlin-build-service-${KotlinGradleBuildServices::class.java.canonicalName}_${KotlinGradleBuildServices::class.java.classLoader.hashCode()}", - KotlinGradleBuildServices::class.java - ) { service -> - service.parameters.sessionsDir.set(gradle.rootProject.kotlinSessionsDir) + fun registerIfAbsent(project: Project): Provider = + project.gradle.registerClassLoaderScopedBuildService(KotlinGradleBuildServices::class) { + it.parameters.sessionsDir.set(project.kotlinSessionsDir) } - } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 48d54cff418..17ce61fa39b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -82,7 +82,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin { addGradlePluginMetadataAttributes(project) } - val kotlinGradleBuildServices = KotlinGradleBuildServices.registerIfAbsent(project.gradle).get() + val kotlinGradleBuildServices = KotlinGradleBuildServices.registerIfAbsent(project).get() if (!project.isProjectIsolationEnabled) { kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, pluginVersion) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index 10f9366b3ad..2e686026f6a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -543,7 +543,16 @@ internal class PropertiesProvider private constructor(private val project: Proje * * If the property is not set, the plugin will use `/.kotlin` as default. */ - val kotlinUserHomeDir: String? = get(PropertyNames.KOTLIN_USER_HOME_DIR) + val kotlinUserHomeDir: String? + get() = get(PropertyNames.KOTLIN_USER_HOME_DIR) + + /** + * The directory where Kotlin stores project-specific persistent caches. + * + * If the property is not set, the plugin will use `/.kotlin` as default. + */ + val kotlinProjectPersistentDir: String? + get() = get(PropertyNames.KOTLIN_PROJECT_PERSISTENT_DIR) /** * Retrieves a comma-separated list of browsers to use when running karma tests for [target] @@ -636,6 +645,7 @@ internal class PropertiesProvider private constructor(private val project: Proje val KOTLIN_SUPPRESS_BUILD_TOOLS_API_VERSION_CONSISTENCY_CHECKS = property("kotlin.internal.suppress.buildToolsApiVersionConsistencyChecks") val KOTLIN_USER_HOME_DIR = property("kotlin.user.home") + val KOTLIN_PROJECT_PERSISTENT_DIR = property("kotlin.project.persistent.dir") /** * Internal properties: builds get big non-suppressible warning when such properties are used diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataLibraryDirectories.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataLibraryDirectories.kt index bd4278822e3..d6a6b801529 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataLibraryDirectories.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataLibraryDirectories.kt @@ -19,19 +19,16 @@ internal fun ProjectLayout.kotlinTransformedMetadataLibraryDirectoryForBuild(sou buildDirectory.get().asFile.resolve(kotlinTransformedMetadataLibraries).resolve(sourceSetName) internal val Project.kotlinTransformedMetadataLibraryDirectoryForIde: File - get() = compositeBuildRootProject - .kotlinMetadataDir + get() = kotlinMetadataDir(compositeBuildRootProject) .resolve(kotlinTransformedMetadataLibraries) internal fun ProjectLayout.kotlinTransformedCInteropMetadataLibraryDirectoryForBuild(sourceSetName: String): File = buildDirectory.get().asFile.resolve(kotlinTransformedCInteropMetadataLibraries).resolve(sourceSetName) internal val Project.kotlinCInteropLibraryDirectoryForIde: File - get() = compositeBuildRootProject - .kotlinMetadataDir + get() = kotlinMetadataDir(compositeBuildRootProject) .resolve(kotlinCInteropLibraries) internal val Project.kotlinTransformedCInteropMetadataLibraryDirectoryForIde: File - get() = compositeBuildRootProject - .kotlinMetadataDir + get() = kotlinMetadataDir(compositeBuildRootProject) .resolve(kotlinTransformedCInteropMetadataLibraries) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt index 76e87ee6c22..3284fa7a5c7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt @@ -33,7 +33,7 @@ internal abstract class CopyCommonizeCInteropForIdeTask @Inject constructor( commonizeCInteropTask.map { it.allOutputDirectories } @get:OutputDirectory - override val outputDirectory: File = project.kotlinMetadataDir + override val outputDirectory: File = project.kotlinMetadataDir() .resolve("commonizer") .resolve(project.path.removePrefix(":").replace(":", "/")) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/persistentCaches.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/persistentCaches.kt index 2b7857dfa20..e82fcf344e9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/persistentCaches.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/persistentCaches.kt @@ -8,31 +8,25 @@ package org.jetbrains.kotlin.gradle.utils import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import java.io.File -import java.security.MessageDigest - -private const val PROJECTS_CACHE_NAME = "projects" -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" private const val ERRORS_DIR_NAME = "errors" -internal val Project.basePersistentDir +@Suppress("unused") // will be used in the followup KT-58223 issues +internal val Project.userKotlinPersistentDir get() = kotlinPropertiesProvider.kotlinUserHomeDir?.let { File(it) } ?: File(System.getProperty("user.home")).resolve(".kotlin") -internal val Project.kotlinSessionsDir - get() = basePersistentDir.resolve(PROJECTS_CACHE_NAME_FULL).resolve(rootDir.absolutePathMd5Hash()).resolve(SESSIONS_DIR_NAME) +internal fun Project.projectKotlinPersistentDir(compositeRootProject: Project? = null) = + kotlinPropertiesProvider.kotlinProjectPersistentDir?.let { File(it) } + ?: (compositeRootProject ?: this).rootDir.resolve(".kotlin") -internal val Project.kotlinMetadataDir - get() = basePersistentDir.projectSpecificCache(rootDir).resolve(METADATA_DIR_NAME) +internal val Project.kotlinSessionsDir + get() = projectKotlinPersistentDir().resolve(SESSIONS_DIR_NAME) + +internal fun Project.kotlinMetadataDir(compositeBuildRootProject: Project? = null) = + projectKotlinPersistentDir(compositeBuildRootProject).resolve(METADATA_DIR_NAME) internal val Project.kotlinErrorsDir - get() = basePersistentDir.projectSpecificCache(rootDir).resolve(ERRORS_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()) + get() = projectKotlinPersistentDir().resolve(ERRORS_DIR_NAME)