mirror of https://github.com/sbt/sbt.git
more customisation for dot output
with dependency-dot-head you can now define your own dot head. dependency-dot-node-label lets you customise the labels of the nodes
This commit is contained in:
parent
24c614d568
commit
2ea4470757
|
|
@ -55,6 +55,9 @@ Tasks & Settings
|
||||||
you want the scala-library dependency to appear in the output. (default: true)
|
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-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-file`: a setting which allows configuring the output path of `dependency-dot`.
|
||||||
|
* `dependency-dot-head`: a setting to customize the head 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
|
* `ivy-report`: let's ivy generate the resolution report for you project. Use
|
||||||
`show ivy-report` for the filename of the generated report
|
`show ivy-report` for the filename of the generated report
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,17 @@ object IvyGraphMLDependencies extends App {
|
||||||
|
|
||||||
XML.save(outputFile, xml)
|
XML.save(outputFile, xml)
|
||||||
}
|
}
|
||||||
def saveAsDot(graph : ModuleGraph, outputFile: File) : File = {
|
def saveAsDot(graph : ModuleGraph,
|
||||||
|
dotHead : String,
|
||||||
|
nodeFormation : Function3[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 = {
|
val edges = {
|
||||||
for ( e <- graph.edges)
|
for ( e <- graph.edges)
|
||||||
|
|
@ -203,16 +213,7 @@ object IvyGraphMLDependencies extends App {
|
||||||
""" "%s" -> "%s"""".format(e._1.idString, e._2.idString)
|
""" "%s" -> "%s"""".format(e._1.idString, e._2.idString)
|
||||||
}.mkString("\n")
|
}.mkString("\n")
|
||||||
|
|
||||||
val dot =
|
val dot = "%s\n%s\n%s\n}".format(dotHead, nodes, edges)
|
||||||
"""digraph "dependency-graph" {
|
|
||||||
| graph[rankdir="LR"]
|
|
||||||
| node [
|
|
||||||
| shape="record"
|
|
||||||
| ]
|
|
||||||
| edge [
|
|
||||||
| arrowtail="none"
|
|
||||||
| ]
|
|
||||||
|""".stripMargin + edges + "\n}"
|
|
||||||
|
|
||||||
sbt.IO.write(outputFile, dot)
|
sbt.IO.write(outputFile, dot)
|
||||||
outputFile
|
outputFile
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ object Plugin extends sbt.Plugin {
|
||||||
"Creates a graphml file containing the dependency-graph for a project")
|
"Creates a graphml file containing the dependency-graph for a project")
|
||||||
val dependencyDotFile = SettingKey[File]("dependency-dot-file",
|
val dependencyDotFile = SettingKey[File]("dependency-dot-file",
|
||||||
"The location the dot file should be generated at")
|
"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 dependencyDotHead = SettingKey[String]("dependency-dot-head",
|
||||||
|
"The head of the dot file. (e.g. to set your preferred node shapes)")
|
||||||
val dependencyDot = TaskKey[File]("dependency-dot",
|
val dependencyDot = TaskKey[File]("dependency-dot",
|
||||||
"Creates a dot file containing the dpendency-graph for a project")
|
"Creates a dot file containing the dpendency-graph for a project")
|
||||||
val moduleGraph = TaskKey[IvyGraphMLDependencies.ModuleGraph]("module-graph",
|
val moduleGraph = TaskKey[IvyGraphMLDependencies.ModuleGraph]("module-graph",
|
||||||
|
|
@ -110,6 +114,17 @@ object Plugin extends sbt.Plugin {
|
||||||
dependencyGraphML <<= dependencyGraphMLTask,
|
dependencyGraphML <<= dependencyGraphMLTask,
|
||||||
dependencyDotFile <<= target / "dependencies-%s.dot".format(config.toString),
|
dependencyDotFile <<= target / "dependencies-%s.dot".format(config.toString),
|
||||||
dependencyDot <<= dependencyDotTask,
|
dependencyDot <<= dependencyDotTask,
|
||||||
|
dependencyDotHead := """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 =>
|
whatDependsOn <<= InputTask(artifactIdParser) { module =>
|
||||||
(module, streams, moduleGraph) map { (module, streams, graph) =>
|
(module, streams, moduleGraph) map { (module, streams, graph) =>
|
||||||
streams.log.info(IvyGraphMLDependencies.asciiTree(IvyGraphMLDependencies.reverseGraphStartingAt(graph, module)))
|
streams.log.info(IvyGraphMLDependencies.asciiTree(IvyGraphMLDependencies.reverseGraphStartingAt(graph, module)))
|
||||||
|
|
@ -128,8 +143,9 @@ object Plugin extends sbt.Plugin {
|
||||||
resultFile
|
resultFile
|
||||||
}
|
}
|
||||||
def dependencyDotTask =
|
def dependencyDotTask =
|
||||||
(moduleGraph, dependencyDotFile, streams) map { (graph, outFile, streams) =>
|
(moduleGraph, dependencyDotHead, dependencyDotNodeLabel, dependencyDotFile, streams).
|
||||||
val resultFile = IvyGraphMLDependencies.saveAsDot(graph, outFile)
|
map { (graph, dotHead, nodeLabelFormation, outFile, streams) =>
|
||||||
|
val resultFile = IvyGraphMLDependencies.saveAsDot(graph, dotHead, nodeLabelFormation, outFile)
|
||||||
streams.log.info("Wrote dependency graph to '%s'" format resultFile)
|
streams.log.info("Wrote dependency graph to '%s'" format resultFile)
|
||||||
resultFile
|
resultFile
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,26 +35,29 @@ object Build extends sbt.Build {
|
||||||
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
|
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
|
||||||
|
|
||||||
TaskKey[Unit]("check") <<= (dependencyDot in Compile) map { (dotFile) =>
|
TaskKey[Unit]("check") <<= (dependencyDot in Compile) map { (dotFile) =>
|
||||||
def sanitize(str: String): String = str.split('\n').drop(1).mkString("\n")
|
val expectedGraph =
|
||||||
val expectedGraph =
|
"""digraph "dependency-graph" {
|
||||||
"""digraph "dependency-graph" {
|
| graph[rankdir="LR"]
|
||||||
| graph[rankdir="LR"]
|
| node [
|
||||||
| node [
|
| shape="record"
|
||||||
| shape="record"
|
| ]
|
||||||
| ]
|
| edge [
|
||||||
| edge [
|
| arrowtail="none"
|
||||||
| 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>]
|
||||||
| "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"[label=<just-a-transitive-dependency<BR/><B>just-a-transitive-dependency_2.9.2</B><BR/>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"
|
| "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>]
|
||||||
| "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"
|
| "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"
|
||||||
""".stripMargin
|
| "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 graph : String = scala.io.Source.fromFile(dotFile.getAbsolutePath).mkString
|
||||||
val errors = compareByLine(graph, expectedGraph)
|
val errors = compareByLine(graph, expectedGraph)
|
||||||
require(errors.isEmpty , errors.mkString("\n"))
|
require(errors.isEmpty , errors.mkString("\n"))
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
).dependsOn(justADependencyProject, justATransitiveDependencyProject)
|
).dependsOn(justADependencyProject, justATransitiveDependencyProject)
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
> test-dot-file-generation/check
|
> project test-dot-file-generation
|
||||||
|
> check
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue