@@ -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