Skip to content

Bug: "missing strict dependencies" using import public and go_proto_library #4357

Open
@sloretz

Description

@sloretz

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.

derr.missing = append(derr.missing, missingDep{f.filename, path})

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions