bzlmod: allow non-default go.work file names (#2303)

The go command accepts any file as a workspace file via the GOWORK
environment variable, and writes checksums to a sibling file with a .sum
suffix (e.g. GOWORK=go.bazel.work produces go.bazel.work.sum).

go_deps.from_file(go_work = ...) currently rejects any name other than
go.work, and hardcodes go.work.sum as the sum file name. This is
stricter than the go command itself. Notably, go_work_from_label already
accepts any name; only the sum-file path checks.

Remove the name check and derive the sum file name from the work file
name.

A non-default name is useful when a repository wants a Bazel-only
workspace that the go toolchain won't auto-discover (the toolchain walks
up directories looking specifically for go.work), so native go builds
remain unaffected by the Bazel workspace configuration.

**What type of PR is this?**

 Bug fix

**What package or component does this PR mostly affect?**

go_repository

**What does this PR do? Why is it needed?**

**Which issues(s) does this PR fix?**

Fixes #2302

**Other notes for review**
diff --git a/.gitignore b/.gitignore
index f39bda5..3ab8e22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,5 +6,6 @@
 /tests/bcr/*/bazel-bin
 /tests/bcr/*/bazel-out
 /tests/bcr/*/bazel-testlogs
+/tests/bcr/*/MODULE.bazel.lock
 .DS_STORE
 .ijwb/
diff --git a/internal/bzlmod/go_mod.bzl b/internal/bzlmod/go_mod.bzl
index 2409a06..fa0b2bf 100644
--- a/internal/bzlmod/go_mod.bzl
+++ b/internal/bzlmod/go_mod.bzl
@@ -404,34 +404,39 @@
     return parse_sumfile(module_ctx, go_mod_label, "go.sum")
 
 def sums_from_go_work(module_ctx, go_work_label):
-    """Loads the entries from a go.work.sum file given a go.work label.
+    """Loads the entries from a go.work.sum file given a go work file label.
 
     Args:
         module_ctx: a https://bazel.build/rules/lib/module_ctx object
             passed from the MODULE.bazel call.
-        go_work_label: a Label for a `go.work` file. This label is used
-            to find the associated `go.work.sum` file.
+        go_work_label: a Label for a go work file. The sum file is located
+            at `<go_work_label.name>.sum` in the same package, matching
+            the convention used by the go command.
 
     Returns:
         A Dict[(string, string) -> (string)] is returned where each entry
         is defined by a Go Module's sum:
             (path, version) -> (sum)
     """
-    _check_go_work_name(go_work_label.name)
 
-    # next we need to test if the go.work.sum file exists, this is a little tricky so we use an indirect approach:
+    # The go command accepts any file name via GOWORK and writes checksums
+    # to a sibling file with a .sum suffix, so derive the sum file name from
+    # the work file name rather than hardcoding go.work.sum.
+    sum_file_name = go_work_label.name + ".sum"
+
+    # next we need to test if the sum file exists, this is a little tricky so we use an indirect approach:
 
     # 1. convert go_work_label into a path
     go_work_path = module_ctx.path(go_work_label)
 
-    # 2. use the go_work_path to create a path for the heisen go.work.sum file
-    maybe_go_work_sum_path = go_work_path.dirname.get_child("go.work.sum")
+    # 2. use the go_work_path to create a path for the heisen sum file
+    maybe_go_work_sum_path = go_work_path.dirname.get_child(sum_file_name)
 
     # 3. check for its existence
     if maybe_go_work_sum_path.exists:
-        return parse_sumfile(module_ctx, go_work_label, "go.work.sum")
+        return parse_sumfile(module_ctx, go_work_label, sum_file_name)
     else:
-        # 4. if go.work.sum does not exist, we should watch it in case it appears in the future
+        # 4. if the sum file does not exist, we should watch it in case it appears in the future
         if hasattr(module_ctx, "watch"):
             # module_ctx.watch_tree is only available in bazel >= 7.1
             module_ctx.watch(maybe_go_work_sum_path)
@@ -477,10 +482,6 @@
     if name != "go.mod":
         fail("go_deps.from_file requires a 'go.mod' file, not '{}'".format(name))
 
-def _check_go_work_name(name):
-    if name != "go.work":
-        fail("go_deps.from_file requires a 'go.work' file, not '{}'".format(name))
-
 def _canonicalize_raw_version(raw_version):
     if raw_version.startswith("v"):
         return raw_version[1:]
diff --git a/tests/bcr/go_work/MODULE.bazel b/tests/bcr/go_work/MODULE.bazel
index cfc40e4..6a4a89e 100644
--- a/tests/bcr/go_work/MODULE.bazel
+++ b/tests/bcr/go_work/MODULE.bazel
@@ -31,8 +31,10 @@
     },
 )
 
-# Validate a full go workspace
-go_deps.from_file(go_work = "//:go.work")
+# Validate a full go workspace. The non-default file name exercises
+# go_deps.from_file's handling of custom work file names (the go command
+# itself accepts any name via GOWORK).
+go_deps.from_file(go_work = "//:workspace.go.work")
 go_deps.gazelle_default_attributes(
     build_file_generation = "on",
     directives = [
diff --git a/tests/bcr/go_work/go.work b/tests/bcr/go_work/workspace.go.work
similarity index 100%
rename from tests/bcr/go_work/go.work
rename to tests/bcr/go_work/workspace.go.work