There is this package https://github.com/open-telemetry/opentelemetry-proto which contains protobuf definitions only. To generate golang code one must type:
make gen-go
and go build fails with following message:
build opentel: cannot load github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1: module github.com/open-telemetry/opentelemetry-proto@latest found (v0.11.0), but does not contain package github.com/open-telemetry/opentelemetry-proto/gen/go/common/v
I've tried to replace one path with another in go.mod file but apparently I'm not too good at it. How can I make it work?
I've copied those generated files to
$GOPATH/src/opentelemetry-proto/gen/go
what should I put in import statement inside my main package?
CodePudding user response:
There are a couple of challenges with the way the Go sources are generated. I assume that the repo authors are aiming for consistency across languages and for GOPATH
and GO MODULES
use-cases with Go.... so, yes, gnarly for them and us.
Here's a (!?) solution:
Assuming you're in /path/to/somedir
and it contains a clone of the opentelemetry-proto
and ``my-module` at the same level, i.e.:
.
├── my-module
└── opentelemetry-proto
make gen-go
as before. This should create./opentelemetry-proto/gen
In
./opentelemetry-proto/gen/go/github.com/open-telemetry/opentelemetry-proto
gogo mod init github.com/open-telemetry/opentelemetry-proto
:
.
├── gen
└── go.mod
- From within
my-module
,go mod init my-module
and then:
go.mod
:
module my-module
go 1.17
require (
github.com/open-telemetry/opentelemetry-proto v0.11.0
)
replace (
github.com/open-telemetry/opentelemetry-proto => ../opentelemetry-proto/gen/go/github.com/open-telemetry/opentelemetry-proto
NOTE With
GOPATH
paths down to packages are required (they're not using Go Modules) and so, if we were usingGOPATH
, we couldGOPATH=${GOPATH}:${PROTO_GEN_GO_DIR}/github.com/open-telemetry/opentelemetry-proto
And then, e.g.
main.go
:
package main
import (
v1 "github.com/open-telemetry/opentelemetry-proto/gen/go/collector/metrics/v1"
)
func main() {
// E.g.
_ = v1.ExportMetricsServiceRequest{}
}
Explanation:
make gen-go
does not create a Module but we can create one.
The Module is implicit from the path under gen/go
i.e. github.com/open-telemetry/opentelemetry-proto
Then, from our project, we can replace
to provide a local path to it. The path is the path to the clone, then back down to our newly-created go.mod
.
The import path is the path from the Module (i.e. that excessively convoluted replace path) to whichever package we're interested in.
NOTE Commonly protobuf imports are pb but I've used
v1
.
What I would do:
I think the Module of generated code should match its repo. If opentelemetry-proto
were mine, I'd generate the sources into the repo root without gen/go
As this would -- IMO -- simplify everything to:
github.com/open-telemetry/opentelemetry-proto => ../opentelemetry-proto
And:
import (
v1 "github.com/open-telemetry/opentelemetry-proto/collector/metrics/v1"
)