cmd/gorelease: fix test runner, and implementation of existing versions check

Currently, all tests pass because the test runner uses the for-loop-scoped
"test" in multiple parallel tests. This change locally scopes it to the for
block so that each parallel test run has its own "test".

That causes some tests to fail. The primary failure is that existing version
check is happening in loadLocalModule. loadLocalModule uses the release version
(the -version flag), whereas loadDownloadedModule uses the base version. Since
loadLocalModule uses the release version, prepareLoadDir (performed inside both
load* functions) will use the release version for the replace directive, which
means "go list" will report the release version. The existing version check uses
"go list", so it's guaranteed to always fail: the release specified will always
be reported as an existing release!

The change is to move the existing version check to loadDownloadedModule, which
performs "go list" as before but now it's only checking things which already
exist, not which the user is proposing should exist.

Fixes golang/go#45892

Change-Id: I5a9776d6ae1af6718b3c39946945c4bbb108a2fc
Reviewed-on: https://go-review.googlesource.com/c/exp/+/318029
Trust: Jean de Klerk <deklerk@google.com>
Run-TryBot: Jean de Klerk <deklerk@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/cmd/gorelease/gorelease.go b/cmd/gorelease/gorelease.go
index 124ad0d..edf3ed9 100644
--- a/cmd/gorelease/gorelease.go
+++ b/cmd/gorelease/gorelease.go
@@ -411,13 +411,6 @@
 		m.highestTransitiveVersion = highestVersion
 	}
 
-	// Calculate the existing versions.
-	ev, err := existingVersions(ctx, m.modPath, tmpLoadDir)
-	if err != nil {
-		return moduleInfo{}, err
-	}
-	m.existingVersions = ev
-
 	return m, nil
 }
 
@@ -521,6 +514,13 @@
 		return moduleInfo{}, err
 	}
 
+	// Calculate the existing versions.
+	ev, err := existingVersions(ctx, m.modPath, tmpLoadDir)
+	if err != nil {
+		return moduleInfo{}, err
+	}
+	m.existingVersions = ev
+
 	return m, nil
 }
 
diff --git a/cmd/gorelease/gorelease_test.go b/cmd/gorelease/gorelease_test.go
index fca52c1..10c1080 100644
--- a/cmd/gorelease/gorelease_test.go
+++ b/cmd/gorelease/gorelease_test.go
@@ -269,6 +269,7 @@
 	t.Cleanup(cleanup)
 
 	for _, test := range tests {
+		test := test
 		testName := strings.TrimSuffix(strings.TrimPrefix(filepath.ToSlash(test.testPath), "testdata/"), ".test")
 		t.Run(testName, func(t *testing.T) {
 			ctx := defaultContext
diff --git a/cmd/gorelease/report.go b/cmd/gorelease/report.go
index 0dbeca1..c2e8c8f 100644
--- a/cmd/gorelease/report.go
+++ b/cmd/gorelease/report.go
@@ -178,7 +178,7 @@
 		return
 	}
 
-	for _, v := range r.release.existingVersions {
+	for _, v := range r.base.existingVersions {
 		if semver.Compare(v, r.release.version) == 0 {
 			setNotValid("version %s already exists", v)
 		}
@@ -255,7 +255,7 @@
 	// This could happen further up, but we want the more pressing errors above
 	// to take precedence.
 	var latestForBaseMajor string
-	for _, v := range r.release.existingVersions {
+	for _, v := range r.base.existingVersions {
 		if semver.Major(v) != semver.Major(r.base.version) {
 			continue
 		}
diff --git a/cmd/gorelease/testdata/README.md b/cmd/gorelease/testdata/README.md
index 9a3a234..3c4880a 100644
--- a/cmd/gorelease/testdata/README.md
+++ b/cmd/gorelease/testdata/README.md
@@ -45,6 +45,9 @@
   or diagnostics. True by default.
 * `skip`: non-empty if the test should be skipped. The value is a string passed
   to `t.Skip`.
+* `proxyVersions`: empty if the test should include all `mod/` entries in the
+  proxy, or else a comma-separated list of the modpath@version's it should
+  include.
 
 Test archives have a file named `want`, containing the expected output of the
 test. A test will fail if the actual output differs from `want`.
diff --git a/cmd/gorelease/testdata/alreadyexists/alreadyexists_suggest_minor.test b/cmd/gorelease/testdata/alreadyexists/alreadyexists_suggest_minor.test
index cb43f45..f9d8529 100644
--- a/cmd/gorelease/testdata/alreadyexists/alreadyexists_suggest_minor.test
+++ b/cmd/gorelease/testdata/alreadyexists/alreadyexists_suggest_minor.test
@@ -1,7 +1,7 @@
 mod=example.com/basic
 base=v0.0.1
 success=false
-# B() was added, so now it should suggest a new minor version. # But, there's a
+# B() was added, so now it should suggest a new minor version. But, there's a
 # later version that already exists: so it should not try to suggest anything at
 # all.
 -- want --