Skip to content
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

Support --include_imports equivalent in proto_library #57

Closed
djudd-stripe opened this issue Nov 30, 2017 · 15 comments
Closed

Support --include_imports equivalent in proto_library #57

djudd-stripe opened this issue Nov 30, 2017 · 15 comments
Assignees
Labels
duplicate This issue or pull request already exists

Comments

@djudd-stripe
Copy link

Description of the feature request:

We would find it useful to have an attribute on the native proto_library rule which causes it to behave like protoc when passed --include_imports, which would include all the transitive descriptor set contents in the output descriptor set. Supporting self-contained descriptor set outputs in this way would make it easier to write tooling that uses descriptor sets as the import/export unit for passing schemas between repos, which in our setting are not always built with Bazel, and it would bring the rule closer to feature parity with using protoc directly.

@cgrushko
Copy link

cgrushko commented Dec 2, 2017

Our internal solution for this, so far, is a tiny Skylark rule which concatenates the individual descriptors (protobuf's wire format allows for that) and exposes a single file.

Then we wrap a proto_library rule in that Skylark rule and get a single file.

I can run the code through the open-sourcing process and publish it, but really it's no more than cat ${list of files from proto.transitive_descriptor_sets} > $@

@cgrushko cgrushko assigned cgrushko and lberki and unassigned cgrushko Dec 2, 2017
@djudd-stripe
Copy link
Author

I'm doing the same thing, but I couldn't figure out how to get the result to be treated like or usable in a native proto_library.

@iirina iirina self-assigned this Dec 4, 2017
@drigz
Copy link

drigz commented Dec 11, 2017

When I invoke bazel build on a proto_library directly, it creates a descriptor set with protoc but doesn't use --include_imports. If this were added (maybe by default?) the output file would presumably be a complete descriptor set.

@iirina, WDYT? Would it just be a matter of adding --include_imports to createDescriptorSetToolchain?

We need such a descriptor set for deploying to Service Management and if I understand right, this would also be useful for @djudd-stripe. Additionally, from protocolbuffers/protobuf#2725, it sounds like @cgrushko was interested in using this with --descriptor_set_in to simplify Bazel's protoc invocations.

@cgrushko
Copy link

My objection to --include_imports is that the total output size is quadratic, which is a no-no for large proto graphs. We have plenty of those at Google :)

My solution from https://github.com/bazelbuild/bazel/issues/4201#issuecomment-348673194 is really the way to go if you need to collect all transitive descriptors at a single point.

protoc invocations can still be given all of the transitive descriptor sets separately (e.g., as separate command-line arguments) without proto_library concatenating them at each step.

@djudd-stripe 's use case is special because he's trying to bridge two build systems.

There's the possibility of controlling this using a configuration-wide option in Blaze, but we should be careful not to turn Bazel into a swamp of options.

I'll defer to @iirina and @lberki.

@drigz
Copy link

drigz commented Dec 12, 2017

@cgrushko Thanks for the explanation! That's a good reason not to make it the default.

We currently have a Skylark rule that converts transitive_srcs into command-line flags for protoc. Having read further, we probably need a descriptor set with --include_imports --include_source_info, in which case it's easiest to keep the rule we have.

EDIT: I found out that --include_source_info is not a requirement for Cloud Endpoints, and have switched to the cat ${transitive_descriptor_sets} approach @cgrushko suggested.

@RNabel
Copy link

RNabel commented Jun 19, 2018

@cgrushko, you mentioned that Google's workaround may be open-sourced: is there any progress there / has this already happened?

@cgrushko
Copy link

cgrushko commented Jun 19, 2018 via email

@drigz
Copy link

drigz commented Jun 19, 2018

@RNabel Here's what we're using:

# Copyright 2018 Google LLC.
# SPDX-License-Identifier: Apache-2.0

def paths(files):
  return [f.path for f in files]

def _impl(ctx):
  descriptors = ctx.attr.proto_library[ProtoInfo].transitive_descriptor_sets
  ctx.actions.run_shell(
    inputs=descriptors,
    outputs=[ctx.outputs.out],
    command='cat %s > %s' % (
        ' '.join(paths(descriptors)), ctx.outputs.out.path))

proto_descriptor = rule(
  implementation=_impl,
  attrs = {
    "proto_library": attr.label(),
    "out": attr.output(mandatory=True),
  }
)

You can then use it like:

load("//tools/build_rules:proto_descriptor.bzl", "proto_descriptor")

proto_descriptor(
    name = "proto_descriptor",
    out = "proto_descriptor.pb",
    proto_library = ":my_proto",
)

@RNabel
Copy link

RNabel commented Jun 19, 2018

Thanks both for the super-fast response - really useful!

@ngalaiko
Copy link

Thanks, that's awesome!

@krlvi
Copy link

krlvi commented Oct 2, 2019

Thanks! PSA - for anybody using this rule

descriptors = ctx.attr.proto_library.proto.transitive_descriptor_sets

will no longer work with bazel 1.0.0
Spent like an hour trying to figure this one out.

Replacing with

descriptors = ctx.attr.proto_library[ProtoInfo].transitive_descriptor_sets

is compliant it seems

@drigz
Copy link

drigz commented Oct 3, 2019

@krlvi, thanks for pointing this out, I've updated the comment.

@manlinl
Copy link

manlinl commented Feb 5, 2020

In bazel 1.2.1, you will need
descriptors = ctx.attr.proto_library[ProtoInfo].transitive_descriptor_sets.to_list()

@aiuto
Copy link

aiuto commented May 13, 2020

It seems like this is resolved for now, but there could be some docs around it.
Moving this to rules_proto as the documentation should go there eventually.

@aiuto aiuto transferred this issue from bazelbuild/bazel May 13, 2020
@Yannic
Copy link
Collaborator

Yannic commented May 13, 2020

Duplicating into #45

TL;DR rules_proto should provide a rule for this (similar to @drigz's rule above).

@Yannic Yannic closed this as completed May 13, 2020
@Yannic Yannic added the duplicate This issue or pull request already exists label May 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests