bazel-contrib / bazel-gazelle

Gazelle is a Bazel build file generator for Bazel projects. It natively supports Go and protobuf, and it may be extended to support new languages and custom rule sets.
Apache License 2.0
1.19k stars 379 forks source link

Gazelle fails to create BUILD files for Proto dependencies of an included library #1035

Open pierreis opened 3 years ago

pierreis commented 3 years ago

What version of gazelle are you using?

0.23.0

What version of rules_go are you using?

0.27.0

What version of Bazel are you using?

4.0.0

Does this issue reproduce with the latest releases of all the above?

Yes

What operating system and processor architecture are you using?

macOS 11.2.3 ; x86_64

What did you do?

Created a file depending on github.com/samsarahq/thunder, and including the following three package:

"github.com/samsarahq/thunder/graphql"
"github.com/samsarahq/thunder/graphql/schemabuilder"
"github.com/samsarahq/thunder/reactive"

Ran go mod tidy as well as gazelle.

What did you expect to see?

I did expect the compilation to be successful. Compiling the same with go build succeeds without issues.

What did you see instead?


ERROR: /private/var/tmp/_bazel_pmatri/f47f4751b0932c40306f84bc4b34e6c3/external/com_github_samsarahq_thunder/thunderpb/BUILD.bazel:15:17: no such package '@com_github_samsarahq_thunder//github.com/gogo/protobuf/gogoproto': BUILD file not found in directory 'github.com/gogo/protobuf/gogoproto' of external repository @com_github_samsarahq_thunder. Add a BUILD file to a directory to mark it as a package. and referenced by '@com_github_samsarahq_thunder//thunderpb:thunderpb_go_proto'
ERROR: Analysis of target '//domain/api/gateway/adapters/graphql:graphql' failed; build aborted: Analysis failed
INFO: Elapsed time: 0.446s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (1 packages loaded, 1 target configured)
    Fetching @local_config_xcode; fetching```

I am fairly new to Gazelle ; I assume this relates to Gazelle not creating BUILD files for dependencies of a proto file?

Are there workarounds?
pierreis commented 3 years ago

Generally, Bazelle fails compiling github.com/samsarahq/thunder/graphql in every case. Vendoring causes additional errors, which significantly impair Gazelle usability with this library:

ERROR: /home/joe/projects/monaco/vendor/github.com/samsarahq/thunder/thunderpb/BUILD.bazel:5:14: no such package 'github.com/gogo/protobuf/gogoproto': BUILD file not found in any of the following directories. Add a BUILD file to a directory to mark it as a package.
 - /home/joe/projects/monaco/github.com/gogo/protobuf/gogoproto and referenced by '//vendor/github.com/samsarahq/thunder/thunderpb:thunderpb_proto'
ERROR: Analysis of target '//domain/example/echo/server/cmd:cmd' failed; build aborted: Analysis failed

I would also seem like dependencies are set incorrectly in vendored mode for Proto files, with the following being generated for instance:

proto_library(
    name = "thunderpb_proto",
    srcs = ["dependency.proto"],
    visibility = ["//visibility:public"],
    deps = [
        "//github.com/gogo/protobuf/gogoproto:gogoproto_proto",
        "@com_google_protobuf//:timestamp_proto",
    ],
)

The dependency should have been //vendor/github.com/gogo/protobuf/gogoproto:gogoproto_proto in vendor mode.

jayconrod commented 3 years ago

Unfortunately, it's very difficult for Gazelle to handle cross-repository proto imports since proto import strings don't correspond well to repository names or remote paths. More information is in Go Protocol buffers. You may want to try the disable_global approach.

You may also need to set the import_prefix or strip_import_prefix attributes on proto_library targets if they're imported with strings that don't correspond to their locations within the repository, which is especially the case here.

Gazelle can set these automatically with the proto_import_prefix and proto_strip_import_prefix directives, though it's hard to get this working correctly.

jfirebaugh commented 3 years ago

I ran into this issue as well. Here is a minimal repro: https://github.com/jfirebaugh/gazelle_etcd

To spell out the workaround that I think @jayconrod is suggesting, it's adding

    build_file_proto_mode = "disable_global",  # keep

to the go_repository declaration for io_etcd_go_etcd_api_v3 (or com_github_samsarahq_thunder in the original example). In the case that you're generating the declaration with update-repos, the # keep will ensure that the line sticks around if you re-run update-repos.

Is there a situation where the default value for build_file_proto_mode will result in a valid generated go_proto_library rule for an external dependency? I'm not familiar with the generation logic but it doesn't seem like

    deps = ["//gogoproto:gogo_proto"],

would ever work inside an external dependency. Maybe disable_global could be the default there?