I have a .proto
protobuf definition file in a dir and I'm building a go library from it with Bazel like so (BUILD.bazel
file below generated using gazelle
):
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
proto_library(
name = "events_proto",
srcs = ["events.proto"],
visibility = ["//visibility:public"],
deps = ["@com_google_protobuf//:timestamp_proto"],
)
go_proto_library(
name = "proto_go_proto",
importpath = "github.com/acme/icoyote/proto",
proto = ":events_proto",
visibility = ["//visibility:public"],
)
go_library(
name = "proto",
embed = [":proto_go_proto"],
importpath = "github.com/acme/icoyote/proto",
visibility = ["//visibility:public"],
)
Some other code depends on //icoyote/proto:proto
, and when I run go mod tidy
in my module, it complains that it can't find the package github.com/acme/icoyote/proto
:
go: finding module for package github.com/acme/icoyote/proto
github.com/acme/icoyote/cmd/icoyote imports
github.com/acme/icoyote/proto: no matching versions for query "latest"
Any IDE that doesn't have Bazel integration (e.g. VSCode, GoLand/IntelliJ without the Bazel plugin) complains as well
What do I do?
This is happening of course because because Bazel does generate .go
files using protoc
under the covers for the go_proto_library
rule in the BUILD
file, but only writes them out to a temp dir under bazel-bin
to be used by the go_library
rule, and go mod tidy
doesn't seem look into bazel-bin
(probably because it's a symlink but also if it did, the path of those files relative to the location of go.mod
is all wrong)
One option is to manually generate the go files by calling protoc
on your own, and remove the proto_library
and go_proto_library
rules in the BUILD
file, then change the go_library
rule to build your generated files. This is suboptimal because you have to manually rerun protoc
every time you make changes to the .proto
file (and if you put it into a //go:generate
directive, you have to rerun go generate
).
Instead, we can do the following:
empty.go
to the dir that contains the .proto
file. It should look like this:package proto
gazelle
to ignore empty.go
(so it doesn't try to add a go_library
rule to the BUILD
file when you run gazelle --fix
). We do that by adding the following to the BUILD
file:# gazelle:exclude empty.go
That's enough to make go mod tidy
shut up.
This will also make the IDE stop complaining about the import, although you'll still get errors when referring to anything that's supposed to be in that package. If you don't want to abandon your IDE for an excellent GoLand or IntelliJ IDEA with a Bazel plugin, you might have to resort to the manual protoc
method. Perhaps there's a way to create a symlink to wherever Bazel writes out the generated .go
files under bazel-bin
and force go mod tidy
to follow it, but I haven't tried that. If you do and it works, do share!