Convert absolute to relative pluginsClasspath..

..to avoid recompilation on build with portable caches

#KT-62256 Fixed


Merge-request: KT-MR-12377
Merged-by: Aleksei Cherepanov <aleksei.cherepanov@jetbrains.com>
This commit is contained in:
Aleksei.Cherepanov
2023-10-05 10:25:53 +00:00
committed by Space Team
parent 7b3e661776
commit a32c65e4e1
9 changed files with 93 additions and 35 deletions
@@ -7,8 +7,9 @@ package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
abstract class BuildMetaInfo {
abstract class BuildMetaInfo(val converter: RelativeFileToPathConverter?) {
enum class CustomKeys {
LANGUAGE_VERSION_STRING, IS_EAP, METADATA_VERSION_STRING, PLUGIN_CLASSPATHS, API_VERSION_STRING
}
@@ -44,7 +45,7 @@ abstract class BuildMetaInfo {
CustomKeys.LANGUAGE_VERSION_STRING.name ->
return LanguageVersion.fromVersionString(currentValue) != LanguageVersion.fromVersionString(previousValue)
CustomKeys.API_VERSION_STRING.name -> return ApiVersion.parse(currentValue) != ApiVersion.parse(previousValue)
CustomKeys.PLUGIN_CLASSPATHS.name -> return !PluginClasspathsComparator(previousValue, currentValue).equals()
CustomKeys.PLUGIN_CLASSPATHS.name -> return !PluginClasspathComparator(previousValue, currentValue).equals()
}
// check keys that are sensitive for true -> false change
@@ -77,8 +78,8 @@ abstract class BuildMetaInfo {
val apiVersionString = args.apiVersion ?: languageVersionSting
resultMap[CustomKeys.API_VERSION_STRING.name] = apiVersionString
val pluginClasspaths = PluginClasspaths(args.pluginClasspaths).serialize()
resultMap[CustomKeys.PLUGIN_CLASSPATHS.name] = pluginClasspaths
val pluginClasspath = PluginClasspath(args.pluginClasspaths, converter).serialize()
resultMap[CustomKeys.PLUGIN_CLASSPATHS.name] = pluginClasspath
return resultMap
}
@@ -6,10 +6,11 @@
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
class CommonBuildMetaInfo : BuildMetaInfo() {
class CommonBuildMetaInfo(converter: RelativeFileToPathConverter?) : BuildMetaInfo(converter) {
override fun checkIfPlatformSpecificCompilerArgumentWasChanged(key: String, currentValue: String, previousValue: String): Boolean? {
when (key) {
CustomKeys.METADATA_VERSION_STRING.name -> {
@@ -6,10 +6,11 @@
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.utils.JsMetadataVersion
class JsBuildMetaInfo : BuildMetaInfo() {
class JsBuildMetaInfo(converter: RelativeFileToPathConverter?) : BuildMetaInfo(converter) {
override fun checkIfPlatformSpecificCompilerArgumentWasChanged(key: String, currentValue: String, previousValue: String): Boolean? {
when (key) {
CustomKeys.METADATA_VERSION_STRING.name -> {
@@ -17,10 +17,11 @@
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
class JvmBuildMetaInfo : BuildMetaInfo() {
class JvmBuildMetaInfo(converter: RelativeFileToPathConverter?) : BuildMetaInfo(converter) {
override fun checkIfPlatformSpecificCompilerArgumentWasChanged(key: String, currentValue: String, previousValue: String): Boolean? {
when (key) {
CustomKeys.METADATA_VERSION_STRING.name -> {
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
import java.io.File
import java.security.DigestInputStream
import java.security.MessageDigest
internal class PluginClasspath(private val classpath: Array<String>?, val converter: RelativeFileToPathConverter?) {
companion object {
fun deserializeWithHashes(str: String): List<Pair<String, String>> =
str.split(":")
.filter(String::isNotBlank)
.map { Pair(File(it.substringBeforeLast("-")).name, it.substringAfterLast("-")) }
}
fun serialize() = classpath?.mapNotNull { it ->
val jar = File(it).takeIf { it.exists() } ?: return@mapNotNull null
val jarPath = converter?.toPath(jar) ?: jar.absolutePath
val jarHash = jar.sha256()
"$jarPath-$jarHash"
}?.joinToString(":") ?: ""
private fun File.sha256(): String {
val digest = MessageDigest.getInstance("SHA-256")
DigestInputStream(this.inputStream(), digest).use { dis ->
val buffer = ByteArray(8192)
var bytesRead = 0
while (bytesRead != -1) {
bytesRead = dis.read(buffer, 0, buffer.size)
}
}
// Convert to hex:
return digest.digest().joinToString("") {
Integer.toHexString((it.toInt() and 0xff) + 0x100).substring(1)
}
}
}
internal class PluginClasspathComparator(old: String, new: String) {
private val oldPluginClasspath: List<Pair<String, String>> by lazy { PluginClasspath.deserializeWithHashes(old) }
private val newPluginClasspath: List<Pair<String, String>> by lazy { PluginClasspath.deserializeWithHashes(new) }
fun equals() = oldPluginClasspath == newPluginClasspath
}