Skip to content

Commit aad2336

Browse files
author
Bryan C. Mills
committed
cmd/go: convert semver tags with metadata to pseudoversions
Some repositories include tags like 'v1.0.0-rc.1+oryOS.9'. If we were to allow such tags, they could become ambiguous: semantic versioning defines versions that differ only in metadata to have equal precedence, so if someone added a tag 'v1.0.0-rc.1+other' at a different commit, then the version 'v1.0.0-rc.1' would become ambiguous. However, we should still allow those tags to be used to resolve versions, and since we can even parse the underlying semantic version, we can at least use that as the basis for a unique (and well-ordered) pseudo-version. Fixes #31713 Change-Id: I5035f76d74ead6e786c04a368595cb5e42d36f91 Reviewed-on: https://go-review.googlesource.com/c/go/+/176905 Run-TryBot: Bryan C. Mills <[email protected]> Reviewed-by: Jay Conrod <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 9892cd6 commit aad2336

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

src/cmd/go/internal/modload/query.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
// - <v1.2.3, <=v1.2.3, >v1.2.3, >=v1.2.3,
3232
// denoting the version closest to the target and satisfying the given operator,
3333
// with non-prereleases preferred over prereleases.
34-
// - a repository commit identifier, denoting that commit.
34+
// - a repository commit identifier or tag, denoting that commit.
3535
//
3636
// If the allowed function is non-nil, Query excludes any versions for which allowed returns false.
3737
//
@@ -106,18 +106,24 @@ func Query(path, query string, allowed func(module.Version) bool) (*modfetch.Rev
106106
}
107107
prefix = query + "."
108108

109-
case semver.IsValid(query):
110-
vers := module.CanonicalVersion(query)
111-
if !allowed(module.Version{Path: path, Version: vers}) {
112-
return nil, fmt.Errorf("%s@%s excluded", path, vers)
113-
}
114-
return modfetch.Stat(path, vers)
115-
116109
default:
117110
// Direct lookup of semantic version or commit identifier.
111+
//
112+
// If the identifier is not a canonical semver tag — including if it's a
113+
// semver tag with a +metadata suffix — then modfetch.Stat will populate
114+
// info.Version with a suitable pseudo-version.
118115
info, err := modfetch.Stat(path, query)
119116
if err != nil {
120-
return nil, err
117+
queryErr := err
118+
// The full query doesn't correspond to a tag. If it is a semantic version
119+
// with a +metadata suffix, see if there is a tag without that suffix:
120+
// semantic versioning defines them to be equivalent.
121+
if vers := module.CanonicalVersion(query); vers != "" && vers != query {
122+
info, err = modfetch.Stat(path, vers)
123+
}
124+
if err != nil {
125+
return nil, queryErr
126+
}
121127
}
122128
if !allowed(module.Version{Path: path, Version: info.Version}) {
123129
return nil, fmt.Errorf("%s@%s excluded", path, info.Version)

src/cmd/go/internal/modload/query_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ var queryTests = []struct {
6262
git add go.mod
6363
git commit -m v1 go.mod
6464
git tag start
65-
for i in v0.0.0-pre1 v0.0.0 v0.0.1 v0.0.2 v0.0.3 v0.1.0 v0.1.1 v0.1.2 v0.3.0 v1.0.0 v1.1.0 v1.9.0 v1.9.9 v1.9.10-pre1; do
65+
for i in v0.0.0-pre1 v0.0.0 v0.0.1 v0.0.2 v0.0.3 v0.1.0 v0.1.1 v0.1.2 v0.3.0 v1.0.0 v1.1.0 v1.9.0 v1.9.9 v1.9.10-pre1 v1.9.10-pre2+metadata; do
6666
echo before $i >status
6767
git add status
6868
git commit -m "before $i" status
@@ -104,6 +104,9 @@ var queryTests = []struct {
104104
{path: queryRepo, query: "v0.1", vers: "v0.1.2"},
105105
{path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`},
106106
{path: queryRepo, query: "v0.0", vers: "v0.0.3"},
107+
{path: queryRepo, query: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
108+
{path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `unknown revision v1.9.10-pre2+wrongmetadata`},
109+
{path: queryRepo, query: "v1.9.10-pre2", err: `unknown revision v1.9.10-pre2`},
107110
{path: queryRepo, query: "latest", vers: "v1.9.9"},
108111
{path: queryRepo, query: "latest", allow: "NOMATCH", err: `no matching versions for query "latest"`},
109112
{path: queryRepo, query: ">v1.9.9", vers: "v1.9.10-pre1"},

0 commit comments

Comments
 (0)