diff options
Diffstat (limited to 'libgo/go/cmd/go/internal/modcmd/tidy.go')
-rw-r--r-- | libgo/go/cmd/go/internal/modcmd/tidy.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go b/libgo/go/cmd/go/internal/modcmd/tidy.go new file mode 100644 index 00000000000..f2063a9ea60 --- /dev/null +++ b/libgo/go/cmd/go/internal/modcmd/tidy.go @@ -0,0 +1,90 @@ +// 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 tidy + +package modcmd + +import ( + "fmt" + "os" + + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/modfetch" + "cmd/go/internal/modload" + "cmd/go/internal/module" +) + +var cmdTidy = &base.Command{ + UsageLine: "go mod tidy [-v]", + Short: "add missing and remove unused modules", + Long: ` +Tidy makes sure go.mod matches the source code in the module. +It adds any missing modules necessary to build the current module's +packages and dependencies, and it removes unused modules that +don't provide any relevant packages. It also adds any missing entries +to go.sum and removes any unnecessary ones. + +The -v flag causes tidy to print information about removed modules +to standard error. + `, +} + +func init() { + cmdTidy.Run = runTidy // break init cycle + cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "") +} + +func runTidy(cmd *base.Command, args []string) { + if len(args) > 0 { + base.Fatalf("go mod tidy: no arguments allowed") + } + + // LoadALL adds missing modules. + // Remove unused modules. + used := make(map[module.Version]bool) + for _, pkg := range modload.LoadALL() { + used[modload.PackageModule(pkg)] = true + } + used[modload.Target] = true // note: LoadALL initializes Target + + inGoMod := make(map[string]bool) + for _, r := range modload.ModFile().Require { + inGoMod[r.Mod.Path] = true + } + + var keep []module.Version + for _, m := range modload.BuildList() { + if used[m] { + keep = append(keep, m) + } else if cfg.BuildV && inGoMod[m.Path] { + fmt.Fprintf(os.Stderr, "unused %s\n", m.Path) + } + } + modload.SetBuildList(keep) + modTidyGoSum() // updates memory copy; WriteGoMod on next line flushes it out + modload.WriteGoMod() +} + +// modTidyGoSum resets the go.sum file content +// to be exactly what's needed for the current go.mod. +func modTidyGoSum() { + // Assuming go.sum already has at least enough from the successful load, + // we only have to tell modfetch what needs keeping. + reqs := modload.Reqs() + keep := make(map[module.Version]bool) + var walk func(module.Version) + walk = func(m module.Version) { + keep[m] = true + list, _ := reqs.Required(m) + for _, r := range list { + if !keep[r] { + walk(r) + } + } + } + walk(modload.Target) + modfetch.TrimGoSum(keep) +} |