cmd/go/internal/mvs: fix get module@version ignoring @version

Fix vgo ignoring the version when it was resolved to v0.0.0-...
and go.mod file contained a higher version, e.g., v1.2.3.

Fix golang/go#25542

Change-Id: Ic6ade40c32ecd326cd9f47805f47b99a335a475c
Reviewed-on: https://go-review.googlesource.com/114735
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/vendor/cmd/go/internal/mvs/mvs.go b/vendor/cmd/go/internal/mvs/mvs.go
index 8936186..c30ac46 100644
--- a/vendor/cmd/go/internal/mvs/mvs.go
+++ b/vendor/cmd/go/internal/mvs/mvs.go
@@ -275,6 +275,13 @@
 			if err != nil {
 				return nil, err // TODO
 			}
+			// If the target version is a pseudo-version, it may not be
+			// included when iterating over prior versions using reqs.Previous.
+			// Insert it into the right place in the iteration.
+			// If v is excluded, p should be returned again by reqs.Previous on the next iteration.
+			if v := max[r.Path]; reqs.Max(v, r.Version) != v && reqs.Max(p.Version, v) != p.Version {
+				p.Version = v
+			}
 			if p.Version == "none" {
 				continue List
 			}
diff --git a/vendor/cmd/go/internal/mvs/mvs_test.go b/vendor/cmd/go/internal/mvs/mvs_test.go
index 3f547f4..717964c 100644
--- a/vendor/cmd/go/internal/mvs/mvs_test.go
+++ b/vendor/cmd/go/internal/mvs/mvs_test.go
@@ -178,6 +178,27 @@
 
 name: down3
 A: 
+
+# golang.org/issue/25542.
+name: noprev1
+A: B4 C2
+B2.hidden: 
+C2: 
+downgrade A B2.hidden: A B2.hidden C2
+
+name: noprev2
+A: B4 C2
+B2.hidden: 
+B1: 
+C2: 
+downgrade A B2.hidden: A B2.hidden C2
+
+name: noprev3
+A: B4 C2
+B3: 
+B2.hidden: 
+C2: 
+downgrade A B2.hidden: A B2.hidden C2
 `
 
 func Test(t *testing.T) {
@@ -309,6 +330,12 @@
 type reqsMap map[module.Version][]module.Version
 
 func (r reqsMap) Max(v1, v2 string) string {
+	if v1 == "none" {
+		return v2
+	}
+	if v2 == "none" {
+		return v1
+	}
 	if v1 < v2 {
 		return v2
 	}
@@ -331,7 +358,7 @@
 func (r reqsMap) Previous(m module.Version) (module.Version, error) {
 	var p module.Version
 	for k := range r {
-		if k.Path == m.Path && p.Version < k.Version && k.Version < m.Version {
+		if k.Path == m.Path && p.Version < k.Version && k.Version < m.Version && !strings.HasSuffix(k.Version, ".hidden") {
 			p = k
 		}
 	}
diff --git a/vendor/cmd/go/vgo_test.go b/vendor/cmd/go/vgo_test.go
index 91e3527..6d7032a 100644
--- a/vendor/cmd/go/vgo_test.go
+++ b/vendor/cmd/go/vgo_test.go
@@ -166,6 +166,45 @@
 	tg.grepStdoutNot(`^m/y/z`, "should ignore submodule m/y/z...")
 }
 
+func TestGetModuleVersion(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+
+	tg.setenv(homeEnvName(), tg.path("home"))
+	tg.must(os.MkdirAll(tg.path("x"), 0777))
+	tg.cd(tg.path("x"))
+	tg.must(ioutil.WriteFile(tg.path("x/x.go"), []byte(`package x`), 0666))
+
+	tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
+		module x
+		require github.com/gobuffalo/uuid v1.1.0
+	`), 0666))
+	tg.run("-vgo", "get", "github.com/gobuffalo/uuid@v2.0.0")
+	tg.run("-vgo", "list", "-m")
+	tg.grepStdout("github.com/gobuffalo/uuid.*v0.0.0-20180207211247-3a9fb6c5c481", "did downgrade to v0.0.0-*")
+
+	tooSlow(t)
+
+	tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
+		module x
+		require github.com/gobuffalo/uuid v1.2.0
+	`), 0666))
+	tg.run("-vgo", "get", "github.com/gobuffalo/uuid@v1.1.0")
+	tg.run("-vgo", "list", "-m")
+	tg.grepStdout("github.com/gobuffalo/uuid.*v1.1.0", "did downgrade to v1.1.0")
+
+	tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
+		module x
+		require github.com/gobuffalo/uuid v1.1.0
+	`), 0666))
+	tg.run("-vgo", "get", "github.com/gobuffalo/uuid@v1.2.0")
+	tg.run("-vgo", "list", "-m")
+	tg.grepStdout("github.com/gobuffalo/uuid.*v1.2.0", "did upgrade to v1.2.0")
+}
+
 func TestVgoBadDomain(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()