diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt index 3b88af6399a..06648bbf813 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt @@ -31,6 +31,7 @@ data class NpmDependency( override fun getGroup(): String? = org + internal var parent: NpmDependency? = null internal val dependencies = mutableSetOf() override fun resolve(transitive: Boolean): MutableSet { @@ -64,7 +65,9 @@ data class NpmDependency( } override fun resolve(): MutableSet { - val npmPackage = resolveProject() ?: return mutableSetOf() + val npmPackage = parent?.resolveProject() + ?: resolveProject() + ?: return mutableSetOf() return mutableSetOf(npmPackage.npmProject.resolve(key)!!) } @@ -86,7 +89,8 @@ data class NpmDependency( return when (result) { null -> null is AlreadyInProgress -> null - is AlreadyResolved -> findIn(result.resolution) ?: error("Project hierarchy is already resolved in NPM without $this") + is AlreadyResolved -> findIn(result.resolution) + ?: error("Project hierarchy is already resolved in NPM without $this") is ResolvedNow -> findIn(result.resolution) ?: error("Cannot find $this after NPM project resolve") } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt index df128bec3bf..8b5f5ce4b65 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt @@ -42,29 +42,35 @@ abstract class YarnBasics : NpmApi { val yarnLock = nodeWorkDir.resolve("yarn.lock") if (yarnLock.isFile) { val byKey = YarnLock.parse(yarnLock).entries.associateBy { it.key } - val visited = mutableSetOf() + val visited = mutableMapOf() fun resolveRecursively(src: NpmDependency): NpmDependency { - if (src in visited) return src - visited.add(src) + val copy = visited[src] + if (copy != null) { + src.dependencies.addAll(copy.dependencies) + return src + } + visited[src] = src val key = YarnLock.key(src.key, src.version) val deps = byKey[key] if (deps != null) { src.dependencies.addAll(deps.dependencies.map { dep -> val scopedName = dep.scopedName - - resolveRecursively( - NpmDependency( - src.project, - scopedName.scope, - scopedName.name, - dep.version ?: "*" - ) + val child = NpmDependency( + src.project, + scopedName.scope, + scopedName.name, + dep.version ?: "*" ) + child.parent = src + + resolveRecursively(child) + + child }) } else { - // todo: [WARN] cannot find $key in yarn.lock + error("Cannot find $key in yarn.lock") } return src