github.com/bir3/gocompiler@v0.9.2202/src/cmd/gocmd/internal/modcmd/tidy.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 tidy 6 7 package modcmd 8 9 import ( 10 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/base" 11 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/cfg" 12 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/gover" 13 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/imports" 14 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/modload" 15 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/toolchain" 16 "context" 17 "fmt" 18 19 "github.com/bir3/gocompiler/src/xvendor/golang.org/x/mod/modfile" 20 ) 21 22 var cmdTidy = &base.Command{ 23 UsageLine: "go mod tidy [-e] [-v] [-x] [-go=version] [-compat=version]", 24 Short: "add missing and remove unused modules", 25 Long: ` 26 Tidy makes sure go.mod matches the source code in the module. 27 It adds any missing modules necessary to build the current module's 28 packages and dependencies, and it removes unused modules that 29 don't provide any relevant packages. It also adds any missing entries 30 to go.sum and removes any unnecessary ones. 31 32 The -v flag causes tidy to print information about removed modules 33 to standard error. 34 35 The -e flag causes tidy to attempt to proceed despite errors 36 encountered while loading packages. 37 38 The -go flag causes tidy to update the 'go' directive in the go.mod 39 file to the given version, which may change which module dependencies 40 are retained as explicit requirements in the go.mod file. 41 (Go versions 1.17 and higher retain more requirements in order to 42 support lazy module loading.) 43 44 The -compat flag preserves any additional checksums needed for the 45 'go' command from the indicated major Go release to successfully load 46 the module graph, and causes tidy to error out if that version of the 47 'go' command would load any imported package from a different module 48 version. By default, tidy acts as if the -compat flag were set to the 49 version prior to the one indicated by the 'go' directive in the go.mod 50 file. 51 52 The -x flag causes tidy to print the commands download executes. 53 54 See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'. 55 `, 56 Run: runTidy, 57 } 58 59 var ( 60 tidyE bool // if true, report errors but proceed anyway. 61 tidyGo goVersionFlag // go version to write to the tidied go.mod file (toggles lazy loading) 62 tidyCompat goVersionFlag // go version for which the tidied go.mod and go.sum files should be “compatible” 63 ) 64 65 func init() { 66 cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "") 67 cmdTidy.Flag.BoolVar(&cfg.BuildX, "x", false, "") 68 cmdTidy.Flag.BoolVar(&tidyE, "e", false, "") 69 cmdTidy.Flag.Var(&tidyGo, "go", "") 70 cmdTidy.Flag.Var(&tidyCompat, "compat", "") 71 base.AddChdirFlag(&cmdTidy.Flag) 72 base.AddModCommonFlags(&cmdTidy.Flag) 73 } 74 75 // A goVersionFlag is a flag.Value representing a supported Go version. 76 // 77 // (Note that the -go argument to 'go mod edit' is *not* a goVersionFlag. 78 // It intentionally allows newer-than-supported versions as arguments.) 79 type goVersionFlag struct { 80 v string 81 } 82 83 func (f *goVersionFlag) String() string { return f.v } 84 func (f *goVersionFlag) Get() any { return f.v } 85 86 func (f *goVersionFlag) Set(s string) error { 87 if s != "" { 88 latest := gover.Local() 89 if !modfile.GoVersionRE.MatchString(s) { 90 return fmt.Errorf("expecting a Go version like %q", latest) 91 } 92 if gover.Compare(s, latest) > 0 { 93 return fmt.Errorf("maximum supported Go version is %s", latest) 94 } 95 } 96 97 f.v = s 98 return nil 99 } 100 101 func runTidy(ctx context.Context, cmd *base.Command, args []string) { 102 if len(args) > 0 { 103 base.Fatalf("go: 'go mod tidy' accepts no arguments") 104 } 105 106 // Tidy aims to make 'go test' reproducible for any package in 'all', so we 107 // need to include test dependencies. For modules that specify go 1.15 or 108 // earlier this is a no-op (because 'all' saturates transitive test 109 // dependencies). 110 // 111 // However, with lazy loading (go 1.16+) 'all' includes only the packages that 112 // are transitively imported by the main module, not the test dependencies of 113 // those packages. In order to make 'go test' reproducible for the packages 114 // that are in 'all' but outside of the main module, we must explicitly 115 // request that their test dependencies be included. 116 modload.ForceUseModules = true 117 modload.RootMode = modload.NeedRoot 118 119 goVersion := tidyGo.String() 120 if goVersion != "" && gover.Compare(gover.Local(), goVersion) < 0 { 121 toolchain.SwitchOrFatal(ctx, &gover.TooNewError{ 122 What: "-go flag", 123 GoVersion: goVersion, 124 }) 125 } 126 127 modload.LoadPackages(ctx, modload.PackageOpts{ 128 TidyGoVersion: tidyGo.String(), 129 Tags: imports.AnyTags(), 130 Tidy: true, 131 TidyCompatibleVersion: tidyCompat.String(), 132 VendorModulesInGOROOTSrc: true, 133 ResolveMissingImports: true, 134 LoadTests: true, 135 AllowErrors: tidyE, 136 SilenceMissingStdImports: true, 137 Switcher: new(toolchain.Switcher), 138 }, "all") 139 }