Reputation: 111
I'm not a golang developer but currently I have to fix code on it, so sorry in advance if I accidentally not understand some basic Go's concept ;) I have a third party protobuf
contract which I have to use and on which I don't have influence. I'm not able to provide actual example of the contract, so I've made similar example project on Github which has the same problem.
In short: there is a deeply nested structure of proto
documents where some of them import others:
syntax = "proto3";
package company.nested1.nested2;
import "company/common.proto";
option go_package = "nested2";
message CompanyMessage {
CompanyEnum compEnum = 1;
}
references
syntax = "proto3";
package company;
option go_package = "company";
enum CompanyEnum {
VAR1 = 0;
VAR2 = 1;
}
There is a go.mod
file with following code:
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
)
And when compiling to the Golang code there is a problem in this import. Generated *.pb.go
files have imports relative to company
package while they are used inside of a go project with root in go-project
so these imports can't be resolved:
As I understand, previously this problem has been solved by manual editing of imports in generated files. Like in the screen below. But in my opinion there should be a better way for this ;)
I'm using this command to generate go code from proto files:
protoc --proto_path=proto (find proto -name '*.proto') --go_out=plugins=grpc:.
So the question is: what is a proper way to solve such import problem in go. Seems like imports in generated files should begin with my program root namespace. But how to achieve this - maybe some options in protoc
command which I haven't found. I tried also to put generated files inside of $GOPATH/src
or in vendors
and tried to make and publish separate module - no result. Is there some proper solution for this?
Upvotes: 1
Views: 544
Reputation: 40061
This is more some pointers rather than a definitive answer. If I find some time tomorrow, I'll repro this to give you a definitive answer.
It is challenging. Protobufs has to find a solution for each language's package management and Go's (while IMO improved) is somewhat compounded with recent addition of Modules.
My approach my with code is to have a separate repo for the protos and generated code. If the protos change, the code is regenerated. I can either reference the generated module (!) or regenerate myself. This model keeps the protos as the definitive "source" with the timesaver of "cached" generated sources. But I'm my own 3rd-party library maintainer in this config.
So:
go.mod
and go.sum
and subsidirectories representing packages.go mod init
and should contain the output of protoc
replace
to the go mod
redirecting from the module path to a local path.company
containing that generated code, should resolve the package too.Upvotes: 3