blob: 27ae9354f3d97792f8d2f11ed455bcfc4c34cebf [file] [log] [blame]
// 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/cfg"
"cmd/go/internal/modload"
"cmd/go/internal/par"
"cmd/go/internal/work"
"golang.org/x/mod/module"
)
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 init() {
work.AddModCommonFlags(cmdGraph)
}
func runGraph(cmd *base.Command, args []string) {
if len(args) > 0 {
base.Fatalf("go mod graph: graph takes no arguments")
}
// Checks go mod expected behavior
if !modload.Enabled() {
if cfg.Getenv("GO111MODULE") == "off" {
base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
} else {
base.Fatalf("go: cannot find main module; see 'go help modules'")
}
}
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()
}