bzlmod: Add support for gomock (#3232)

This introduces a dependency on the new gazelle module, which requires
using Bazel at HEAD for c068b0d2347905c5e9be793b741f693c7edb6e53.

Aliases are introduced for the required gomock targets so that users
don't have to declare their own dependency on gomock with bzlmod.
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 3d00d19..b6333b5 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -26,7 +26,10 @@
   ubuntu2004_bcr_tests:
     name: BCR test module
     platform: ubuntu2004
-    bazel: 6.0.0-pre.20220608.2
+    bazel: last_green
+    shell_commands:
+      # Patch io_bazel_rules_go to rules_go. The patch may be slightly out of date, so we ignore the exit status.
+      - "curl https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/modules/rules_go/0.33.0/patches/bcr.patch | patch -r -u -p1 -d ../.. || exit 0"
     working_directory: tests/bcr
     build_flags:
       - "--experimental_enable_bzlmod"
diff --git a/MODULE.bazel b/MODULE.bazel
index 35e60d7..49a2b3f 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -21,3 +21,8 @@
 go_sdk = use_extension("//go:extensions.bzl", "go_sdk")
 go_sdk.download(name = "go_default_sdk", version = "1.18.3")
 use_repo(go_sdk, "go_default_sdk")
+
+bazel_dep(name = "gazelle", version = "0.26.0")
+go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
+go_deps.module(importpath = "github.com/golang/mock", version = "v1.6.0", sum = "h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=")
+use_repo(go_deps, "com_github_golang_mock")
diff --git a/docs/go/extras/extras.md b/docs/go/extras/extras.md
index f0fafc4..1548b19 100644
--- a/docs/go/extras/extras.md
+++ b/docs/go/extras/extras.md
@@ -98,7 +98,7 @@
 | <a id="gomock-package"></a>package |  the name of the package the generated mocks should be in. If not specified, uses mockgen's default. See [mockgen's -package](https://github.com/golang/mock#flags) for more information.   |  <code>""</code> |
 | <a id="gomock-self_package"></a>self_package |  the full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. See [mockgen's -self_package](https://github.com/golang/mock#flags) for more information.   |  <code>""</code> |
 | <a id="gomock-aux_files"></a>aux_files |  a map from source files to their package path. This only needed when <code>source</code> is provided. See [mockgen's -aux_files](https://github.com/golang/mock#flags) for more information.   |  <code>{}</code> |
-| <a id="gomock-mockgen_tool"></a>mockgen_tool |  the mockgen tool to run.   |  <code>"@com_github_golang_mock//mockgen"</code> |
+| <a id="gomock-mockgen_tool"></a>mockgen_tool |  the mockgen tool to run.   |  <code>Label("//extras/gomock:mockgen")</code> |
 | <a id="gomock-imports"></a>imports |  dictionary of name-path pairs of explicit imports to use. See [mockgen's -imports](https://github.com/golang/mock#flags) for more information.   |  <code>{}</code> |
 | <a id="gomock-copyright_file"></a>copyright_file |  optional file containing copyright to prepend to the generated contents. See [mockgen's -copyright_file](https://github.com/golang/mock#flags) for more information.   |  <code>None</code> |
 | <a id="gomock-mock_names"></a>mock_names |  dictionary of interface name to mock name pairs to change the output names of the mock objects. Mock names default to 'Mock' prepended to the name of the interface. See [mockgen's -mock_names](https://github.com/golang/mock#flags) for more information.   |  <code>{}</code> |
diff --git a/extras/gomock.bzl b/extras/gomock.bzl
index 047171e..7e960ea 100644
--- a/extras/gomock.bzl
+++ b/extras/gomock.bzl
@@ -28,8 +28,8 @@
 load("//go/private:providers.bzl", "GoLibrary")
 load("@bazel_skylib//lib:paths.bzl", "paths")
 
-_MOCKGEN_TOOL = "@com_github_golang_mock//mockgen"
-_MOCKGEN_MODEL_LIB = "@com_github_golang_mock//mockgen/model"
+_MOCKGEN_TOOL = Label("//extras/gomock:mockgen")
+_MOCKGEN_MODEL_LIB = Label("//extras/gomock:mockgen_model")
 
 def _gomock_source_impl(ctx):
     go_ctx = go_context(ctx)
@@ -137,7 +137,7 @@
         ),
         "mockgen_tool": attr.label(
             doc = "The mockgen tool to run",
-            default = Label(_MOCKGEN_TOOL),
+            default = _MOCKGEN_TOOL,
             allow_single_file = True,
             executable = True,
             cfg = "exec",
@@ -271,7 +271,7 @@
         ),
         "mockgen_tool": attr.label(
             doc = "The mockgen tool to run",
-            default = Label(_MOCKGEN_TOOL),
+            default = _MOCKGEN_TOOL,
             allow_single_file = True,
             executable = True,
             cfg = "exec",
@@ -353,7 +353,7 @@
         ),
         "mockgen_tool": attr.label(
             doc = "The mockgen tool to run",
-            default = Label(_MOCKGEN_TOOL),
+            default = _MOCKGEN_TOOL,
             allow_single_file = True,
             executable = True,
             cfg = "exec",
diff --git a/extras/gomock/BUILD.bazel b/extras/gomock/BUILD.bazel
new file mode 100644
index 0000000..5eb1e08
--- /dev/null
+++ b/extras/gomock/BUILD.bazel
@@ -0,0 +1,17 @@
+alias(
+    name = "gomock",
+    actual = "@com_github_golang_mock//gomock",
+    visibility = ["//visibility:public"],
+)
+
+alias(
+    name = "mockgen",
+    actual = "@com_github_golang_mock//mockgen",
+    visibility = ["//visibility:public"],
+)
+
+alias(
+    name = "mockgen_model",
+    actual = "@com_github_golang_mock//mockgen/model",
+    visibility = ["//visibility:public"],
+)
diff --git a/tests/bcr/.bazelversion b/tests/bcr/.bazelversion
index 7229a26..5e52a62 100644
--- a/tests/bcr/.bazelversion
+++ b/tests/bcr/.bazelversion
@@ -1 +1 @@
-6.0.0-pre.20220526.1
+last_green
diff --git a/tests/bcr/BUILD.bazel b/tests/bcr/BUILD.bazel
index 5da66df..813d72f 100644
--- a/tests/bcr/BUILD.bazel
+++ b/tests/bcr/BUILD.bazel
@@ -1,3 +1,4 @@
+load("@my_rules_go//extras:gomock.bzl", "gomock")
 load("@my_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
 
 go_library(
@@ -17,3 +18,30 @@
     srcs = ["test.go"],
     embed = [":lib"],
 )
+
+go_library(
+    name = "mockable",
+    srcs = [
+        "mockable.go",
+    ],
+    importpath = "example.com/mockable",
+)
+
+gomock(
+    name = "mocks",
+    out = "mockable_mock.go",
+    library = ":mockable",
+    package = "mockable",
+    source = "mockable.go",
+    visibility = ["//visibility:public"],
+)
+
+go_test(
+    name = "mockable_test",
+    srcs = [
+        "mockable_mock.go",
+        "mockable_test.go",
+    ],
+    embed = [":mockable"],
+    deps = ["@my_rules_go//extras/gomock"],
+)
diff --git a/tests/bcr/mockable.go b/tests/bcr/mockable.go
new file mode 100644
index 0000000..e310105
--- /dev/null
+++ b/tests/bcr/mockable.go
@@ -0,0 +1,7 @@
+package mockable
+
+import "net/url"
+
+type Client interface {
+	Connect(addr string) url.URL
+}
diff --git a/tests/bcr/mockable_test.go b/tests/bcr/mockable_test.go
new file mode 100644
index 0000000..7e9cc8a
--- /dev/null
+++ b/tests/bcr/mockable_test.go
@@ -0,0 +1,3 @@
+package mockable
+
+var _ Client = (*MockClient)(nil)