]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modfetch: filter pseudo-versions from proxy /list endpoints
authorBryan C. Mills <bcmills@google.com>
Fri, 21 Jun 2019 19:13:10 +0000 (15:13 -0400)
committerBryan C. Mills <bcmills@google.com>
Tue, 25 Jun 2019 13:27:20 +0000 (13:27 +0000)
The /list files in the module cache include pseudo-versions, but the
documentation for (*modfetch).Repo.Versions explicitly states that
they are not included in the output of that method.

Fixes #32715

Change-Id: Ieba1500b91f52b5fa689e70e16dbe3ad40de20f7
Reviewed-on: https://go-review.googlesource.com/c/go/+/183402
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
src/cmd/go/internal/modfetch/proxy.go
src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt [new file with mode: 0644]
src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt [new file with mode: 0644]
src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt [new file with mode: 0644]
src/cmd/go/testdata/script/mod_list_pseudo.txt [new file with mode: 0644]

index 6235ad3d6ec78ac4551967a9c79368b2534dc164..6049ccfd30a5bc26abf6140173e71aabbeb84d09 100644 (file)
@@ -251,7 +251,7 @@ func (p *proxyRepo) Versions(prefix string) ([]string, error) {
        var list []string
        for _, line := range strings.Split(string(data), "\n") {
                f := strings.Fields(line)
-               if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) {
+               if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !IsPseudoVersion(f[0]) {
                        list = append(list, f[0])
                }
        }
@@ -264,14 +264,36 @@ func (p *proxyRepo) latest() (*RevInfo, error) {
        if err != nil {
                return nil, p.versionError("", err)
        }
-       var best time.Time
-       var bestVersion string
+
+       var (
+               bestTime             time.Time
+               bestTimeIsFromPseudo bool
+               bestVersion          string
+       )
+
        for _, line := range strings.Split(string(data), "\n") {
                f := strings.Fields(line)
-               if len(f) >= 2 && semver.IsValid(f[0]) {
-                       ft, err := time.Parse(time.RFC3339, f[1])
-                       if err == nil && best.Before(ft) {
-                               best = ft
+               if len(f) >= 1 && semver.IsValid(f[0]) {
+                       // If the proxy includes timestamps, prefer the timestamp it reports.
+                       // Otherwise, derive the timestamp from the pseudo-version.
+                       var (
+                               ft             time.Time
+                               ftIsFromPseudo = false
+                       )
+                       if len(f) >= 2 {
+                               ft, _ = time.Parse(time.RFC3339, f[1])
+                       } else if IsPseudoVersion(f[0]) {
+                               ft, _ = PseudoVersionTime(f[0])
+                               ftIsFromPseudo = true
+                       } else {
+                               // Repo.Latest promises that this method is only called where there are
+                               // no tagged versions. Ignore any tagged versions that were added in the
+                               // meantime.
+                               continue
+                       }
+                       if bestTime.Before(ft) {
+                               bestTime = ft
+                               bestTimeIsFromPseudo = ftIsFromPseudo
                                bestVersion = f[0]
                        }
                }
@@ -279,13 +301,23 @@ func (p *proxyRepo) latest() (*RevInfo, error) {
        if bestVersion == "" {
                return nil, p.versionError("", codehost.ErrNoCommits)
        }
-       info := &RevInfo{
+
+       if bestTimeIsFromPseudo {
+               // We parsed bestTime from the pseudo-version, but that's in UTC and we're
+               // supposed to report the timestamp as reported by the VCS.
+               // Stat the selected version to canonicalize the timestamp.
+               //
+               // TODO(bcmills): Should we also stat other versions to ensure that we
+               // report the correct Name and Short for the revision?
+               return p.Stat(bestVersion)
+       }
+
+       return &RevInfo{
                Version: bestVersion,
                Name:    bestVersion,
                Short:   bestVersion,
-               Time:    best,
-       }
-       return info, nil
+               Time:    bestTime,
+       }, nil
 }
 
 func (p *proxyRepo) Stat(rev string) (*RevInfo, error) {
diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt
new file mode 100644 (file)
index 0000000..c2709c1
--- /dev/null
@@ -0,0 +1,10 @@
+module github.com/dmitshur-test/modtest5@v0.0.0-20190619020302-197a620e0c9a
+
+-- .mod --
+module github.com/dmitshur-test/modtest5
+-- .info --
+{"Version":"v0.0.0-20190619020302-197a620e0c9a","Time":"2019-06-18T19:03:02-07:00"}
+-- p.go --
+package p
+
+const v = 1
diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt
new file mode 100644 (file)
index 0000000..22e47f3
--- /dev/null
@@ -0,0 +1,10 @@
+module github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e
+
+-- .mod --
+module github.com/dmitshur-test/modtest5
+-- .info --
+{"Version":"v0.5.0-alpha.0.20190619023908-3da23a9deb9e","Time":"2019-06-18T19:39:08-07:00"}
+-- p.go --
+package p
+
+const v = 3
diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt
new file mode 100644 (file)
index 0000000..4f088cc
--- /dev/null
@@ -0,0 +1,10 @@
+module github.com/dmitshur-test/modtest5@v0.5.0-alpha
+
+-- .mod --
+module github.com/dmitshur-test/modtest5
+-- .info --
+{"Version":"v0.5.0-alpha","Time":"2019-06-18T19:04:46-07:00"}
+-- p.go --
+package p
+
+const v = 2
diff --git a/src/cmd/go/testdata/script/mod_list_pseudo.txt b/src/cmd/go/testdata/script/mod_list_pseudo.txt
new file mode 100644 (file)
index 0000000..3a10b3a
--- /dev/null
@@ -0,0 +1,50 @@
+env GO111MODULE=on
+
+# Regression test for golang.org/issue/32715.
+
+# When using $GOPATH/pkg/mod/cache/download as a proxy,
+# 'latest' queries should prefer tagged versions over pseudo-versions.
+
+go mod download github.com/dmitshur-test/modtest5@v0.0.0-20190619020302-197a620e0c9a
+go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha
+go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e
+cmp $GOPATH/pkg/mod/cache/download/github.com/dmitshur-test/modtest5/@v/list $WORK/modtest5.list
+
+env GOPROXY=file:///$GOPATH/pkg/mod/cache/download
+env GOPATH=$WORK/gopath2
+mkdir $GOPATH
+
+go list -m -json github.com/dmitshur-test/modtest5@latest
+cmp stdout $WORK/modtest5.json
+
+# If the module proxy contains only pseudo-versions, 'latest' should stat
+# the version with the most recent timestamp — not the highest semantic
+# version — and return its metadata.
+env GOPROXY=file:///$WORK/tinyproxy
+go list -m -json dmitri.shuralyov.com/test/modtest3@latest
+cmp stdout $WORK/modtest3.json
+
+-- $WORK/modtest5.list --
+v0.0.0-20190619020302-197a620e0c9a
+v0.5.0-alpha
+v0.5.0-alpha.0.20190619023908-3da23a9deb9e
+-- $WORK/modtest5.json --
+{
+       "Path": "github.com/dmitshur-test/modtest5",
+       "Version": "v0.5.0-alpha",
+       "Time": "2019-06-18T19:04:46-07:00"
+}
+-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/list --
+v0.1.0-0.20161023043300-000000000000
+v0.0.0-20181023043359-a85b471d5412
+-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/v0.0.0-20181023043359-a85b471d5412.info --
+{
+       "Version": "v0.0.0-20181023043359-a85b471d5412",
+       "Time": "2018-10-22T21:33:59-07:00"
+}
+-- $WORK/modtest3.json --
+{
+       "Path": "dmitri.shuralyov.com/test/modtest3",
+       "Version": "v0.0.0-20181023043359-a85b471d5412",
+       "Time": "2018-10-22T21:33:59-07:00"
+}