diff options
Diffstat (limited to 'libgo/go/cmd/go/internal/modcmd/graph.go')
-rw-r--r-- | libgo/go/cmd/go/internal/modcmd/graph.go | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/libgo/go/cmd/go/internal/modcmd/graph.go b/libgo/go/cmd/go/internal/modcmd/graph.go new file mode 100644 index 00000000000..5825c6d8ca8 --- /dev/null +++ b/libgo/go/cmd/go/internal/modcmd/graph.go @@ -0,0 +1,73 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// go mod graph + +package modcmd + +import ( + "bufio" + "os" + "sort" + + "cmd/go/internal/base" + "cmd/go/internal/modload" + "cmd/go/internal/module" + "cmd/go/internal/par" +) + +var cmdGraph = &base.Command{ + UsageLine: "go mod graph", + 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. + `, + Run: runGraph, +} + +func runGraph(cmd *base.Command, args []string) { + if len(args) > 0 { + base.Fatalf("go mod graph: graph takes no arguments") + } + modload.LoadBuildList() + + reqs := modload.MinReqs() + format := func(m module.Version) string { + if m.Version == "" { + return m.Path + } + return m.Path + "@" + m.Version + } + + // Note: using par.Work only to manage work queue. + // No parallelism here, so no locking. + var out []string + var deps int // index in out where deps start + var work par.Work + work.Add(modload.Target) + work.Do(1, func(item interface{}) { + m := item.(module.Version) + list, _ := reqs.Required(m) + for _, r := range list { + work.Add(r) + out = append(out, format(m)+" "+format(r)+"\n") + } + if m == modload.Target { + deps = len(out) + } + }) + + sort.Slice(out[deps:], func(i, j int) bool { + return out[deps+i][0] < out[deps+j][0] + }) + + w := bufio.NewWriter(os.Stdout) + for _, line := range out { + w.WriteString(line) + } + w.Flush() +} |