[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
|
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||||
|
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.DirectoryProperty
|
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.getCacheDirectory
|
||||||
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
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.BooleanMetrics
|
||||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -260,10 +264,12 @@ internal class CacheBuilder(
|
|||||||
.filter { it !in visitedDependenciesForCache }
|
.filter { it !in visitedDependenciesForCache }
|
||||||
.forEach { dependencyForCache ->
|
.forEach { dependencyForCache ->
|
||||||
visitedDependenciesForCache.add(dependencyForCache)
|
visitedDependenciesForCache.add(dependencyForCache)
|
||||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependencyForCache)
|
dependencyForCache.moduleArtifacts
|
||||||
if (cacheDirectory.exists()) {
|
.map {
|
||||||
allCacheDirectories.add(cacheDirectory)
|
getCacheDirectory(rootCacheDirectory, dependencyForCache, it, { libraryFilter(it.file) })
|
||||||
}
|
}
|
||||||
|
.filter { it.exists() }
|
||||||
|
.forEach { allCacheDirectories.add(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,20 +307,65 @@ internal class CacheBuilder(
|
|||||||
|
|
||||||
val dependenciesCacheDirectories = getDependenciesCacheDirectories(
|
val dependenciesCacheDirectories = getDependenciesCacheDirectories(
|
||||||
rootCacheDirectory,
|
rootCacheDirectory,
|
||||||
dependency
|
dependency,
|
||||||
|
libraryFilter = { libraryFilter(it.file) }
|
||||||
) ?: return
|
) ?: return
|
||||||
|
|
||||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependency)
|
val nameMap: MutableMap<String, ResolvedArtifact> = mutableMapOf()
|
||||||
cacheDirectory.mkdirs()
|
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(
|
runCompiler(
|
||||||
library.file,
|
library.file,
|
||||||
getAllDependencies(dependency)
|
(getAllDependencies(dependency)
|
||||||
.flatMap { it.moduleArtifacts }
|
.flatMap { it.moduleArtifacts } + additionalDependencies)
|
||||||
.map { it.file },
|
.map { it.file },
|
||||||
cacheDirectory,
|
cacheDirectory,
|
||||||
dependenciesCacheDirectories
|
dependenciesCacheDirectories + additionalCacheDirectories
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-10
@@ -5,19 +5,42 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.utils
|
package org.jetbrains.kotlin.gradle.utils
|
||||||
|
|
||||||
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
|
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
||||||
|
import org.jetbrains.kotlin.library.uniqueName
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
fun getCacheDirectory(
|
fun getCacheDirectory(
|
||||||
rootCacheDirectory: File,
|
rootCacheDirectory: File,
|
||||||
dependency: ResolvedDependency
|
dependency: ResolvedDependency,
|
||||||
|
artifact: ResolvedArtifact? = null,
|
||||||
|
libraryFilter: (ResolvedArtifact) -> Boolean = { it.file.absolutePath.endsWith(".klib") }
|
||||||
): File {
|
): File {
|
||||||
val moduleCacheDirectory = File(rootCacheDirectory, dependency.moduleName)
|
val moduleCacheDirectory = File(rootCacheDirectory, dependency.moduleName)
|
||||||
val versionCacheDirectory = File(moduleCacheDirectory, dependency.moduleVersion)
|
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') }
|
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(
|
fun getDependenciesCacheDirectories(
|
||||||
rootCacheDirectory: File,
|
rootCacheDirectory: File,
|
||||||
dependency: ResolvedDependency
|
dependency: ResolvedDependency,
|
||||||
|
libraryFilter: (ResolvedArtifact) -> Boolean = { it.file.absolutePath.endsWith(".klib") }
|
||||||
): List<File>? {
|
): List<File>? {
|
||||||
return getAllDependencies(dependency)
|
return getAllDependencies(dependency)
|
||||||
.map { childDependency ->
|
.flatMap { childDependency ->
|
||||||
val hasKlibs = childDependency.moduleArtifacts.any { it.file.absolutePath.endsWith(".klib") }
|
childDependency.moduleArtifacts.map {
|
||||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, childDependency)
|
if (libraryFilter(it)) {
|
||||||
// We can only compile klib to cache if all of its dependencies are also cached.
|
val cacheDirectory = getCacheDirectory(rootCacheDirectory, childDependency, it, libraryFilter)
|
||||||
if (hasKlibs && !cacheDirectory.exists())
|
if (!cacheDirectory.exists()) return null
|
||||||
return null
|
cacheDirectory
|
||||||
cacheDirectory
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.filterNotNull()
|
||||||
.filter { it.exists() }
|
.filter { it.exists() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user