1
0
mirror of https://github.com/golang/go synced 2024-09-29 03:34:33 -06:00

cmd/go: convert semver.IsValid to gover.ModIsValid

Change-Id: Id584c4bd6d1c12fd085414188bc7e7ca08164c04
Reviewed-on: https://go-review.googlesource.com/c/go/+/497416
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
Russ Cox 2023-05-23 10:29:47 -04:00
parent ef23bd11a8
commit 8366497625
7 changed files with 44 additions and 40 deletions

View File

@ -88,3 +88,25 @@ func untoolchain(x string) string {
}
return x
}
// ModIsPrefix reports whether v is a valid version syntax prefix for the module with the given path.
// The caller is assumed to have checked that ModIsValid(path, vers) is true.
func ModIsPrefix(path, vers string) bool {
if IsToolchain(path) {
return IsLang(vers)
}
// Semver
dots := 0
for i := 0; i < len(vers); i++ {
switch vers[i] {
case '-', '+':
return false
case '.':
dots++
if dots >= 2 {
return false
}
}
}
return true
}

View File

@ -3231,9 +3231,10 @@ func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args
// Check that the arguments satisfy syntactic constraints.
var version string
var firstPath string
for _, arg := range args {
if i := strings.Index(arg, "@"); i >= 0 {
version = arg[i+1:]
firstPath, version = arg[:i], arg[i+1:]
if version == "" {
return nil, fmt.Errorf("%s: version must not be empty", arg)
}
@ -3271,7 +3272,7 @@ func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args
// later arguments, and other modules would. Let's not try to be too
// magical though.
allowed := modload.CheckAllowed
if modload.IsRevisionQuery(version) {
if modload.IsRevisionQuery(firstPath, version) {
// Don't check for retractions if a specific revision is requested.
allowed = nil
}

View File

@ -50,7 +50,7 @@ func CachePath(ctx context.Context, m module.Version, suffix string) (string, er
if err != nil {
return "", err
}
if !semver.IsValid(m.Version) {
if !gover.ModIsValid(m.Path, m.Version) {
return "", fmt.Errorf("non-semver module version %q", m.Version)
}
if module.CanonicalVersion(m.Version) != m.Version {
@ -79,7 +79,7 @@ func DownloadDir(ctx context.Context, m module.Version) (string, error) {
if err != nil {
return "", err
}
if !semver.IsValid(m.Version) {
if !gover.ModIsValid(m.Path, m.Version) {
return "", fmt.Errorf("non-semver module version %q", m.Version)
}
if module.CanonicalVersion(m.Version) != m.Version {
@ -334,7 +334,7 @@ func (r *cachingRepo) Zip(ctx context.Context, dst io.Writer, version string) er
// InfoFile is like Lookup(ctx, path).Stat(version) but also returns the name of the file
// containing the cached information.
func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, error) {
if !semver.IsValid(version) {
if !gover.ModIsValid(path, version) {
return nil, "", fmt.Errorf("invalid version %q", version)
}
@ -374,7 +374,7 @@ func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, erro
func GoMod(ctx context.Context, path, rev string) ([]byte, error) {
// Convert commit hash to pseudo-version
// to increase cache hit rate.
if !semver.IsValid(rev) {
if !gover.ModIsValid(path, rev) {
if _, info, err := readDiskStat(ctx, path, rev); err == nil {
rev = info.Version
} else {
@ -409,7 +409,7 @@ func GoMod(ctx context.Context, path, rev string) ([]byte, error) {
// GoModFile is like GoMod but returns the name of the file containing
// the cached information.
func GoModFile(ctx context.Context, path, version string) (string, error) {
if !semver.IsValid(version) {
if !gover.ModIsValid(path, version) {
return "", fmt.Errorf("invalid version %q", version)
}
if _, err := GoMod(ctx, path, version); err != nil {
@ -426,7 +426,7 @@ func GoModFile(ctx context.Context, path, version string) (string, error) {
// GoModSum returns the go.sum entry for the module version's go.mod file.
// (That is, it returns the entry listed in go.sum as "path version/go.mod".)
func GoModSum(ctx context.Context, path, version string) (string, error) {
if !semver.IsValid(version) {
if !gover.ModIsValid(path, version) {
return "", fmt.Errorf("invalid version %q", version)
}
data, err := GoMod(ctx, path, version)

View File

@ -183,7 +183,7 @@ func listModules(ctx context.Context, rs *Requirements, args []string, mode List
}
allowed := CheckAllowed
if IsRevisionQuery(vers) || mode&ListRetracted != 0 {
if IsRevisionQuery(path, vers) || mode&ListRetracted != 0 {
// Allow excluded and retracted versions if the user asked for a
// specific revision or used 'go list -retracted'.
allowed = nil

View File

@ -25,7 +25,6 @@ import (
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
)
const (
@ -762,7 +761,7 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) {
return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err))
}
} else {
if !semver.IsValid(m.Version) {
if !gover.ModIsValid(m.Path, m.Version) {
// Disallow the broader queries supported by fetch.Lookup.
base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
}

View File

@ -60,7 +60,7 @@ func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
return summary.require, nil
}
// Max returns the maximum of v1 and v2 according to semver.Compare.
// Max returns the maximum of v1 and v2 according to gover.ModCompare.
//
// As a special case, the version "" is considered higher than all other
// versions. The main module (also known as the target) has no version and must

View File

@ -324,36 +324,18 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
// a particular version or revision in a repository like "v1.0.0", "master",
// or "0123abcd". IsRevisionQuery returns false if vers is a query that
// chooses from among available versions like "latest" or ">v1.0.0".
func IsRevisionQuery(vers string) bool {
func IsRevisionQuery(path, vers string) bool {
if vers == "latest" ||
vers == "upgrade" ||
vers == "patch" ||
strings.HasPrefix(vers, "<") ||
strings.HasPrefix(vers, ">") ||
(semver.IsValid(vers) && isSemverPrefix(vers)) {
(gover.ModIsValid(path, vers) && gover.ModIsPrefix(path, vers)) {
return false
}
return true
}
// isSemverPrefix reports whether v is a semantic version prefix: v1 or v1.2 (not v1.2.3).
// The caller is assumed to have checked that semver.IsValid(v) is true.
func isSemverPrefix(v string) bool {
dots := 0
for i := 0; i < len(v); i++ {
switch v[i] {
case '-', '+':
return false
case '.':
dots++
if dots >= 2 {
return false
}
}
}
return true
}
type queryMatcher struct {
path string
prefix string
@ -417,10 +399,10 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
case strings.HasPrefix(query, "<="):
v := query[len("<="):]
if !semver.IsValid(v) {
if !gover.ModIsValid(path, v) {
return badVersion(v)
}
if isSemverPrefix(v) {
if gover.ModIsPrefix(path, v) {
// Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3).
return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query)
}
@ -431,7 +413,7 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
case strings.HasPrefix(query, "<"):
v := query[len("<"):]
if !semver.IsValid(v) {
if !gover.ModIsValid(path, v) {
return badVersion(v)
}
qm.filter = func(mv string) bool { return gover.ModCompare(qm.path, mv, v) < 0 }
@ -441,7 +423,7 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
case strings.HasPrefix(query, ">="):
v := query[len(">="):]
if !semver.IsValid(v) {
if !gover.ModIsValid(path, v) {
return badVersion(v)
}
qm.filter = func(mv string) bool { return gover.ModCompare(qm.path, mv, v) >= 0 }
@ -452,10 +434,10 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
case strings.HasPrefix(query, ">"):
v := query[len(">"):]
if !semver.IsValid(v) {
if !gover.ModIsValid(path, v) {
return badVersion(v)
}
if isSemverPrefix(v) {
if gover.ModIsPrefix(path, v) {
// Refuse to say whether >v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3).
return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query)
}
@ -465,8 +447,8 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
qm.preferIncompatible = true
}
case semver.IsValid(query):
if isSemverPrefix(query) {
case gover.ModIsValid(path, query):
if gover.ModIsPrefix(path, query) {
qm.prefix = query + "."
// Do not allow the query "v1.2" to match versions lower than "v1.2.0",
// such as prereleases for that version. (https://golang.org/issue/31972)