[Gradle, JS] Fix case with multiple artifacts in module
This commit is contained in:
@@ -0,0 +1 @@
|
||||
kotlin.incremental.js.ir=false
|
||||
+62
-11
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
@@ -42,6 +43,9 @@ import org.jetbrains.kotlin.gradle.utils.getAllDependencies
|
||||
import org.jetbrains.kotlin.gradle.utils.getCacheDirectory
|
||||
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
||||
import org.jetbrains.kotlin.library.uniqueName
|
||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||
import java.io.File
|
||||
@@ -260,10 +264,12 @@ internal class CacheBuilder(
|
||||
.filter { it !in visitedDependenciesForCache }
|
||||
.forEach { dependencyForCache ->
|
||||
visitedDependenciesForCache.add(dependencyForCache)
|
||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependencyForCache)
|
||||
if (cacheDirectory.exists()) {
|
||||
allCacheDirectories.add(cacheDirectory)
|
||||
}
|
||||
dependencyForCache.moduleArtifacts
|
||||
.map {
|
||||
getCacheDirectory(rootCacheDirectory, dependencyForCache, it, { libraryFilter(it.file) })
|
||||
}
|
||||
.filter { it.exists() }
|
||||
.forEach { allCacheDirectories.add(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,20 +307,65 @@ internal class CacheBuilder(
|
||||
|
||||
val dependenciesCacheDirectories = getDependenciesCacheDirectories(
|
||||
rootCacheDirectory,
|
||||
dependency
|
||||
dependency,
|
||||
libraryFilter = { libraryFilter(it.file) }
|
||||
) ?: return
|
||||
|
||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependency)
|
||||
cacheDirectory.mkdirs()
|
||||
val nameMap: MutableMap<String, ResolvedArtifact> = mutableMapOf()
|
||||
val depsMap: MutableMap<ResolvedArtifact, MutableList<ResolvedArtifact>> = mutableMapOf()
|
||||
val cacheMap: MutableMap<ResolvedArtifact, File> = mutableMapOf()
|
||||
var newOrderArtifactsToAddToCache = mutableListOf<ResolvedArtifact>()
|
||||
|
||||
for (library in artifactsToAddToCache) {
|
||||
if (artifactsToAddToCache.size > 1) {
|
||||
artifactsToAddToCache.forEach {
|
||||
val klib = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File(it.file.absolutePath))
|
||||
nameMap[klib.uniqueName] = it
|
||||
}
|
||||
artifactsToAddToCache.forEach { artifact ->
|
||||
val klib = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File(artifact.file.absolutePath))
|
||||
klib.unresolvedDependencies
|
||||
.forEach { depLib ->
|
||||
val depName = depLib.path.substringAfterLast("/")
|
||||
nameMap[depName]?.let {
|
||||
val depsSet = depsMap.getOrPut(artifact) {
|
||||
mutableListOf()
|
||||
}
|
||||
depsSet.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
fun traverseDependency(library: ResolvedArtifact) {
|
||||
depsMap[library]?.let {
|
||||
it.forEach {
|
||||
traverseDependency(it)
|
||||
}
|
||||
}
|
||||
if (library !in newOrderArtifactsToAddToCache) {
|
||||
newOrderArtifactsToAddToCache.add(library)
|
||||
}
|
||||
}
|
||||
depsMap.forEach { key, deps ->
|
||||
traverseDependency(key)
|
||||
}
|
||||
} else {
|
||||
newOrderArtifactsToAddToCache = artifactsToAddToCache.toMutableList()
|
||||
}
|
||||
|
||||
for (library in newOrderArtifactsToAddToCache) {
|
||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependency, library, { libraryFilter(it.file) })
|
||||
cacheDirectory.mkdirs()
|
||||
cacheMap[library] = cacheDirectory
|
||||
val additionalDependencies = depsMap[library] ?: emptyList()
|
||||
val additionalCacheDirectories = if (additionalDependencies.isNotEmpty()) {
|
||||
additionalDependencies.map { cacheMap.getValue(it) }
|
||||
} else emptyList()
|
||||
runCompiler(
|
||||
library.file,
|
||||
getAllDependencies(dependency)
|
||||
.flatMap { it.moduleArtifacts }
|
||||
(getAllDependencies(dependency)
|
||||
.flatMap { it.moduleArtifacts } + additionalDependencies)
|
||||
.map { it.file },
|
||||
cacheDirectory,
|
||||
dependenciesCacheDirectories
|
||||
dependenciesCacheDirectories + additionalCacheDirectories
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+38
-10
@@ -5,19 +5,42 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
||||
import org.jetbrains.kotlin.library.uniqueName
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
|
||||
fun getCacheDirectory(
|
||||
rootCacheDirectory: File,
|
||||
dependency: ResolvedDependency
|
||||
dependency: ResolvedDependency,
|
||||
artifact: ResolvedArtifact? = null,
|
||||
libraryFilter: (ResolvedArtifact) -> Boolean = { it.file.absolutePath.endsWith(".klib") }
|
||||
): File {
|
||||
val moduleCacheDirectory = File(rootCacheDirectory, dependency.moduleName)
|
||||
val versionCacheDirectory = File(moduleCacheDirectory, dependency.moduleVersion)
|
||||
return File(versionCacheDirectory, computeDependenciesHash(dependency))
|
||||
val uniqueName = artifact
|
||||
?.let {
|
||||
if (libraryFilter(it))
|
||||
it.file
|
||||
else
|
||||
null
|
||||
}
|
||||
?.let {
|
||||
resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File(it.absolutePath))
|
||||
}
|
||||
?.uniqueName
|
||||
|
||||
val cacheDirectory = if (uniqueName != null) {
|
||||
val digest = MessageDigest.getInstance("SHA-256")
|
||||
val hash = digest.digest(uniqueName.toByteArray(StandardCharsets.UTF_8)).toHexString()
|
||||
versionCacheDirectory.resolve(hash)
|
||||
} else versionCacheDirectory
|
||||
|
||||
return File(cacheDirectory, computeDependenciesHash(dependency))
|
||||
}
|
||||
|
||||
private fun ByteArray.toHexString() = joinToString("") { (0xFF and it.toInt()).toString(16).padStart(2, '0') }
|
||||
@@ -36,17 +59,22 @@ private fun computeDependenciesHash(dependency: ResolvedDependency): String {
|
||||
|
||||
fun getDependenciesCacheDirectories(
|
||||
rootCacheDirectory: File,
|
||||
dependency: ResolvedDependency
|
||||
dependency: ResolvedDependency,
|
||||
libraryFilter: (ResolvedArtifact) -> Boolean = { it.file.absolutePath.endsWith(".klib") }
|
||||
): List<File>? {
|
||||
return getAllDependencies(dependency)
|
||||
.map { childDependency ->
|
||||
val hasKlibs = childDependency.moduleArtifacts.any { it.file.absolutePath.endsWith(".klib") }
|
||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, childDependency)
|
||||
// We can only compile klib to cache if all of its dependencies are also cached.
|
||||
if (hasKlibs && !cacheDirectory.exists())
|
||||
return null
|
||||
cacheDirectory
|
||||
.flatMap { childDependency ->
|
||||
childDependency.moduleArtifacts.map {
|
||||
if (libraryFilter(it)) {
|
||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, childDependency, it, libraryFilter)
|
||||
if (!cacheDirectory.exists()) return null
|
||||
cacheDirectory
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
.filterNotNull()
|
||||
.filter { it.exists() }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user