[Gradle, JS] Fix yarn.lock resolution in case of duplicated dependencies
^KT-42222 fixed ^KT-40986 fixed ^KT-39838 fixed
This commit is contained in:
+10
-6
@@ -19,12 +19,11 @@ fun versionToNpmRanges(version: String): Set<NpmRange> {
|
|||||||
.visit(parser.rangeSet())!!
|
.visit(parser.rangeSet())!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildNpmVersion(
|
fun includedRange(
|
||||||
includedVersions: List<String>,
|
includedVersions: List<String>,
|
||||||
excludedVersions: List<String>,
|
|
||||||
includedWithCaret: Boolean = false
|
includedWithCaret: Boolean = false
|
||||||
): String {
|
): NpmRange =
|
||||||
val includedRange: NpmRange? = try {
|
try {
|
||||||
includedVersions
|
includedVersions
|
||||||
.flatMap { versionToNpmRanges(it) }
|
.flatMap { versionToNpmRanges(it) }
|
||||||
.map { if (includedWithCaret) it.caretizeSingleVersion() else it }
|
.map { if (includedWithCaret) it.caretizeSingleVersion() else it }
|
||||||
@@ -33,13 +32,18 @@ fun buildNpmVersion(
|
|||||||
requireNotNull(intersection) {
|
requireNotNull(intersection) {
|
||||||
"Included versions have no intersection $includedVersions"
|
"Included versions have no intersection $includedVersions"
|
||||||
}
|
}
|
||||||
intersection!!
|
intersection
|
||||||
}
|
}
|
||||||
} catch (e: UnsupportedOperationException) {
|
} catch (e: UnsupportedOperationException) {
|
||||||
throw InvalidUserDataException("No ranges for included versions $includedVersions")
|
throw InvalidUserDataException("No ranges for included versions $includedVersions")
|
||||||
}
|
}
|
||||||
|
|
||||||
includedRange!!
|
fun buildNpmVersion(
|
||||||
|
includedVersions: List<String>,
|
||||||
|
excludedVersions: List<String>,
|
||||||
|
includedWithCaret: Boolean = false
|
||||||
|
): String {
|
||||||
|
val includedRange: NpmRange = includedRange(includedVersions, includedWithCaret)
|
||||||
|
|
||||||
if (excludedVersions.isEmpty()) return includedRange.toString()
|
if (excludedVersions.isEmpty()) return includedRange.toString()
|
||||||
|
|
||||||
|
|||||||
+14
-6
@@ -9,6 +9,7 @@ import com.google.gson.ExclusionStrategy
|
|||||||
import com.google.gson.FieldAttributes
|
import com.google.gson.FieldAttributes
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
|
import org.gradle.api.GradleException
|
||||||
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ fun packageJson(
|
|||||||
|
|
||||||
npmDependencies.forEach {
|
npmDependencies.forEach {
|
||||||
val module = it.key
|
val module = it.key
|
||||||
dependencies[it.key] = chooseVersion(dependencies[module], it.version)
|
dependencies[module] = chooseVersion(module, dependencies[module], it.version)
|
||||||
}
|
}
|
||||||
|
|
||||||
npmDependencies.forEach {
|
npmDependencies.forEach {
|
||||||
@@ -146,12 +147,19 @@ fun packageJson(
|
|||||||
return packageJson
|
return packageJson
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: real versions conflict resolution
|
private fun chooseVersion(
|
||||||
private fun chooseVersion(oldVersion: String?, newVersion: String): String {
|
module: String,
|
||||||
// https://yarnpkg.com/lang/en/docs/dependency-versions/#toc-x-ranges
|
oldVersion: String?,
|
||||||
if (oldVersion == "*") {
|
newVersion: String
|
||||||
|
): String {
|
||||||
|
if (oldVersion == null) {
|
||||||
return newVersion
|
return newVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldVersion ?: newVersion
|
return (includedRange(listOf(oldVersion)) intersect includedRange(listOf(newVersion)))?.toString()
|
||||||
|
?: throw GradleException(
|
||||||
|
"""
|
||||||
|
There is already declared version of '$module' with version '$oldVersion' which does not intersects with another declared version '${newVersion}'
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
+20
-12
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||||
|
|
||||||
import com.github.gundy.semver4j.SemVer
|
import org.gradle.api.GradleException
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.FILE_VERSION_PREFIX
|
import org.jetbrains.kotlin.gradle.targets.js.npm.FILE_VERSION_PREFIX
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.includedRange
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.intersect
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class YarnEntryRegistry(private val lockFile: File) {
|
internal class YarnEntryRegistry(private val lockFile: File) {
|
||||||
@@ -16,21 +18,27 @@ internal class YarnEntryRegistry(private val lockFile: File) {
|
|||||||
|
|
||||||
fun find(packageKey: String, version: String): YarnLock.Entry {
|
fun find(packageKey: String, version: String): YarnLock.Entry {
|
||||||
val key = dependencyKey(packageKey, version)
|
val key = dependencyKey(packageKey, version)
|
||||||
var entry = entryMap[key]
|
val entry = entryMap[key]
|
||||||
|
|
||||||
if (entry == null && version == "*") {
|
if (entry != null) {
|
||||||
val searchKey = dependencyKey(packageKey, "")
|
return entry
|
||||||
entry = entryMap.entries
|
}
|
||||||
.filter { it.key.startsWith(searchKey) }
|
|
||||||
.firstOrNull {
|
val versionRange = includedRange(listOf(version))
|
||||||
SemVer.satisfies(it.key.removePrefix(searchKey), "*")
|
|
||||||
|
entryMap.entries
|
||||||
|
.firstOrNull { (_, entry) ->
|
||||||
|
if (entry.version == null) {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
(versionRange intersect includedRange(listOf(entry.version))) != null
|
||||||
}
|
}
|
||||||
?.value
|
}
|
||||||
}
|
?.let { return it.value }
|
||||||
|
|
||||||
return checkNotNull(entry) {
|
throw GradleException(
|
||||||
"Cannot find $key in yarn.lock"
|
"Cannot find $key in yarn.lock"
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val YarnLock.Entry.dependencyKey: String
|
private val YarnLock.Entry.dependencyKey: String
|
||||||
|
|||||||
Reference in New Issue
Block a user