internal/history: include ".0" in go1.21.0 and onwards

Now that proposal go.dev/issue/57631 is accepted, the upcoming major Go
release version will not omit its trailing zero component in "go1.21.0".
Update the behavior and documentation of Version accordingly.

Drop IsMajor and IsMinor since they would need to be updated but aren't
used anywhere. Instead, add MajorPrefix and use it to not break the
future Go 1.21 release notes link. We decided those release notes
document the entire release series, not just the first release,
so it needs to eventually stay as "/doc/go1.21" and not "/doc/go1.21.0".

For golang/go#57631.

Change-Id: I069d171354752e5123b7950c45581a236b304f95
Reviewed-on: https://go-review.googlesource.com/c/website/+/497497
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/_content/doc/devel/release.html b/_content/doc/devel/release.html
index f514a23..f6710a5 100644
--- a/_content/doc/devel/release.html
+++ b/_content/doc/devel/release.html
@@ -30,10 +30,10 @@
 
 	<p>
 	Go {{.Version}} is a major release of Go.
-	Read the <a href="/doc/go{{.Version}}">Go {{.Version}} Release Notes</a> for more information.
+	Read the <a href="/doc/go{{.Version.MajorPrefix}}">Go {{.Version.MajorPrefix}} Release Notes</a> for more information.
 	</p>
 
-	{{if .Minor}}<h3 id="go{{.Version}}.minor">Minor revisions</h3>{{end}}
+	{{if .Minor}}<h3 id="go{{.Version.MajorPrefix}}.minor">Minor revisions</h3>{{end}}
 
 	{{range .Minor}}
 		<p id="go{{.Version}}">
diff --git a/internal/history/history.go b/internal/history/history.go
index f8bab54..ab976a2 100644
--- a/internal/history/history.go
+++ b/internal/history/history.go
@@ -37,11 +37,11 @@
 // A Version is a Go release version.
 //
 // In contrast to Semantic Versioning 2.0.0,
-// trailing zero components are omitted,
-// a version like Go 1.14 is considered a major Go release,
-// a version like Go 1.14.1 is considered a minor Go release.
+// a version like Go 1.21.0 is considered a major Go release and
+// a version like Go 1.21.1 is considered a minor Go release.
+// Prior to 1.21.0, trailing zero components were omitted. (See proposal 57631 that changed this.)
 //
-// See proposal golang.org/issue/32450 for background, details,
+// See proposal go.dev/issue/32450 for background, details,
 // and a discussion of the costs involved in making a change.
 type Version struct {
 	X int // X is the 1st component of a Go X.Y.Z version. It must be 1 or higher.
@@ -50,11 +50,30 @@
 }
 
 // String returns the Go release version string,
-// like "1.14", "1.14.1", "1.14.2", and so on.
+// like "1.21.0", "1.21.1", "1.21.2", and so on.
 func (v Version) String() string {
 	switch {
-	case v.Z != 0:
+	// Starting with 1.21.0, trailing 0 components are no longer
+	// left out out of the Go version string. See proposal 57631.
+	// So it only needs to be done for prior historical versions.
+	case v.X == 1 && v.Y < 21 && v.Z == 0:
+		return fmt.Sprintf("%d.%d", v.X, v.Y)
+	case v.X == 1 && v.Y == 0 && v.Z == 0:
+		return fmt.Sprintf("%d", v.X)
+
+	default:
 		return fmt.Sprintf("%d.%d.%d", v.X, v.Y, v.Z)
+	}
+}
+
+// MajorPrefix returns the major version prefix of a Go release version,
+// like "1", "1.20", "1.21", and so on.
+//
+// This prefix can be used when referring to the entire series of releases,
+// including the major Go release and all of its subsequent minor releases,
+// that this version belongs to.
+func (v Version) MajorPrefix() string {
+	switch {
 	case v.Y != 0:
 		return fmt.Sprintf("%d.%d", v.X, v.Y)
 	default:
@@ -73,14 +92,6 @@
 	return v.Z < u.Z
 }
 
-// IsMajor reports whether version v is considered to be a major Go release.
-// For example, Go 1.14 and 1.13 are major Go releases.
-func (v Version) IsMajor() bool { return v.Z == 0 }
-
-// IsMinor reports whether version v is considered to be a minor Go release.
-// For example, Go 1.14.1 and 1.13.9 are minor Go releases.
-func (v Version) IsMinor() bool { return v.Z != 0 }
-
 // A Date represents the date (year, month, day) of a Go release.
 //
 // This type does not include location information, and