英文:
`go mod tidy` complains that the bazel-generated protobuf package is missing
问题
我有一个位于目录中的.proto
protobuf定义文件,并且我正在使用Bazel构建一个go库(使用gazelle
生成下面的BUILD.bazel
文件):
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"],
)
一些其他代码依赖于//icoyote/proto:proto
,当我在我的模块中运行go mod tidy
时,它抱怨找不到包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"
任何没有Bazel集成的IDE(例如VSCode、GoLand/IntelliJ没有Bazel插件的情况下)也会抱怨。
我该怎么办?
英文:
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?
答案1
得分: 3
这是因为Bazel在BUILD
文件中的go_proto_library
规则中使用protoc
生成.go
文件,但只将它们写入bazel-bin
下的临时目录供go_library
规则使用,而go mod tidy
似乎不会查看bazel-bin
(可能是因为它是一个符号链接,而且即使它查看了,相对于go.mod
位置的这些文件的路径也是错误的)。
一种选择是通过自己调用protoc
手动生成go文件,并在BUILD
文件中删除proto_library
和go_proto_library
规则,然后将go_library
规则更改为构建生成的文件。这种方法不太理想,因为每次更改.proto
文件时都必须手动重新运行protoc
(如果将其放入//go:generate
指令中,则必须重新运行go generate
)。
相反,我们可以采取以下步骤:
1)在包含.proto
文件的目录中添加一个名为empty.go
的文件,内容如下:
package proto
2)然后告诉gazelle
忽略empty.go
(这样在运行gazelle --fix
时它就不会尝试向BUILD
文件中添加go_library
规则)。我们可以通过在BUILD
文件中添加以下内容来实现:
# gazelle:exclude empty.go
这样就足够让go mod tidy
保持安静了。
这也会使IDE停止对导入的警告,尽管当引用应该在该包中的任何内容时,仍会出现错误。如果您不想放弃您的IDE,而是使用带有Bazel插件的优秀GoLand或IntelliJ IDEA,您可能需要采用手动的protoc
方法。也许有一种方法可以创建一个符号链接,指向Bazel在bazel-bin
下写出生成的.go
文件的位置,并强制go mod tidy
跟随它,但我还没有尝试过。如果您尝试并且成功了,请分享一下!
英文:
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:
- Add a file
empty.go
to the dir that contains the.proto
file. It should look like this:
package proto
- Then tell
gazelle
to ignoreempty.go
(so it doesn't try to add ago_library
rule to theBUILD
file when you rungazelle --fix
). We do that by adding the following to theBUILD
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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论