...
1
2
3
4
5
6
7 package modcmd
8
9 import (
10 "cmd/go/internal/base"
11 "cmd/go/internal/cfg"
12 "cmd/go/internal/gover"
13 "cmd/go/internal/imports"
14 "cmd/go/internal/modload"
15 "cmd/go/internal/toolchain"
16 "context"
17 "fmt"
18
19 "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
61 tidyGo goVersionFlag
62 tidyCompat goVersionFlag
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
76
77
78
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
107
108
109
110
111
112
113
114
115
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 }
140
View as plain text