diff --git a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala index 84e6dff7e..cec856fbe 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala @@ -33,6 +33,9 @@ object IvyGraphMLDependencies extends App { case class ModuleGraph(nodes: Seq[Module], edges: Seq[(Module, Module)]) + def graph(ivyReportFile: String): ModuleGraph = + buildGraph(buildDoc(ivyReportFile)) + def buildGraph(doc: Document): ModuleGraph = { val edges = for { mod <- doc \ "dependencies" \ "module" @@ -46,7 +49,23 @@ object IvyGraphMLDependencies extends App { ModuleGraph(nodes, edges) } - private def asciiGraph(moduleGraph: ModuleGraph): layout.Graph[String] = { + def asciiGraph(graph: ModuleGraph): String = + Layouter.renderGraph(buildAsciiGraph(graph)) + + def asciiTree(graph: ModuleGraph): String = { + val deps = { + val m = new HashMap[String, MSet[Module]] with MultiMap[String, Module] + graph.edges.foreach { case (from, to) => m.addBinding(from.id, to) } + m.toMap.mapValues(_.toSeq.sortBy(_.id)) + } + // there should only be one root node (the project itself) + val roots = graph.nodes.filter(n => !graph.edges.exists(_._2 == n)).sortBy(_.id) + roots.map { root => + Graph.toAscii[Module](root, node => deps.getOrElse(node.id, Seq.empty[Module]), x => x.id + x.error.map(" (error: "+_+")").getOrElse("")) + }.mkString("\n") + } + + private def buildAsciiGraph(moduleGraph: ModuleGraph): layout.Graph[String] = { def renderVertex(module: Module): String = { module.name + "\n" + module.organisation + "\n" + module.version } @@ -55,35 +74,9 @@ object IvyGraphMLDependencies extends App { layout.Graph(vertices, edges) } - def asciiGraph(ivyReportFile: String): String = { - val doc = buildDoc(ivyReportFile) - val graph = buildGraph(doc) - Layouter.renderGraph(asciiGraph(graph)) - } - - def asciiTree(ivyReportFile: String): String = { - val doc = buildDoc(ivyReportFile) - val graph = buildGraph(doc) - import graph._ - val deps = { - val m = new HashMap[String, MSet[Module]] with MultiMap[String, Module] - edges.foreach { case (from, to) => m.addBinding(from.id, to) } - m.toMap.mapValues(_.toSeq.sortBy(_.id)) - } - // there should only be one root node (the project itself) - val roots = nodes.filter(n => !edges.exists(_._2 == n)).sortBy(_.id) - roots.map(root => - Graph.toAscii[Module](root, node => deps.getOrElse(node.id, Seq.empty[Module]), x => x.id + x.error.map(" (error: "+_+")").getOrElse("")) - ).mkString("\n") - } - - def transform(ivyReportFile: String, outputFile: String) { - val doc = buildDoc(ivyReportFile) - val graph = buildGraph(doc) - import graph._ - + def saveAsGraphML(graph: ModuleGraph, outputFile: String) { val nodesXml = - for (n <- nodes) + for (n <- graph.nodes) yield @@ -92,7 +85,7 @@ object IvyGraphMLDependencies extends App { val edgesXml = - for (e <- edges) + for (e <- graph.edges) yield val xml = @@ -123,5 +116,5 @@ object IvyGraphMLDependencies extends App { val file = args.lift(0).filter(f => new File(f).exists).getOrElse(die(usage)) val inputFile = args.lift(1).getOrElse(die(usage)) - transform(file, inputFile) + saveAsGraphML(graph(file), inputFile) } \ No newline at end of file diff --git a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala index 2a56851af..81227c62b 100755 --- a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala @@ -25,6 +25,8 @@ object Plugin extends sbt.Plugin { "The location the graphml file should be generated at") val dependencyGraphML = TaskKey[File]("dependency-graph-ml", "Creates a graphml file containing the dependency-graph for a project") + val moduleGraph = TaskKey[IvyGraphMLDependencies.ModuleGraph]("module-graph", + "The dependency graph for a project") val asciiGraph = TaskKey[String]("dependency-graph-string", "Returns a string containing the ascii representation of the dependency graph for a project") val dependencyGraph = TaskKey[Unit]("dependency-graph", @@ -57,35 +59,30 @@ object Plugin extends sbt.Plugin { def ivyReportForConfig(config: Configuration) = inConfig(config)(seq( ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn(ignoreMissingUpdate), - asciiGraph <<= asciiGraphTask, - dependencyGraph <<= printAsciiGraphTask, - asciiTree <<= asciiTreeTask, - dependencyTree <<= printAsciiTreeTask, + moduleGraph <<= ivyReport map (absoluteReportPath.andThen(IvyGraphMLDependencies.graph)), + asciiGraph <<= moduleGraph map IvyGraphMLDependencies.asciiGraph, + dependencyGraph <<= print(asciiGraph), + asciiTree <<= moduleGraph map IvyGraphMLDependencies.asciiTree, + dependencyTree <<= print(asciiTree), dependencyGraphMLFile <<= target / "dependencies-%s.graphml".format(config.toString), dependencyGraphML <<= dependencyGraphMLTask, Compat.ignoreMissingUpdateT )) - def asciiGraphTask = (ivyReport) map { report => - IvyGraphMLDependencies.asciiGraph(report.getAbsolutePath) - } - def printAsciiGraphTask = (streams, asciiGraph) map (_.log.info(_)) def dependencyGraphMLTask = - (ivyReport, dependencyGraphMLFile, streams) map { (report, resultFile, streams) => - IvyGraphMLDependencies.transform(report.getAbsolutePath, resultFile.getAbsolutePath) + (moduleGraph, dependencyGraphMLFile, streams) map { (graph, resultFile, streams) => + IvyGraphMLDependencies.saveAsGraphML(graph, resultFile.getAbsolutePath) streams.log.info("Wrote dependency graph to '%s'" format resultFile) resultFile } - def asciiTreeTask = (ivyReport) map { report => - IvyGraphMLDependencies.asciiTree(report.getAbsolutePath) - } + def absoluteReportPath = (file: File) => file.getAbsolutePath - def printAsciiTreeTask = - (streams, asciiTree) map (_.log.info(_)) + def print(key: TaskKey[String]) = + (streams, key) map (_.log.info(_)) def crossName(ivyModule: IvySbt#Module) = ivyModule.moduleSettings match {