mirror of
https://github.com/golang/go.git
synced 2025-11-10 21:51:05 +00:00
Fixes #46141 Change-Id: I9d4032e75252ade9eaa937389ea97ef3fb287499 Reviewed-on: https://go-review.googlesource.com/c/go/+/321071 Trust: Bryan C. Mills <bcmills@google.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
125 lines
4.2 KiB
Go
125 lines
4.2 KiB
Go
// 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 (
|
|
"cmd/go/internal/base"
|
|
"cmd/go/internal/cfg"
|
|
"cmd/go/internal/imports"
|
|
"cmd/go/internal/modload"
|
|
"context"
|
|
"fmt"
|
|
|
|
"golang.org/x/mod/modfile"
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
var cmdTidy = &base.Command{
|
|
UsageLine: "go mod tidy [-e] [-v] [-go=version] [-compat=version]",
|
|
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.
|
|
|
|
The -e flag causes tidy to attempt to proceed despite errors
|
|
encountered while loading packages.
|
|
|
|
The -go flag causes tidy to update the 'go' directive in the go.mod
|
|
file to the given version, which may change which module dependencies
|
|
are retained as explicit requirements in the go.mod file.
|
|
(Go versions 1.17 and higher retain more requirements in order to
|
|
support lazy module loading.)
|
|
|
|
The -compat flag preserves any additional checksums needed for the
|
|
'go' command from the indicated major Go release to successfully load
|
|
the module graph, and causes tidy to error out if that version of the
|
|
'go' command would load any imported package from a different module
|
|
version. By default, tidy acts as if the -compat flag were set to the
|
|
version prior to the one indicated by the 'go' directive in the go.mod
|
|
file.
|
|
|
|
See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
|
|
`,
|
|
Run: runTidy,
|
|
}
|
|
|
|
var (
|
|
tidyE bool // if true, report errors but proceed anyway.
|
|
tidyGo goVersionFlag // go version to write to the tidied go.mod file (toggles lazy loading)
|
|
tidyCompat goVersionFlag // go version for which the tidied go.mod and go.sum files should be “compatible”
|
|
)
|
|
|
|
func init() {
|
|
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
|
cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
|
|
cmdTidy.Flag.Var(&tidyGo, "go", "")
|
|
cmdTidy.Flag.Var(&tidyCompat, "compat", "")
|
|
base.AddModCommonFlags(&cmdTidy.Flag)
|
|
}
|
|
|
|
// A goVersionFlag is a flag.Value representing a supported Go version.
|
|
//
|
|
// (Note that the -go argument to 'go mod edit' is *not* a goVersionFlag.
|
|
// It intentionally allows newer-than-supported versions as arguments.)
|
|
type goVersionFlag struct {
|
|
v string
|
|
}
|
|
|
|
func (f *goVersionFlag) String() string { return f.v }
|
|
func (f *goVersionFlag) Get() interface{} { return f.v }
|
|
|
|
func (f *goVersionFlag) Set(s string) error {
|
|
if s != "" {
|
|
latest := modload.LatestGoVersion()
|
|
if !modfile.GoVersionRE.MatchString(s) {
|
|
return fmt.Errorf("expecting a Go version like %q", latest)
|
|
}
|
|
if semver.Compare("v"+s, "v"+latest) > 0 {
|
|
return fmt.Errorf("maximum supported Go version is %s", latest)
|
|
}
|
|
}
|
|
|
|
f.v = s
|
|
return nil
|
|
}
|
|
|
|
func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
|
if len(args) > 0 {
|
|
base.Fatalf("go mod tidy: no arguments allowed")
|
|
}
|
|
|
|
// Tidy aims to make 'go test' reproducible for any package in 'all', so we
|
|
// need to include test dependencies. For modules that specify go 1.15 or
|
|
// earlier this is a no-op (because 'all' saturates transitive test
|
|
// dependencies).
|
|
//
|
|
// However, with lazy loading (go 1.16+) 'all' includes only the packages that
|
|
// are transitively imported by the main module, not the test dependencies of
|
|
// those packages. In order to make 'go test' reproducible for the packages
|
|
// that are in 'all' but outside of the main module, we must explicitly
|
|
// request that their test dependencies be included.
|
|
modload.ForceUseModules = true
|
|
modload.RootMode = modload.NeedRoot
|
|
|
|
modload.LoadPackages(ctx, modload.PackageOpts{
|
|
GoVersion: tidyGo.String(),
|
|
Tags: imports.AnyTags(),
|
|
Tidy: true,
|
|
TidyCompatibleVersion: tidyCompat.String(),
|
|
VendorModulesInGOROOTSrc: true,
|
|
ResolveMissingImports: true,
|
|
LoadTests: true,
|
|
AllowErrors: tidyE,
|
|
SilenceMissingStdImports: true,
|
|
}, "all")
|
|
}
|