1
0
mirror of https://github.com/golang/go synced 2024-11-13 15:00:23 -07:00

cmd/go: refactor modload.ListModules to accept bit flags

Instead of accepting bool flags, ListModules now accepts ListMode, a
set of bit flags.

Four flags are defined. listRetracted is split into ListRetracted and
ListRetractedVersion to avoid ambiguity with -u, -retracted, and
-versions.

For #40357

Change-Id: Ibbbe44dc1e285ed17f27a6581f3392679f2124fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/306331
Trust: Jay Conrod <jayconrod@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Jay Conrod 2021-03-31 14:19:41 -04:00
parent 4230a6ebdd
commit ee51e3d895
5 changed files with 50 additions and 34 deletions

View File

@ -451,7 +451,20 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
} }
} }
mods, err := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted) var mode modload.ListMode
if *listU {
mode |= modload.ListU | modload.ListRetracted
}
if *listRetracted {
mode |= modload.ListRetracted
}
if *listVersions {
mode |= modload.ListVersions
if *listRetracted {
mode |= modload.ListRetractedVersions
}
}
mods, err := modload.ListModules(ctx, args, mode)
if !*listE { if !*listE {
for _, m := range mods { for _, m := range mods {
if m.Error != nil { if m.Error != nil {
@ -686,9 +699,11 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
} }
if len(args) > 0 { if len(args) > 0 {
listU := false var mode modload.ListMode
listVersions := false if *listRetracted {
rmods, err := modload.ListModules(ctx, args, listU, listVersions, *listRetracted) mode |= modload.ListRetracted
}
rmods, err := modload.ListModules(ctx, args, mode)
if err != nil && !*listE { if err != nil && !*listE {
base.Errorf("go list -retracted: %v", err) base.Errorf("go list -retracted: %v", err)
} }

View File

@ -132,12 +132,9 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
} }
var mods []*moduleJSON var mods []*moduleJSON
listU := false
listVersions := false
listRetractions := false
type token struct{} type token struct{}
sem := make(chan token, runtime.GOMAXPROCS(0)) sem := make(chan token, runtime.GOMAXPROCS(0))
infos, infosErr := modload.ListModules(ctx, args, listU, listVersions, listRetractions) infos, infosErr := modload.ListModules(ctx, args, 0)
for _, info := range infos { for _, info := range infos {
if info.Replace != nil { if info.Replace != nil {
info = info.Replace info = info.Replace

View File

@ -76,16 +76,13 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
} }
if *whyM { if *whyM {
listU := false
listVersions := false
listRetractions := false
for _, arg := range args { for _, arg := range args {
if strings.Contains(arg, "@") { if strings.Contains(arg, "@") {
base.Fatalf("go mod why: module query not allowed") base.Fatalf("go mod why: module query not allowed")
} }
} }
mods, err := modload.ListModules(ctx, args, listU, listVersions, listRetractions) mods, err := modload.ListModules(ctx, args, 0)
if err != nil { if err != nil {
base.Fatalf("go mod why: %v", err) base.Fatalf("go mod why: %v", err)
} }

View File

@ -60,8 +60,7 @@ func PackageModuleInfo(ctx context.Context, pkgpath string) *modinfo.ModulePubli
} }
rs := LoadModFile(ctx) rs := LoadModFile(ctx)
listRetracted := false return moduleInfo(ctx, rs, m, 0)
return moduleInfo(ctx, rs, m, listRetracted)
} }
func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic { func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
@ -69,10 +68,9 @@ func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
return nil return nil
} }
listRetracted := false
if i := strings.Index(path, "@"); i >= 0 { if i := strings.Index(path, "@"); i >= 0 {
m := module.Version{Path: path[:i], Version: path[i+1:]} m := module.Version{Path: path[:i], Version: path[i+1:]}
return moduleInfo(ctx, nil, m, listRetracted) return moduleInfo(ctx, nil, m, 0)
} }
rs := LoadModFile(ctx) rs := LoadModFile(ctx)
@ -101,7 +99,7 @@ func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
} }
} }
return moduleInfo(ctx, rs, module.Version{Path: path, Version: v}, listRetracted) return moduleInfo(ctx, rs, module.Version{Path: path, Version: v}, 0)
} }
// addUpdate fills in m.Update if an updated version is available. // addUpdate fills in m.Update if an updated version is available.
@ -157,7 +155,7 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
// moduleInfo returns information about module m, loaded from the requirements // moduleInfo returns information about module m, loaded from the requirements
// in rs (which may be nil to indicate that m was not loaded from a requirement // in rs (which may be nil to indicate that m was not loaded from a requirement
// graph). // graph).
func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, listRetracted bool) *modinfo.ModulePublic { func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode ListMode) *modinfo.ModulePublic {
if m == Target { if m == Target {
info := &modinfo.ModulePublic{ info := &modinfo.ModulePublic{
Path: m.Path, Path: m.Path,
@ -226,7 +224,7 @@ func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, listRet
} }
} }
if listRetracted { if mode&ListRetracted != 0 {
addRetraction(ctx, m) addRetraction(ctx, m)
} }
} }

View File

@ -20,27 +20,36 @@ import (
"golang.org/x/mod/module" "golang.org/x/mod/module"
) )
type ListMode int
const (
ListU ListMode = 1 << iota
ListRetracted
ListVersions
ListRetractedVersions
)
// ListModules returns a description of the modules matching args, if known, // ListModules returns a description of the modules matching args, if known,
// along with any error preventing additional matches from being identified. // along with any error preventing additional matches from being identified.
// //
// The returned slice can be nonempty even if the error is non-nil. // The returned slice can be nonempty even if the error is non-nil.
func ListModules(ctx context.Context, args []string, listU, listVersions, listRetracted bool) ([]*modinfo.ModulePublic, error) { func ListModules(ctx context.Context, args []string, mode ListMode) ([]*modinfo.ModulePublic, error) {
rs, mods, err := listModules(ctx, LoadModFile(ctx), args, listVersions, listRetracted) rs, mods, err := listModules(ctx, LoadModFile(ctx), args, mode)
type token struct{} type token struct{}
sem := make(chan token, runtime.GOMAXPROCS(0)) sem := make(chan token, runtime.GOMAXPROCS(0))
if listU || listVersions || listRetracted { if mode != 0 {
for _, m := range mods { for _, m := range mods {
add := func(m *modinfo.ModulePublic) { add := func(m *modinfo.ModulePublic) {
sem <- token{} sem <- token{}
go func() { go func() {
if listU { if mode&ListU != 0 {
addUpdate(ctx, m) addUpdate(ctx, m)
} }
if listVersions { if mode&ListVersions != 0 {
addVersions(ctx, m, listRetracted) addVersions(ctx, m, mode&ListRetractedVersions != 0)
} }
if listRetracted || listU { if mode&ListRetracted != 0 {
addRetraction(ctx, m) addRetraction(ctx, m)
} }
<-sem <-sem
@ -64,7 +73,7 @@ func ListModules(ctx context.Context, args []string, listU, listVersions, listRe
return mods, err return mods, err
} }
func listModules(ctx context.Context, rs *Requirements, args []string, listVersions, listRetracted bool) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error) { func listModules(ctx context.Context, rs *Requirements, args []string, mode ListMode) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error) {
var mg *ModuleGraph var mg *ModuleGraph
if go117LazyTODO { if go117LazyTODO {
// Pull the args-loop below into another (new) loop. // Pull the args-loop below into another (new) loop.
@ -78,7 +87,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
} }
if len(args) == 0 { if len(args) == 0 {
return rs, []*modinfo.ModulePublic{moduleInfo(ctx, rs, Target, listRetracted)}, mgErr return rs, []*modinfo.ModulePublic{moduleInfo(ctx, rs, Target, mode)}, mgErr
} }
matchedModule := map[module.Version]bool{} matchedModule := map[module.Version]bool{}
@ -93,7 +102,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
if arg == "all" || strings.Contains(arg, "...") { if arg == "all" || strings.Contains(arg, "...") {
base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot) base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot)
} }
if !listVersions && !strings.Contains(arg, "@") { if mode&ListVersions == 0 && !strings.Contains(arg, "@") {
base.Fatalf("go: cannot match %q without -versions or an explicit version: %v", arg, ErrNoModRoot) base.Fatalf("go: cannot match %q without -versions or an explicit version: %v", arg, ErrNoModRoot)
} }
} }
@ -112,7 +121,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
} }
allowed := CheckAllowed allowed := CheckAllowed
if IsRevisionQuery(vers) || listRetracted { if IsRevisionQuery(vers) || mode&ListRetracted != 0 {
// Allow excluded and retracted versions if the user asked for a // Allow excluded and retracted versions if the user asked for a
// specific revision or used 'go list -retracted'. // specific revision or used 'go list -retracted'.
allowed = nil allowed = nil
@ -131,7 +140,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
// *Requirements instead. // *Requirements instead.
var noRS *Requirements var noRS *Requirements
mod := moduleInfo(ctx, noRS, module.Version{Path: path, Version: info.Version}, listRetracted) mod := moduleInfo(ctx, noRS, module.Version{Path: path, Version: info.Version}, mode)
mods = append(mods, mod) mods = append(mods, mod)
continue continue
} }
@ -153,7 +162,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
continue continue
} }
if v != "none" { if v != "none" {
mods = append(mods, moduleInfo(ctx, rs, module.Version{Path: arg, Version: v}, listRetracted)) mods = append(mods, moduleInfo(ctx, rs, module.Version{Path: arg, Version: v}, mode))
} else if cfg.BuildMod == "vendor" { } else if cfg.BuildMod == "vendor" {
// In vendor mode, we can't determine whether a missing module is “a // In vendor mode, we can't determine whether a missing module is “a
// known dependency” because the module graph is incomplete. // known dependency” because the module graph is incomplete.
@ -162,7 +171,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
Path: arg, Path: arg,
Error: modinfoError(arg, "", errors.New("can't resolve module using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)")), Error: modinfoError(arg, "", errors.New("can't resolve module using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)")),
}) })
} else if listVersions { } else if mode&ListVersions != 0 {
// Don't make the user provide an explicit '@latest' when they're // Don't make the user provide an explicit '@latest' when they're
// explicitly asking what the available versions are. Instead, return a // explicitly asking what the available versions are. Instead, return a
// module with version "none", to which we can add the requested list. // module with version "none", to which we can add the requested list.
@ -182,7 +191,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, listVersi
matched = true matched = true
if !matchedModule[m] { if !matchedModule[m] {
matchedModule[m] = true matchedModule[m] = true
mods = append(mods, moduleInfo(ctx, rs, m, listRetracted)) mods = append(mods, moduleInfo(ctx, rs, m, mode))
} }
} }
} }