aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modcmd/graph.go
diff options
context:
space:
mode:
authorGiovanni Bajo <rasky@develer.com>2018-08-03 02:08:43 +0200
committerGiovanni Bajo <rasky@develer.com>2018-08-20 18:14:55 +0000
commit723479bc30f998f29ecbba7caea118ac4e2c9afd (patch)
tree5ef457345f7a14b272fe3abb53b7dffe4960d81b /src/cmd/go/internal/modcmd/graph.go
parent18034e6b9f0f623335e6358e0a4634a4eec04dd1 (diff)
downloadgo-723479bc30f998f29ecbba7caea118ac4e2c9afd.tar.gz
go-723479bc30f998f29ecbba7caea118ac4e2c9afd.zip
cmd/go: add graphviz output to graph command
This allows to quickly visual inspect dependencies. Change-Id: Ice326ec69d7d57720f608b04cdf3ece153b8c5f1 Reviewed-on: https://go-review.googlesource.com/127599 Run-TryBot: Giovanni Bajo <rasky@develer.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/go/internal/modcmd/graph.go')
-rw-r--r--src/cmd/go/internal/modcmd/graph.go33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 5825c6d8ca..b123454d60 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -18,15 +18,25 @@ import (
)
var cmdGraph = &base.Command{
- UsageLine: "go mod graph",
+ UsageLine: "go mod graph [-dot]",
Short: "print module requirement graph",
Long: `
Graph prints the module requirement graph (with replacements applied)
in text form. Each line in the output has two space-separated fields: a module
and one of its requirements. Each module is identified as a string of the form
path@version, except for the main module, which has no @version suffix.
+
+The -dot flag generates the output in graphviz format that can be used
+with a tool like dot to visually render the dependency graph.
`,
- Run: runGraph,
+}
+
+var (
+ graphDot = cmdGraph.Flag.Bool("dot", false, "")
+)
+
+func init() {
+ cmdGraph.Run = runGraph // break init cycle
}
func runGraph(cmd *base.Command, args []string) {
@@ -51,10 +61,21 @@ func runGraph(cmd *base.Command, args []string) {
work.Add(modload.Target)
work.Do(1, func(item interface{}) {
m := item.(module.Version)
+ if *graphDot {
+ if m.Version == "" {
+ out = append(out, "\""+m.Path+"\" [label=<"+m.Path+">]\n")
+ } else {
+ out = append(out, "\""+m.Path+"\" [label=<"+m.Path+"<br/><font point-size=\"9\">"+m.Version+"</font>>]\n")
+ }
+ }
list, _ := reqs.Required(m)
for _, r := range list {
work.Add(r)
- out = append(out, format(m)+" "+format(r)+"\n")
+ if *graphDot {
+ out = append(out, "\""+m.Path+"\" -> \""+r.Path+"\"\n")
+ } else {
+ out = append(out, format(m)+" "+format(r)+"\n")
+ }
}
if m == modload.Target {
deps = len(out)
@@ -66,8 +87,14 @@ func runGraph(cmd *base.Command, args []string) {
})
w := bufio.NewWriter(os.Stdout)
+ if *graphDot {
+ w.WriteString("digraph deps {\nrankdir=LR\n")
+ }
for _, line := range out {
w.WriteString(line)
}
+ if *graphDot {
+ w.WriteString("}\n")
+ }
w.Flush()
}