Description
Given :
- three
go_proto_library()
targets foo, bar, and baz - foo depends on bar, and bar depends on baz
- bar uses import public "baz.proto"
The protoc-gen-go
tool generates code for foo (foo.pb.go
) that looks like:
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.3
// protoc v5.27.0
// [...]
import (
baz "[...]/baz_go_proto"
_ "[...]/bar_go_proto"
The compilepkg
strict dependencies check scans this file for imports, sees the import of baz, and then errors because foo did not declare a direct dependency on baz.
rules_go/go/tools/builders/importcfg.go
Line 100 in 393faea
However, I think this behavior is a bug. If I understand correctly, import public
is supposed to enable moving messages without breaking downstream consumers. The alternative is to update all users atomically, but it can be difficult to impossible to do that in:
- a large and active monorepo, or
- an SDK where you've promised your customers backwards compatibility
Steps to reproduce
Clone my fork
git clone -b sloretz_repro_import_public_issue https://github.com/sloretz/rules_go.git
Run this test
bazel test //tests/core/go_proto_library_import_public:import_public_test
Observe this failure:
compilepkg: missing strict dependencies:
/home/sloretz/.cache/bazel/_bazel_sloretz/e4e5127b5b9f1e33f9a706fce20cac1d/sandbox/linux-sandbox/4/execroot/io_bazel_rules_go/bazel-out/k8-fastbuild/bin/tests/core/go_proto_library_import_public/dog_go_proto_/github.com/bazelbuild/rules_go/tests/core/go_proto_library_import_public/dog_go_proto/dog.pb.go: import of "github.com/bazelbuild/rules_go/tests/core/go_proto_library_import_public/new_dir/dog_collar_go_proto"
No dependencies were provided.
Check that imports in Go sources match importpath attributes in deps.
Suggested fix
The proto_library()
rule has an exports
attribute for the import public
use case. How about go_proto_library()
gets an exports
attribute as well? Then bar could declare an export of baz, and foo can be ignorant of protos being moved upstream of it.
The exports
attribute would need to set some provider such that foo's call to compilepkg
would get a new -arc argument for baz