]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: convert semver tags with metadata to pseudoversions
authorBryan C. Mills <bcmills@google.com>
Mon, 13 May 2019 15:22:32 +0000 (11:22 -0400)
committerBryan C. Mills <bcmills@google.com>
Tue, 14 May 2019 14:29:59 +0000 (14:29 +0000)
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 <bcmills@google.com>
Reviewed-by: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

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

index cd0d9b17c5cc7928e54851f8dfdeebecca56b129..f0f67c193cd016b891b2962739f5f5b2b4bc74e5 100644 (file)
@@ -31,7 +31,7 @@ import (
 //     - <v1.2.3, <=v1.2.3, >v1.2.3, >=v1.2.3,
 //        denoting the version closest to the target and satisfying the given operator,
 //        with non-prereleases preferred over prereleases.
-//     - a repository commit identifier, denoting that commit.
+//     - a repository commit identifier or tag, denoting that commit.
 //
 // If the allowed function is non-nil, Query excludes any versions for which allowed returns false.
 //
@@ -106,18 +106,24 @@ func Query(path, query string, allowed func(module.Version) bool) (*modfetch.Rev
                }
                prefix = query + "."
 
-       case semver.IsValid(query):
-               vers := module.CanonicalVersion(query)
-               if !allowed(module.Version{Path: path, Version: vers}) {
-                       return nil, fmt.Errorf("%s@%s excluded", path, vers)
-               }
-               return modfetch.Stat(path, vers)
-
        default:
                // Direct lookup of semantic version or commit identifier.
+               //
+               // If the identifier is not a canonical semver tag — including if it's a
+               // semver tag with a +metadata suffix — then modfetch.Stat will populate
+               // info.Version with a suitable pseudo-version.
                info, err := modfetch.Stat(path, query)
                if err != nil {
-                       return nil, err
+                       queryErr := err
+                       // The full query doesn't correspond to a tag. If it is a semantic version
+                       // with a +metadata suffix, see if there is a tag without that suffix:
+                       // semantic versioning defines them to be equivalent.
+                       if vers := module.CanonicalVersion(query); vers != "" && vers != query {
+                               info, err = modfetch.Stat(path, vers)
+                       }
+                       if err != nil {
+                               return nil, queryErr
+                       }
                }
                if !allowed(module.Version{Path: path, Version: info.Version}) {
                        return nil, fmt.Errorf("%s@%s excluded", path, info.Version)
index 17e23ad12ae048042287a15460bd93bdbc973c66..d2b9baa4d56ef364d1939ee8bc8b5f66cd0b44e5 100644 (file)
@@ -62,7 +62,7 @@ var queryTests = []struct {
                git add go.mod
                git commit -m v1 go.mod
                git tag start
-               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
+               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
                        echo before $i >status
                        git add status
                        git commit -m "before $i" status
@@ -104,6 +104,9 @@ var queryTests = []struct {
        {path: queryRepo, query: "v0.1", vers: "v0.1.2"},
        {path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`},
        {path: queryRepo, query: "v0.0", vers: "v0.0.3"},
+       {path: queryRepo, query: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
+       {path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `unknown revision v1.9.10-pre2+wrongmetadata`},
+       {path: queryRepo, query: "v1.9.10-pre2", err: `unknown revision v1.9.10-pre2`},
        {path: queryRepo, query: "latest", vers: "v1.9.9"},
        {path: queryRepo, query: "latest", allow: "NOMATCH", err: `no matching versions for query "latest"`},
        {path: queryRepo, query: ">v1.9.9", vers: "v1.9.10-pre1"},