cmd/gorelease: allow -base to be a different major version

gorelease already allows comparing different modules, and major
versions are technically distinct modules, but it's inconvenient to
write the full module path with -base on the command line.

With this change, for example, when checking example.com/mod/v2, the
user can now write -base=v1.9.0 instead of -base=example.com/mod@v1.9.0.

Fixes golang/go#40913

Change-Id: I077a8b75d6d3cab8156716094ce5eaed3e043e88
Reviewed-on: https://go-review.googlesource.com/c/exp/+/323856
Trust: Jay Conrod <jayconrod@google.com>
Trust: Jean de Klerk <deklerk@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jean de Klerk <deklerk@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jean de Klerk <deklerk@google.com>
diff --git a/cmd/gorelease/gorelease.go b/cmd/gorelease/gorelease.go
index 9ab8f12..fffb42d 100644
--- a/cmd/gorelease/gorelease.go
+++ b/cmd/gorelease/gorelease.go
@@ -223,8 +223,24 @@
 	// the module cache.
 	var max string
 	if baseModPath == "" {
-		baseModPath = release.modPath
-		max = releaseVersion
+		if baseVersion != "" && semver.Canonical(baseVersion) == baseVersion && module.Check(release.modPath, baseVersion) != nil {
+			// Base version was specified, but it's not consistent with the release
+			// module path, for example, the module path is example.com/m/v2, but
+			// the user said -base=v1.0.0. Instead of making the user explicitly
+			// specify the base module path, we'll adjust the major version suffix.
+			prefix, _, _ := module.SplitPathVersion(release.modPath)
+			major := semver.Major(baseVersion)
+			if strings.HasPrefix(prefix, "gopkg.in/") {
+				baseModPath = prefix + "." + semver.Major(baseVersion)
+			} else if major >= "v2" {
+				baseModPath = prefix + "/" + major
+			} else {
+				baseModPath = prefix
+			}
+		} else {
+			baseModPath = release.modPath
+			max = releaseVersion
+		}
 	}
 	base, err := loadDownloadedModule(ctx, baseModPath, baseVersion, max)
 	if err != nil {
diff --git a/cmd/gorelease/testdata/basic/v1_v2_base_version_suggest.test b/cmd/gorelease/testdata/basic/v1_v2_base_version_suggest.test
new file mode 100644
index 0000000..cde8731
--- /dev/null
+++ b/cmd/gorelease/testdata/basic/v1_v2_base_version_suggest.test
@@ -0,0 +1,7 @@
+mod=example.com/basic/v2
+base=v1.1.0
+version=v2.1.0
+success=false
+-- want --
+Cannot suggest a release version.
+Base module path is different from release.
diff --git a/cmd/gorelease/testdata/basic/v1_v2_base_version_verify.test b/cmd/gorelease/testdata/basic/v1_v2_base_version_verify.test
new file mode 100644
index 0000000..3099cfd
--- /dev/null
+++ b/cmd/gorelease/testdata/basic/v1_v2_base_version_verify.test
@@ -0,0 +1,6 @@
+mod=example.com/basic/v2
+base=v1.1.0
+version=v2.1.0
+release=v2.1.0
+-- want --
+v2.1.0 is a valid semantic version for this release.
diff --git a/cmd/gorelease/testdata/basic/v1_v2_incompatible_verify_suffix.test b/cmd/gorelease/testdata/basic/v1_v2_incompatible_verify_suffix.test
deleted file mode 100644
index 9d6a303..0000000
--- a/cmd/gorelease/testdata/basic/v1_v2_incompatible_verify_suffix.test
+++ /dev/null
@@ -1,7 +0,0 @@
-mod=example.com/basic/v2
-version=v2.1.2
-base=v1.1.1
-release=v2.0.0
-error=1
--- want --
-can't compare major versions: base version v1.1.1 does not belong to module example.com/basic/v2