-
-
Notifications
You must be signed in to change notification settings - Fork 685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using rules_go with go modules and generated packages #2262
Comments
I have been using the dummy.go trick as well. |
So if I can summarize a bit, the issue is that you depend on a package that only contains generated code ( You're correct that Go modules are very much integrated into the go command. Code generation is very much not integrated into the go command. There is There are a number of workarounds, some of which you've already found.
Beyond that, I'm not sure I have a generally good solution to recommend for you. Kubernetes ran into some of the same issues. Bazel appealed to them because it seemed like they could remove a lot of their generated code from their repo, but non-Bazel users still needed to import their packages, so they were never really able to do that. I'm open to solutions on the Gazelle side that don't diverge too far from what the go command does. Currently, It's unlikely that fully general code generation will be integrated into |
That pretty much sums it up. To add some clarifications on our situation: the repository we use the Manually editing the module file could be a possibility, but manually having to trim the module and sum file would be error prone with a large group of developers. I guess what I'm looking for is some way to do maintainence like |
You may want a custom tool for this. At one point, I wanted There are primitives available you may find useful.
|
I would like to hear your feedback on another approach we have thought of for our monorepo, to help go modules work with generated packages. So like you said, the source of our problem is The idea is that we can filter all of the imports in our repo to only what
We then can move our With this "shadow module" approach, we will be able to use go modules for dependency management, and bazel for building and code generation. Known limitations:
Are there any other limitations or gotchas you think we may be missing? |
@blico I think that will work. How are you planning to list all imports? I can think of a couple different ways.Something built with Once you have that list, using an |
Our idea right now is to:
Because we are using Bazel as our source of truth with this approach, an added requirement for users is they will need to run |
@blico, @robbertvanginkel, are you still using the same approach? I'm bumping into this as well. |
Yes, we are still using @blico's approach (I am in the same team as @blico and @robbertvanginkel). |
A solution that I came up with to this problem is the following: Suppose we have a directory of proto files. Add a file
Add Disable proto rule generation in gazelle using Now to get everything running for a freshly cloned repo do the following:
This solution should work for any code you can generate using a Note that this pushes dependency management of code generators to the underlying system (your CI or Container this runs in). Ideally there should be a native solution for this problem but for the moment this is simple and robust. |
After investigating all above solutions, I think using the stackb rules is best for me: https://github.com/stackb/rules_proto Just use the echo "Cleaning up existing generated protobuf files..."
#find "proto/" -name BUILD.bazel -delete # uncomment if you rely on gazelle to generate rules.
find "proto/" -name "*.pb.go" -delete
echo "Generating bazel BUILD rules..."
bazel run //:gazelle
echo "Compiling protobuf files..."
bazel query "kind('proto_compile rule', //proto/...)" | tr '\n' '\0' | xargs -0 -n1 bazel build
bazel query "kind('proto_compile_gencopy_run rule', //proto/...)" | tr '\n' '\0' | xargs -0 -n1 bazel run
bazel query "kind('proto_compile_gencopy_test rule', //proto/...)" | tr '\n' '\0' | xargs -0 -n1 bazel test In my case, both my upstream repositories and downstream repositories do not use bazel (yeah I am the only one promoting it due to my past Googler experience), so |
Currently we're just adding empty Go files to generated packages and excluding said files from Gazelle. The empty Go files do not have build constraints ( empty.gopackage mock BUILD.bazel# gazelle:exclude **/mock/empty.go One thought I had: I wonder if it's possible to use the GOPACKAGESDRIVER (#512) with gopls to tidy modules? |
@blico IS the tool you use open source? |
Is it possible to tell |
First, I'm not sure if I should file this on rules_go, bazel-gazelle or golang. Please let me know if there's a better forum.
The experience of building go code with
rules_go
/gazelle
works pretty well in general. Unfortunately when using both go modules for dependency management and rules for autogenerating go packages (such asgo_proto_library
orgomock
), the experience breaks down a bit.Consider the following project:
With a standard workspace file (I tested go1.13.3, rules_go v0.20.1, gazelle 0.19.0, bazel 1.1.0) it is straightforward to get the program running:
Adding a dependency with go mod is also straightforward:
When starting to consume some generated code, at first all seems fine:
Where
github.com/example/project/proto
is a generated golang package:After generating the rules everything seems to work fine:
But when at a later stage, you try to add a new dependency to your project,
go get
will still work, whilego mod tidy
will start throwing errors like:So far, we'd come up with the following to get around this:
dummy.go
files with// +build ignore
in directory corresponding to the importpath for generated modules.gen/
. This made go1.12 modules think they were part of the standard library and not worry about them, but go1.13's modules require the first path component contain a.
somewhere.As far as I've read into the design and code of go modules, it seems pretty tightly coupled with the default go build system. That's unfortunate, as we like Bazel due to some codegen/caching features, but not being able to use both the standard go modules dependency management resolution logic and generated go packages at the same time is a bit sour.
Are there any known workarounds to this? Maybe there is a way for rules_go/bazel could inform go modules about which packages are expected to exist? Or would we need to open an issue with golang to see if the modules functionality can somehow be exposed for usage with 3rd party buildsystems?
The text was updated successfully, but these errors were encountered: