php小編香蕉在處理編譯錯誤時,有時會遇到”go mod tidy”命令抱怨bazel生成的protobuf包丟失的問題。這個問題的解決方法其實很簡單,只需要在go.mod文件中手動添加對應的protobuf包依賴即可。通過執行”go mod tidy”命令來更新依賴關系,再次編譯就不會出現包丟失的問題了。這個方法簡單有效,能夠幫助開發者快速解決編譯錯誤,提高開發效率。
問題內容
我在目錄中有一個 .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 = ["http://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 = ["http://visibility:public"],
)
go_library(
name = "proto",
embed = [":proto_go_proto"],
importpath = "github.com/acme/icoyote/proto",
visibility = ["http://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、沒有 bazel 插件的 goland/intellij)也會抱怨
我該怎么辦?
解決方法
之所以發生這種情況,是因為 bazel 確實使用 protoc 在 build 文件中的 go_proto_library 規則下生成 .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 指令,則必須重新運行 gogenerate)。
相反,我們可以執行以下操作:
-
將文件
empty.go 添加到包含 .proto 文件的目錄中。它應該看起來像這樣:
package proto
登錄后復制
-
然后告訴
ngazelle 忽略 empty.go (這樣當您運行 gazelle --fix 時,它不會嘗試將 go_library 規則添加到 build 文件中)。我們通過將以下內容添加到 build 文件來實現此目的:
# gazelle:exclude empty.go
登錄后復制
這足以讓 go mod tidy 閉嘴。
這也將使 ide 停止抱怨導入,盡管在引用該包中應該包含的任何內容時仍然會出現錯誤。如果您不想放棄 ide 而選擇帶有 bazel 插件的優秀 goland 或 intellij idea,您可能必須求助于手動 protoc 方法。也許有一種方法可以創建一個符號鏈接到 bazel 在 bazel-bin 下寫出生成的 .go 文件的位置,并強制 go mod tidy 跟隨它,但我還沒有嘗試過。如果您這樣做并且有效,請分享!






