Skip to content

Commit

Permalink
cmd/go/internal/modfetch: filter pseudo-versions from proxy /list end…
Browse files Browse the repository at this point in the history
…points

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 <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Jay Conrod <[email protected]>
  • Loading branch information
Bryan C. Mills committed Jun 25, 2019
1 parent e28f0d9 commit 1969005
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 11 deletions.
54 changes: 43 additions & 11 deletions src/cmd/go/internal/modfetch/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
}
Expand All @@ -264,28 +264,60 @@ 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]
}
}
}
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/dmitshur-test/[email protected]

-- .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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/dmitshur-test/[email protected]

-- .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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/dmitshur-test/[email protected]

-- .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
50 changes: 50 additions & 0 deletions src/cmd/go/testdata/script/mod_list_pseudo.txt
Original file line number Diff line number Diff line change
@@ -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/[email protected]
go mod download github.com/dmitshur-test/[email protected]
go mod download github.com/dmitshur-test/[email protected]
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"
}

0 comments on commit 1969005

Please sign in to comment.