[Gradle] Split global and project persistent caches
Now for project persistent caches plugin will use '<rootDir>/.kotlin' directory. Global persistent cache has stayed in the '<user.home>/.kotlin' directory. ^KT-58223 Fixed
This commit is contained in:
committed by
Space Team
parent
5413973891
commit
070de9cc85
+6
-11
@@ -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() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-14
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -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 ->
|
||||
|
||||
+4
-6
@@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-15
@@ -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")
|
||||
|
||||
+4
-8
@@ -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<KotlinGradleBuildServices.Parameters>, AutoCloseable {
|
||||
@@ -71,14 +71,10 @@ internal abstract class KotlinGradleBuildServices : BuildService<KotlinGradleBui
|
||||
private val INIT_MESSAGE = "Initialized $CLASS_NAME"
|
||||
private val DISPOSE_MESSAGE = "Disposed $CLASS_NAME"
|
||||
|
||||
fun registerIfAbsent(gradle: Gradle): Provider<KotlinGradleBuildServices> =
|
||||
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<KotlinGradleBuildServices> =
|
||||
project.gradle.registerClassLoaderScopedBuildService(KotlinGradleBuildServices::class) {
|
||||
it.parameters.sessionsDir.set(project.kotlinSessionsDir)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
+11
-1
@@ -543,7 +543,16 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
*
|
||||
* If the property is not set, the plugin will use `<user_home>/.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 `<project_dir>/.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
|
||||
|
||||
+3
-6
@@ -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)
|
||||
|
||||
+1
-1
@@ -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(":", "/"))
|
||||
|
||||
|
||||
+11
-17
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user