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
跟隨它,但我還沒有嘗試過。如果您這樣做并且有效,請分享!