diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala index 2abdd15..44648cc 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphKeys.scala @@ -65,6 +65,9 @@ trait DependencyGraphKeys { val moduleGraph = TaskKey[ModuleGraph]( "module-graph", "The dependency graph for a project") + val moduleTree = TaskKey[ModuleTree]( + "module-tree", + "The dependency tree for a project") val moduleGraphIvyReport = TaskKey[ModuleGraph]( "module-graph-ivy-report", "The dependency graph for a project as generated from an Ivy Report XML") diff --git a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala index 2ea3b3c..fa40d5e 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/DependencyGraphSettings.scala @@ -78,6 +78,8 @@ object DependencyGraphSettings { }, moduleGraphStore := (moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph).value, + moduleTree := ModuleTree(DependencyGraphKeys.moduleGraph.value), + // browse dependencyBrowseGraphTarget := { target.value / "browse-dependency-graph" }, dependencyBrowseGraphHTML := browseGraphHTMLTask.value, diff --git a/src/main/scala/net/virtualvoid/sbt/graph/model.scala b/src/main/scala/net/virtualvoid/sbt/graph/model.scala index cbfc432..be171c2 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/model.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/model.scala @@ -21,6 +21,7 @@ import java.io.File import sbinary.Format import scala.collection.mutable.{ HashMap, MultiMap, Set } +import scala.collection.immutable case class ModuleId( organisation: String, @@ -77,3 +78,22 @@ object ModuleGraphProtocol extends ModuleGraphProtocolCompat { implicit val ModuleFormat: Format[Module] = asProduct6(Module)(Module.unapply(_).get) implicit val ModuleGraphFormat: Format[ModuleGraph] = asProduct2(ModuleGraph.apply _)(ModuleGraph.unapply(_).get) } + +case class ModuleTreeNode(node: Module, children: immutable.Seq[ModuleTreeNode]) + +object ModuleTreeNode { + def apply(module: Module, deps: Map[ModuleId, Seq[Module]]): ModuleTreeNode = { + val children = deps.getOrElse(module.id, immutable.Seq.empty[Module]).map(m ⇒ apply(m, deps)).toList + ModuleTreeNode(module, children) + } +} + +case class ModuleTree(roots: immutable.Seq[ModuleTreeNode]) + +object ModuleTree { + def apply(graph: ModuleGraph): ModuleTree = { + val deps = graph.dependencyMap + ModuleTree(graph.roots.toList.map { root ⇒ ModuleTreeNode(root, deps) }) + } + +}