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])
}
}
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]
}
}
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) {
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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"
+}