summaryrefslogtreecommitdiff
path: root/libgo/go/cmd/go/internal/modcmd/graph.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/cmd/go/internal/modcmd/graph.go')
-rw-r--r--libgo/go/cmd/go/internal/modcmd/graph.go73
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()
+}