diff --git a/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt b/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt index 0982af66..1b3aac9e 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt @@ -93,6 +93,10 @@ public class DynamicGraphExecutor(val graph: DynamicGraph, } } executor.shutdown() + if (graph.freeNodes.size == 0 && graph.nodesReady.size > 0) { + throw KobaltException("Couldn't find any free nodes but a few nodes still haven't run, there is " + + "a cycle in the dependencies.\n Nodes left: " + graph.dump(graph.nodesReady)) + } return if (lastResult.success) 0 else 1 } } @@ -101,7 +105,7 @@ public class DynamicGraphExecutor(val graph: DynamicGraph, * Representation of the graph of methods. */ public class DynamicGraph { - private val nodesReady = linkedSetOf() + val nodesReady = linkedSetOf() private val nodesRunning = linkedSetOf() private val nodesFinished = linkedSetOf() private val nodesInError = linkedSetOf() @@ -258,21 +262,23 @@ public class DynamicGraph { val nodes = hashSetOf() - fun dump() : String { + fun dump(nodes: Collection) : String { val result = StringBuffer() val free = arrayListOf() - nodesReady.forEach { node -> + nodes.forEach { node -> val d = dependedUpon.get(node) if (d == null || d.isEmpty()) { free.add(node) } } - result.append("Free: $free").append("\n Dependencies:\n") - dependedUpon.keySet().forEach { + result.append("Free nodes: $free").append("\n Dependent nodes:\n") + nodes.forEach { result.append(" $it -> ${dependedUpon.get(it)}\n") } return result.toString() } + + fun dump() = dump(nodesReady) }