Skip to content

Commit 3b2f357

Browse files
committed
Improve cycle reporting
1 parent b464e8f commit 3b2f357

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

buildSrc/src/main/kotlin/io/micronaut/build/ProjectGraphBuilder.kt

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ abstract class ProjectGraphBuilder : DefaultTask() {
9898
warnings.add("[WARNING] The following modules are not included in the platform: $missingPlatformDependencies")
9999
}
100100
val cycles = mutableSetOf<Pair<String, String>>()
101-
val projects = sortByDependents(projectToMetadata, cycles)
102-
cycles.forEach {
103-
val warning = "[WARNING] A cycle exists between ${it.first} and ${it.second}"
101+
val cyclePaths = mutableSetOf<String>()
102+
val projects = sortByDependents(projectToMetadata, cycles, cyclePaths)
103+
cyclePaths.forEach {
104+
val warning = "[WARNING] A cycle was detected: $it"
104105
System.err.println(warning)
105106
warnings.add(warning)
106107
}
@@ -240,7 +241,7 @@ abstract class ProjectGraphBuilder : DefaultTask() {
240241
}
241242
}
242243

243-
private fun sortByDependents(projectToMetadata: Map<String, ModuleMetadata>, cycles: MutableSet<Pair<String, String>>): List<String> {
244+
private fun sortByDependents(projectToMetadata: Map<String, ModuleMetadata>, cycles: MutableSet<Pair<String, String>>, cyclePaths: MutableSet<String>): List<String> {
244245
val remaining = projectToMetadata.keys.toTypedArray()
245246
var i = 0
246247
while (i < remaining.size) {
@@ -255,6 +256,9 @@ abstract class ProjectGraphBuilder : DefaultTask() {
255256
if (t2.contains(p1)) {
256257
if (!cycles.contains(p2 to p1)) {
257258
cycles.add(p1 to p2)
259+
p1.findPathTo(projectToMetadata, p2)?.also {
260+
cyclePaths.add(it)
261+
}
258262
}
259263
j++
260264
} else {
@@ -379,6 +383,31 @@ abstract class ProjectGraphBuilder : DefaultTask() {
379383
return transitive
380384
}
381385

386+
fun String.findPathTo(deps: Map<String, ModuleMetadata>, target: String): String? {
387+
val path = findPathTo(deps, target, this, mutableSetOf())
388+
if (path != null) {
389+
return "$path -> $this"
390+
}
391+
return null
392+
}
393+
394+
fun String.findPathTo(deps: Map<String, ModuleMetadata>, target: String, currentPath: String, visited: MutableSet<String>): String? {
395+
if (visited.add(this)) {
396+
val dependencies = deps[this]?.dependencies ?: emptySet()
397+
dependencies.forEach {
398+
val path = "$currentPath -> $it"
399+
if (it == target) {
400+
return path
401+
}
402+
val candidate = it.findPathTo(deps, target, path, visited)
403+
if (candidate != null) {
404+
return candidate
405+
}
406+
}
407+
}
408+
return null;
409+
}
410+
382411
private fun String.transitiveDeps(deps: Map<String, ModuleMetadata>, visited: MutableSet<String>): Unit {
383412
val dependencies = deps[this]?.dependencies ?: emptySet()
384413
if (visited.add(this)) {

0 commit comments

Comments
 (0)