Golang 项目 Protobuf 损坏的导入
Golang project Protobuf corrupted imports
我不是 golang 开发人员,但目前我必须修复它的代码,如果我不小心不理解 Go 的一些基本概念,请提前道歉 ;) 我有第三方 protobuf
合同,我必须使用并且我没有影响。我无法提供合同的实际示例,所以我制作了 similar example project on Github,它有同样的问题。
简而言之:proto
文档有一个深层嵌套结构,其中一些导入其他文档:
syntax = "proto3";
package company.nested1.nested2;
import "company/common.proto";
option go_package = "nested2";
message CompanyMessage {
CompanyEnum compEnum = 1;
}
参考文献
syntax = "proto3";
package company;
option go_package = "company";
enum CompanyEnum {
VAR1 = 0;
VAR2 = 1;
}
有一个包含以下代码的 go.mod
文件:
module go-program
go 1.16
require (
github.com/golang/protobuf v1.5.2
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/grpc v1.40.0 // indirect
google.golang.org/protobuf v1.26.0
)
并且在编译为Golang代码时,这个import有问题。生成的 *.pb.go
文件具有相对于 company
包的导入,而它们在 go-project
中具有根目录的 go 项目中使用,因此无法解析这些导入:
据我所知,以前这个问题已经通过手动编辑生成文件中的导入来解决。就像在下面的屏幕中一样。但在我看来应该有更好的方法;)
我正在使用此命令从原始文件生成 go 代码:
protoc --proto_path=proto (find proto -name '*.proto') --go_out=plugins=grpc:.
所以问题是:在 go 中解决此类导入问题的正确方法是什么。似乎生成文件中的导入应该以我的程序根命名空间开头。但是如何实现这一点 - 也许 protoc
命令中的一些选项我还没有找到。我还尝试将生成的文件放在 $GOPATH/src
或 vendors
中,并尝试制作和发布单独的模块 - 没有结果。有没有合适的解决方案?
这更多的是一些指点,而不是一个明确的答案。如果我明天有时间,我会重现这个给你一个明确的答案。
很有挑战性。 Protobufs 必须为每种语言的包管理找到解决方案,而 Go 的(虽然 IMO 有所改进)与最近添加的模块有点复杂。
我使用代码的方法是为原型和生成的代码创建一个单独的回购协议。如果原型发生变化,则重新生成代码。我可以引用生成的模块 (!) 或重新生成自己。该模型将原型保留为最终的“源”,并节省了“缓存”生成源的时间。但在这个配置中我是我自己的第 3 方库维护者。
所以:
- 模块在本地显示为目录树,其根包含
go.mod
和 go.sum
以及代表包的子目录。
- 当您为第 3 方原型生成代码时,我认为最好在它们自己的模块下创建它,作为独立目录或作为供应子目录。
- 这个模块应该被命名为引用第 3 方,并且可以用
go mod init
创建并且应该包含 protoc
的输出
- 模块通常是从代理或 repo 中提取的,但您可以通过手动将
replace
添加到 go mod
来规避此问题(因为第 3 方不为您托管生成的代码)从模块路径重定向到本地路径。
- 根据您的错误,这应该可以解决缺少模块的问题,并带有一个子目录,例如
company
包含生成的代码,也应该解析包。
我不是 golang 开发人员,但目前我必须修复它的代码,如果我不小心不理解 Go 的一些基本概念,请提前道歉 ;) 我有第三方 protobuf
合同,我必须使用并且我没有影响。我无法提供合同的实际示例,所以我制作了 similar example project on Github,它有同样的问题。
简而言之:proto
文档有一个深层嵌套结构,其中一些导入其他文档:
syntax = "proto3";
package company.nested1.nested2;
import "company/common.proto";
option go_package = "nested2";
message CompanyMessage {
CompanyEnum compEnum = 1;
}
参考文献
syntax = "proto3";
package company;
option go_package = "company";
enum CompanyEnum {
VAR1 = 0;
VAR2 = 1;
}
有一个包含以下代码的 go.mod
文件:
module go-program
go 1.16
require (
github.com/golang/protobuf v1.5.2
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/grpc v1.40.0 // indirect
google.golang.org/protobuf v1.26.0
)
并且在编译为Golang代码时,这个import有问题。生成的 *.pb.go
文件具有相对于 company
包的导入,而它们在 go-project
中具有根目录的 go 项目中使用,因此无法解析这些导入:
据我所知,以前这个问题已经通过手动编辑生成文件中的导入来解决。就像在下面的屏幕中一样。但在我看来应该有更好的方法;)
我正在使用此命令从原始文件生成 go 代码:
protoc --proto_path=proto (find proto -name '*.proto') --go_out=plugins=grpc:.
所以问题是:在 go 中解决此类导入问题的正确方法是什么。似乎生成文件中的导入应该以我的程序根命名空间开头。但是如何实现这一点 - 也许 protoc
命令中的一些选项我还没有找到。我还尝试将生成的文件放在 $GOPATH/src
或 vendors
中,并尝试制作和发布单独的模块 - 没有结果。有没有合适的解决方案?
这更多的是一些指点,而不是一个明确的答案。如果我明天有时间,我会重现这个给你一个明确的答案。
很有挑战性。 Protobufs 必须为每种语言的包管理找到解决方案,而 Go 的(虽然 IMO 有所改进)与最近添加的模块有点复杂。
我使用代码的方法是为原型和生成的代码创建一个单独的回购协议。如果原型发生变化,则重新生成代码。我可以引用生成的模块 (!) 或重新生成自己。该模型将原型保留为最终的“源”,并节省了“缓存”生成源的时间。但在这个配置中我是我自己的第 3 方库维护者。
所以:
- 模块在本地显示为目录树,其根包含
go.mod
和go.sum
以及代表包的子目录。 - 当您为第 3 方原型生成代码时,我认为最好在它们自己的模块下创建它,作为独立目录或作为供应子目录。
- 这个模块应该被命名为引用第 3 方,并且可以用
go mod init
创建并且应该包含protoc
的输出
- 模块通常是从代理或 repo 中提取的,但您可以通过手动将
replace
添加到go mod
来规避此问题(因为第 3 方不为您托管生成的代码)从模块路径重定向到本地路径。 - 根据您的错误,这应该可以解决缺少模块的问题,并带有一个子目录,例如
company
包含生成的代码,也应该解析包。