internal/worker: upgrade x/mod to allow fetching 1.21.0 modules

Upgrade x/mod so that modfile.Parse accepts the newly relaxed go
directive syntax. Add a test.

For golang/go#62031

Change-Id: I63a8eb73ff7428e67d80446b493c624a52ad2e96
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/521125
TryBot-Result: Gopher Robot <gobot@golang.org>
kokoro-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
diff --git a/go.mod b/go.mod
index 33dd6e1..31dcecb 100644
--- a/go.mod
+++ b/go.mod
@@ -33,7 +33,7 @@
 	github.com/yuin/goldmark v1.4.13
 	github.com/yuin/goldmark-emoji v1.0.1
 	go.opencensus.io v0.23.0
-	golang.org/x/mod v0.8.0
+	golang.org/x/mod v0.12.0
 	golang.org/x/net v0.13.0
 	golang.org/x/sync v0.1.0
 	golang.org/x/text v0.11.0
diff --git a/go.sum b/go.sum
index a23947e..8804a21 100644
--- a/go.sum
+++ b/go.sum
@@ -1140,8 +1140,8 @@
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
diff --git a/internal/worker/fetch_test.go b/internal/worker/fetch_test.go
index 27bc709..a2d9061 100644
--- a/internal/worker/fetch_test.go
+++ b/internal/worker/fetch_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"context"
+	"fmt"
 	"sort"
 	"strings"
 	"testing"
@@ -21,6 +22,7 @@
 	"golang.org/x/pkgsite/internal/source"
 	"golang.org/x/pkgsite/internal/stdlib"
 	"golang.org/x/pkgsite/internal/testing/sample"
+	"golang.org/x/pkgsite/internal/testing/testhelper"
 	"golang.org/x/pkgsite/internal/version"
 )
 
@@ -339,3 +341,37 @@
 			modulePath, wantRaw, wantCooked)
 	}
 }
+
+func TestFetchGo121(t *testing.T) {
+	// This test verifies that we can fetch modules using the more relaxed go
+	// directive syntax added with Go 1.21 (e.g. `go 1.21.0`).
+	var (
+		modulePath = sample.ModulePath
+		version    = sample.VersionString
+		foo        = map[string]string{
+			"go.mod":     fmt.Sprintf("module %s\n\ngo 1.21.0\n", modulePath),
+			"foo/foo.go": "// Package foo\npackage foo\n\nconst Foo = 42",
+			"README.md":  "This is a readme",
+			"LICENSE":    testhelper.MITLicense,
+		}
+	)
+	proxyClient, teardownProxy := proxytest.SetupTestClient(t, []*proxytest.Module{
+		{
+			ModulePath: modulePath,
+			Version:    version,
+			Files:      foo,
+		},
+	})
+	defer teardownProxy()
+
+	sourceClient := source.NewClient(sourceTimeout)
+	f := &Fetcher{proxyClient, sourceClient, testDB, nil, nil, ""}
+	got, _, err := f.FetchAndUpdateState(context.Background(), modulePath, version, testAppVersion)
+	if err != nil {
+		t.Fatalf("FetchAndUpdateState(%q, %q): %v", sample.ModulePath, version, err)
+	}
+	want := 200
+	if got != want {
+		t.Fatalf("FetchAndUpdateState(%q, %q): status = %d, want %d", sample.ModulePath, version, got, want)
+	}
+}