aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/list/list.go
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2020-04-15 14:42:15 -0400
committerJay Conrod <jayconrod@google.com>2020-08-26 21:17:01 +0000
commiteb3e27ac1a9346c7c2669ba2b863811607eddeae (patch)
tree767051299d2f74722b242fecca14c96751697da1 /src/cmd/go/internal/list/list.go
parent0bbd386e8bbdf419077d708d3671245fc0f50f0c (diff)
downloadgo-eb3e27ac1a9346c7c2669ba2b863811607eddeae.tar.gz
go-eb3e27ac1a9346c7c2669ba2b863811607eddeae.zip
cmd/go: add -retracted flag to 'go list'
The -retracted flag causes 'go list' to load information about retracted module module versions. When -retracted is used with -f or -json, the Retracted field is set to a string containing the reason for the retraction on retracted module versions. The string is based on comments on the retract directive. This field is also populated when the -u flag is used. When -retracted is used with -versions, retracted versions are shown. Normally, they are omitted. For #24031 Change-Id: Ic13d516eddffb1b8404e21034f78cecc9896d1b8 Reviewed-on: https://go-review.googlesource.com/c/go/+/228382 Reviewed-by: Michael Matloob <matloob@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/go/internal/list/list.go')
-rw-r--r--src/cmd/go/internal/list/list.go100
1 files changed, 86 insertions, 14 deletions
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index e68c39f392..6d81c1cad1 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -10,6 +10,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "fmt"
"io"
"os"
"sort"
@@ -215,6 +216,7 @@ applied to a Go struct, but now a Module struct:
Dir string // directory holding files for this module, if any
GoMod string // path to go.mod file used when loading this module, if any
GoVersion string // go version used in module
+ Retracted string // retraction information, if any (with -retracted or -u)
Error *ModuleError // error loading module
}
@@ -246,14 +248,16 @@ the replaced source code.)
The -u flag adds information about available upgrades.
When the latest version of a given module is newer than
the current one, list -u sets the Module's Update field
-to information about the newer module.
+to information about the newer module. list -u will also set
+the module's Retracted field if the current version is retracted.
The Module's String method indicates an available upgrade by
formatting the newer version in brackets after the current version.
+If a version is retracted, the string "(retracted)" will follow it.
For example, 'go list -m -u all' might print:
my/main/module
golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
- rsc.io/pdf v0.1.1 [v0.1.2]
+ rsc.io/pdf v0.1.1 (retracted) [v0.1.2]
(For tools, 'go list -m -u -json all' may be more convenient to parse.)
@@ -263,6 +267,14 @@ to semantic versioning, earliest to latest. The flag also changes
the default output format to display the module path followed by the
space-separated version list.
+The -retracted flag causes list to report information about retracted
+module versions. When -retracted is used with -f or -json, the Retracted
+field will be set to a string explaining why the version was retracted.
+The string is taken from comments on the retract directive in the
+module's go.mod file. When -retracted is used with -versions, retracted
+versions are listed together with unretracted versions. The -retracted
+flag may be used with or without -m.
+
The arguments to list -m are interpreted as a list of modules, not packages.
The main module is the module containing the current directory.
The active modules are the main module and its dependencies.
@@ -296,17 +308,18 @@ func init() {
}
var (
- listCompiled = CmdList.Flag.Bool("compiled", false, "")
- listDeps = CmdList.Flag.Bool("deps", false, "")
- listE = CmdList.Flag.Bool("e", false, "")
- listExport = CmdList.Flag.Bool("export", false, "")
- listFmt = CmdList.Flag.String("f", "", "")
- listFind = CmdList.Flag.Bool("find", false, "")
- listJson = CmdList.Flag.Bool("json", false, "")
- listM = CmdList.Flag.Bool("m", false, "")
- listU = CmdList.Flag.Bool("u", false, "")
- listTest = CmdList.Flag.Bool("test", false, "")
- listVersions = CmdList.Flag.Bool("versions", false, "")
+ listCompiled = CmdList.Flag.Bool("compiled", false, "")
+ listDeps = CmdList.Flag.Bool("deps", false, "")
+ listE = CmdList.Flag.Bool("e", false, "")
+ listExport = CmdList.Flag.Bool("export", false, "")
+ listFmt = CmdList.Flag.String("f", "", "")
+ listFind = CmdList.Flag.Bool("find", false, "")
+ listJson = CmdList.Flag.Bool("json", false, "")
+ listM = CmdList.Flag.Bool("m", false, "")
+ listRetracted = CmdList.Flag.Bool("retracted", false, "")
+ listTest = CmdList.Flag.Bool("test", false, "")
+ listU = CmdList.Flag.Bool("u", false, "")
+ listVersions = CmdList.Flag.Bool("versions", false, "")
)
var nl = []byte{'\n'}
@@ -367,6 +380,16 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
}
+ modload.Init()
+ if *listRetracted {
+ if cfg.BuildMod == "vendor" {
+ base.Fatalf("go list -retracted cannot be used when vendoring is enabled")
+ }
+ if !modload.Enabled() {
+ base.Fatalf("go list -retracted can only be used in module-aware mode")
+ }
+ }
+
if *listM {
// Module mode.
if *listCompiled {
@@ -416,7 +439,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
modload.LoadBuildList(ctx)
- mods := modload.ListModules(ctx, args, *listU, *listVersions)
+ mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted)
if !*listE {
for _, m := range mods {
if m.Error != nil {
@@ -607,6 +630,55 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
}
+ // TODO(golang.org/issue/40676): This mechanism could be extended to support
+ // -u without -m.
+ if *listRetracted {
+ // Load retractions for modules that provide packages that will be printed.
+ // TODO(golang.org/issue/40775): Packages from the same module refer to
+ // distinct ModulePublic instance. It would be nice if they could all point
+ // to the same instance. This would require additional global state in
+ // modload.loaded, so that should be refactored first. For now, we update
+ // all instances.
+ modToArg := make(map[*modinfo.ModulePublic]string)
+ argToMods := make(map[string][]*modinfo.ModulePublic)
+ var args []string
+ addModule := func(mod *modinfo.ModulePublic) {
+ if mod.Version == "" {
+ return
+ }
+ arg := fmt.Sprintf("%s@%s", mod.Path, mod.Version)
+ if argToMods[arg] == nil {
+ args = append(args, arg)
+ }
+ argToMods[arg] = append(argToMods[arg], mod)
+ modToArg[mod] = arg
+ }
+ for _, p := range pkgs {
+ if p.Module == nil {
+ continue
+ }
+ addModule(p.Module)
+ if p.Module.Replace != nil {
+ addModule(p.Module.Replace)
+ }
+ }
+
+ if len(args) > 0 {
+ listU := false
+ listVersions := false
+ rmods := modload.ListModules(ctx, args, listU, listVersions, *listRetracted)
+ for i, arg := range args {
+ rmod := rmods[i]
+ for _, mod := range argToMods[arg] {
+ mod.Retracted = rmod.Retracted
+ if rmod.Error != nil && mod.Error == nil {
+ mod.Error = rmod.Error
+ }
+ }
+ }
+ }
+ }
+
// Record non-identity import mappings in p.ImportMap.
for _, p := range pkgs {
for i, srcPath := range p.Internal.RawImports {