I am having some trouble using go generate to generate a grpc server when running go generate from the root of my project directory.
When I run go generate -v
it only returns main.go
. However, the directives are defined in one the subpackages. If I run go generate
in the sub package it works as expected. I expected the imports to ensure that go generate
would find the subpackages and run the directives.
The project has the following structure:
cmd/
root.go
run.go
pkg/
subpkg/
protobuf/
proto1.proto
subpkg.go
main.go
Contents of subpkg.go
//go:generate protoc -I ./protobuf --go_out=plugins=grpc:./protobuf ./protobuf/proto1.proto
package subpkg
Contents of main.go:
package main
import (
"fmt"
"os"
"my-project/cmd"
)
func main() {
if err := cmd.RootCommand.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
In the run.go package, I import the package subpkg.
How do I ensure go generate can be run from the root of the project and execute all directives in all sub packages.
You're looking for go generate ./...
.
Per go help generate
:
usage: go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
...
For more about specifying packages, see 'go help packages'.
go help packages
:
Many commands apply to a set of packages:
go action [packages]
Usually, [packages] is a list of import paths.
An import path that is a rooted path or that begins with
a . or .. element is interpreted as a file system path and
denotes the package in that directory.
Otherwise, the import path P denotes the package found in
the directory DIR/src/P for some DIR listed in the GOPATH
environment variable (For more details see: 'go help gopath').
If no import paths are given, the action applies to the
package in the current directory.
...
An import path is a pattern if it includes one or more "..." wildcards,
each of which can match any string, including the empty string and
strings containing slashes. Such a pattern expands to all package
directories found in the GOPATH trees with names matching the
patterns.
So, when you don't specify a package to a Go command that takes one, it assumes the package is the current directory. Subdirectories are different packages, so they aren't included. A handy shorthand for "this package and all packages in sudirectories underneath it recursively" is ./...
, as in
go get ./...
go generate ./...
go test ./...