github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/modcmd/graph.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // go mod graph 6 7 package modcmd 8 9 import ( 10 "bufio" 11 "os" 12 "sort" 13 14 "github.com/gagliardetto/golang-go/cmd/go/not-internal/base" 15 "github.com/gagliardetto/golang-go/cmd/go/not-internal/cfg" 16 "github.com/gagliardetto/golang-go/cmd/go/not-internal/modload" 17 "github.com/gagliardetto/golang-go/cmd/go/not-internal/par" 18 "github.com/gagliardetto/golang-go/cmd/go/not-internal/work" 19 20 "golang.org/x/mod/module" 21 ) 22 23 var cmdGraph = &base.Command{ 24 UsageLine: "go mod graph", 25 Short: "print module requirement graph", 26 Long: ` 27 Graph prints the module requirement graph (with replacements applied) 28 in text form. Each line in the output has two space-separated fields: a module 29 and one of its requirements. Each module is identified as a string of the form 30 path@version, except for the main module, which has no @version suffix. 31 `, 32 Run: runGraph, 33 } 34 35 func init() { 36 work.AddModCommonFlags(cmdGraph) 37 } 38 39 func runGraph(cmd *base.Command, args []string) { 40 if len(args) > 0 { 41 base.Fatalf("go mod graph: graph takes no arguments") 42 } 43 // Checks go mod expected behavior 44 if !modload.Enabled() { 45 if cfg.Getenv("GO111MODULE") == "off" { 46 base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") 47 } else { 48 base.Fatalf("go: cannot find main module; see 'go help modules'") 49 } 50 } 51 modload.LoadBuildList() 52 53 reqs := modload.MinReqs() 54 format := func(m module.Version) string { 55 if m.Version == "" { 56 return m.Path 57 } 58 return m.Path + "@" + m.Version 59 } 60 61 // Note: using par.Work only to manage work queue. 62 // No parallelism here, so no locking. 63 var out []string 64 var deps int // index in out where deps start 65 var work par.Work 66 work.Add(modload.Target) 67 work.Do(1, func(item interface{}) { 68 m := item.(module.Version) 69 list, _ := reqs.Required(m) 70 for _, r := range list { 71 work.Add(r) 72 out = append(out, format(m)+" "+format(r)+"\n") 73 } 74 if m == modload.Target { 75 deps = len(out) 76 } 77 }) 78 79 sort.Slice(out[deps:], func(i, j int) bool { 80 return out[deps+i][0] < out[deps+j][0] 81 }) 82 83 w := bufio.NewWriter(os.Stdout) 84 for _, line := range out { 85 w.WriteString(line) 86 } 87 w.Flush() 88 }