...
Source file src/pkg/cmd/go/internal/modcmd/graph.go
1
2
3
4
5
6
7 package modcmd
8
9 import (
10 "bufio"
11 "cmd/go/internal/cfg"
12 "os"
13 "sort"
14
15 "cmd/go/internal/base"
16 "cmd/go/internal/modload"
17 "cmd/go/internal/module"
18 "cmd/go/internal/par"
19 )
20
21 var cmdGraph = &base.Command{
22 UsageLine: "go mod graph",
23 Short: "print module requirement graph",
24 Long: `
25 Graph prints the module requirement graph (with replacements applied)
26 in text form. Each line in the output has two space-separated fields: a module
27 and one of its requirements. Each module is identified as a string of the form
28 path@version, except for the main module, which has no @version suffix.
29 `,
30 Run: runGraph,
31 }
32
33 func runGraph(cmd *base.Command, args []string) {
34 if len(args) > 0 {
35 base.Fatalf("go mod graph: graph takes no arguments")
36 }
37
38 if !modload.Enabled() {
39 if cfg.Getenv("GO111MODULE") == "off" {
40 base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
41 } else {
42 base.Fatalf("go: cannot find main module; see 'go help modules'")
43 }
44 }
45 modload.LoadBuildList()
46
47 reqs := modload.MinReqs()
48 format := func(m module.Version) string {
49 if m.Version == "" {
50 return m.Path
51 }
52 return m.Path + "@" + m.Version
53 }
54
55
56
57 var out []string
58 var deps int
59 var work par.Work
60 work.Add(modload.Target)
61 work.Do(1, func(item interface{}) {
62 m := item.(module.Version)
63 list, _ := reqs.Required(m)
64 for _, r := range list {
65 work.Add(r)
66 out = append(out, format(m)+" "+format(r)+"\n")
67 }
68 if m == modload.Target {
69 deps = len(out)
70 }
71 })
72
73 sort.Slice(out[deps:], func(i, j int) bool {
74 return out[deps+i][0] < out[deps+j][0]
75 })
76
77 w := bufio.NewWriter(os.Stdout)
78 for _, line := range out {
79 w.WriteString(line)
80 }
81 w.Flush()
82 }
83
View as plain text