mirror of https://github.com/sbt/sbt.git
Merge commit 'pull/25'
Conflicts: src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala
This commit is contained in:
commit
f28b009b02
|
|
@ -44,6 +44,8 @@ Tasks & Settings
|
|||
* `dependency-graph`: Shows an ASCII graph of the project's dependencies on the sbt console
|
||||
* `dependency-graph-ml`: Generates a .graphml file with the project's dependencies to `target/dependencies-<config>.graphml`.
|
||||
Use e.g. [yEd](http://www.yworks.com/en/products_yed_about.html) to format the graph to your needs.
|
||||
* `dependency-dot`: Generates a .dot file with the project's dependencies to `target/dependencies-<config>.dot`.
|
||||
Use [graphviz](http://www.graphviz.org/) to render it to your preferred graphic format.
|
||||
* `dependency-tree`: Shows an ASCII tree representation of the project's dependencies
|
||||
* `what-depends-on <organization> <module> <revision>`: Find out what depends on an artifact. Shows a reverse dependency
|
||||
tree for the selected module.
|
||||
|
|
@ -52,6 +54,10 @@ Tasks & Settings
|
|||
If `true`, instead of showing the dependency `"[S]"` is appended to the artifact name. Set to `false` if
|
||||
you want the scala-library dependency to appear in the output. (default: true)
|
||||
* `dependency-graph-ml-file`: a setting which allows configuring the output path of `dependency-graph-ml`.
|
||||
* `dependency-dot-file`: a setting which allows configuring the output path of `dependency-dot`.
|
||||
* `dependency-dot-header`: a setting to customize the header of the dot file (e.g. to set your preferred node shapes).
|
||||
* `dependency-dot-nodes-label`: defines the formation of a node label
|
||||
(default set to `[organisation]<BR/><B>[name]</B><BR/>[version]`)
|
||||
* `ivy-report`: let's ivy generate the resolution report for you project. Use
|
||||
`show ivy-report` for the filename of the generated report
|
||||
|
||||
|
|
@ -95,4 +101,4 @@ Copyright (c) 2011, 2012 Johannes Rudolph
|
|||
|
||||
Published under the [Apache License 2.0](http://en.wikipedia.org/wiki/Apache_license).
|
||||
|
||||
[example project]: https://gist.github.com/3106492
|
||||
[example project]: https://gist.github.com/3106492
|
||||
|
|
|
|||
|
|
@ -195,6 +195,29 @@ object IvyGraphMLDependencies extends App {
|
|||
|
||||
XML.save(outputFile, xml)
|
||||
}
|
||||
def saveAsDot(graph: ModuleGraph,
|
||||
dotHead: String,
|
||||
nodeFormation: (String, String, String) => String,
|
||||
outputFile: File): File = {
|
||||
val nodes = {
|
||||
for (n <- graph.nodes)
|
||||
yield
|
||||
""" "%s"[label=%s]""".format(n.id.idString,
|
||||
nodeFormation(n.id.organisation, n.id.name, n.id.version))
|
||||
}.mkString("\n")
|
||||
|
||||
val edges = {
|
||||
for ( e <- graph.edges)
|
||||
yield
|
||||
""" "%s" -> "%s"""".format(e._1.idString, e._2.idString)
|
||||
}.mkString("\n")
|
||||
|
||||
val dot = "%s\n%s\n%s\n}".format(dotHead, nodes, edges)
|
||||
|
||||
sbt.IO.write(outputFile, dot)
|
||||
outputFile
|
||||
}
|
||||
|
||||
def moduleIdFromElement(element: Node, version: String): ModuleId =
|
||||
ModuleId(element.attribute("organisation").get.text, element.attribute("name").get.text, version)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ 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 dependencyDotFile = SettingKey[File]("dependency-dot-file",
|
||||
"The location the dot file should be generated at")
|
||||
val dependencyDotNodeLabel = SettingKey[(String,String,String) => String]("dependency-dot-node-label",
|
||||
"Returns a formated string of a dependency. Takes organisation, name and version as parameters")
|
||||
val dependencyDotHeader = SettingKey[String]("dependency-dot-header",
|
||||
"The header of the dot file. (e.g. to set your preferred node shapes)")
|
||||
val dependencyDot = TaskKey[File]("dependency-dot",
|
||||
"Creates a dot file containing the dpendency-graph for a project")
|
||||
val moduleGraph = TaskKey[IvyGraphMLDependencies.ModuleGraph]("module-graph",
|
||||
"The dependency graph for a project")
|
||||
val asciiGraph = TaskKey[String]("dependency-graph-string",
|
||||
|
|
@ -104,6 +112,19 @@ object Plugin extends sbt.Plugin {
|
|||
dependencyTree <<= print(asciiTree),
|
||||
dependencyGraphMLFile <<= target / "dependencies-%s.graphml".format(config.toString),
|
||||
dependencyGraphML <<= dependencyGraphMLTask,
|
||||
dependencyDotFile <<= target / "dependencies-%s.dot".format(config.toString),
|
||||
dependencyDot <<= dependencyDotTask,
|
||||
dependencyDotHeader := """digraph "dependency-graph" {
|
||||
| graph[rankdir="LR"]
|
||||
| node [
|
||||
| shape="record"
|
||||
| ]
|
||||
| edge [
|
||||
| arrowtail="none"
|
||||
| ]""".stripMargin,
|
||||
dependencyDotNodeLabel := { (organisation: String, name: String, version: String) =>
|
||||
"""<%s<BR/><B>%s</B><BR/>%s>""".format(organisation, name, version)
|
||||
},
|
||||
whatDependsOn <<= InputTask(artifactIdParser) { module =>
|
||||
(module, streams, moduleGraph) map { (module, streams, graph) =>
|
||||
streams.log.info(IvyGraphMLDependencies.asciiTree(IvyGraphMLDependencies.reverseGraphStartingAt(graph, module)))
|
||||
|
|
@ -121,7 +142,14 @@ object Plugin extends sbt.Plugin {
|
|||
streams.log.info("Wrote dependency graph to '%s'" format resultFile)
|
||||
resultFile
|
||||
}
|
||||
def dependencyDotTask =
|
||||
(moduleGraph, dependencyDotHeader, dependencyDotNodeLabel, dependencyDotFile, streams).map {
|
||||
(graph, dotHead, nodeLabel, outFile, streams) =>
|
||||
|
||||
val resultFile = IvyGraphMLDependencies.saveAsDot(graph, dotHead, nodeLabel, outFile)
|
||||
streams.log.info("Wrote dependency graph to '%s'" format resultFile)
|
||||
resultFile
|
||||
}
|
||||
def absoluteReportPath = (file: File) => file.getAbsolutePath
|
||||
|
||||
def print(key: TaskKey[String]) =
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ scalaVersion := "2.9.2"
|
|||
|
||||
libraryDependencies ++= Seq(
|
||||
"org.slf4j" % "slf4j-api" % "1.7.2",
|
||||
"ch.qos.logback" % "logback-classic" % "1.0.7",
|
||||
"com.typesafe.akka" % "akka-actor" % "2.0.3")
|
||||
"ch.qos.logback" % "logback-classic" % "1.0.7"
|
||||
)
|
||||
|
||||
TaskKey[Unit]("check") <<= (ivyReport in Test, asciiTree in Test) map { (report, graph) =>
|
||||
def sanitize(str: String): String = str.split('\n').drop(1).map(_.trim).mkString("\n")
|
||||
|
|
@ -17,9 +17,6 @@ TaskKey[Unit]("check") <<= (ivyReport in Test, asciiTree in Test) map { (report,
|
|||
| | +-ch.qos.logback:logback-core:1.0.7
|
||||
| | +-org.slf4j:slf4j-api:1.6.6 (evicted by: 1.7.2)
|
||||
| |
|
||||
| +-com.typesafe.akka:akka-actor:2.0.3 [S]
|
||||
| | +-com.typesafe:config:0.3.1
|
||||
| |
|
||||
| +-org.slf4j:slf4j-api:1.7.2
|
||||
| """.stripMargin
|
||||
IO.writeLines(file("/tmp/blib"), sanitize(graph).split("\n"))
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.0-RC3")
|
||||
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.1-SNAPSHOT")
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import collection.mutable.ListBuffer
|
||||
import net.virtualvoid.sbt.graph.Plugin._
|
||||
|
||||
import sbt._
|
||||
import sbt.Keys._
|
||||
|
||||
object Build extends sbt.Build {
|
||||
|
||||
def defaultSettings =
|
||||
seq(scalaVersion := "2.9.2")
|
||||
|
||||
lazy val justATransiviteDependencyEndpointProject =
|
||||
Project("just-a-transitive-dependency-endpoint", file("."))
|
||||
.settings(defaultSettings: _*)
|
||||
|
||||
lazy val justATransitiveDependencyProject =
|
||||
Project("just-a-transitive-dependency", file("."))
|
||||
.settings(defaultSettings: _*)
|
||||
.dependsOn(justATransiviteDependencyEndpointProject)
|
||||
|
||||
lazy val justADependencyProject =
|
||||
Project("just-a-dependency", file("."))
|
||||
.settings(defaultSettings: _*)
|
||||
|
||||
lazy val test_project =
|
||||
Project("test-dot-file-generation", file("."))
|
||||
.settings(graphSettings: _*)
|
||||
.settings(defaultSettings: _*)
|
||||
.settings(
|
||||
TaskKey[Unit]("check") <<= (dependencyDot in Compile) map { (dotFile) =>
|
||||
val expectedGraph =
|
||||
"""digraph "dependency-graph" {
|
||||
| graph[rankdir="LR"]
|
||||
| node [
|
||||
| shape="record"
|
||||
| ]
|
||||
| edge [
|
||||
| arrowtail="none"
|
||||
| ]
|
||||
| "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT"[label=<test-dot-file-generation<BR/><B>test-dot-file-generation_2.9.2</B><BR/>0.1-SNAPSHOT>]
|
||||
| "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT"[label=<just-a-transitive-dependency<BR/><B>just-a-transitive-dependency_2.9.2</B><BR/>0.1-SNAPSHOT>]
|
||||
| "just-a-transitive-dependency-endpoint:just-a-transitive-dependency-endpoint_2.9.2:0.1-SNAPSHOT"[label=<just-a-transitive-dependency-endpoint<BR/><B>just-a-transitive-dependency-endpoint_2.9.2</B><BR/>0.1-SNAPSHOT>]
|
||||
| "just-a-dependency:just-a-dependency_2.9.2:0.1-SNAPSHOT"[label=<just-a-dependency<BR/><B>just-a-dependency_2.9.2</B><BR/>0.1-SNAPSHOT>]
|
||||
| "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT" -> "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT"
|
||||
| "just-a-transitive-dependency:just-a-transitive-dependency_2.9.2:0.1-SNAPSHOT" -> "just-a-transitive-dependency-endpoint:just-a-transitive-dependency-endpoint_2.9.2:0.1-SNAPSHOT"
|
||||
| "test-dot-file-generation:test-dot-file-generation_2.9.2:0.1-SNAPSHOT" -> "just-a-dependency:just-a-dependency_2.9.2:0.1-SNAPSHOT"
|
||||
|}
|
||||
""".stripMargin
|
||||
|
||||
val graph : String = scala.io.Source.fromFile(dotFile.getAbsolutePath).mkString
|
||||
val errors = compareByLine(graph, expectedGraph)
|
||||
require(errors.isEmpty , errors.mkString("\n"))
|
||||
()
|
||||
}
|
||||
)
|
||||
.dependsOn(justADependencyProject, justATransitiveDependencyProject)
|
||||
|
||||
def compareByLine(got : String, expected : String) : Seq[String] = {
|
||||
val errors = ListBuffer[String]()
|
||||
got.split("\n").zip(expected.split("\n").toSeq).zipWithIndex.foreach { case((got_line : String, expected_line : String), i : Int) =>
|
||||
if(got_line != expected_line) {
|
||||
errors.append(
|
||||
"""not matching lines at line %s
|
||||
|expected: %s
|
||||
|got: %s
|
||||
|""".stripMargin.format(i,expected_line, got_line))
|
||||
}
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../plugins.sbt
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
> project test-dot-file-generation
|
||||
> check
|
||||
Loading…
Reference in New Issue