Commit 19690053 authored by Bryan C. Mills's avatar Bryan C. Mills

cmd/go/internal/modfetch: filter pseudo-versions from proxy /list endpoints

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: default avatarJay Conrod <jayconrod@google.com>
parent e28f0d92
......@@ -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) {
......
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
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
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
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"
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment