You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
3.8 KiB
80 lines
3.8 KiB
# Borrowed from |
|
# https://github.com/bazelbuild/rules_go/blob/master/proto/toolchain.bzl. This |
|
# does some magic munging to remove workspace prefixes from output paths to |
|
# convert path as understood by Bazel into paths as understood by protoc. |
|
def _proto_path(proto): |
|
""" |
|
The proto path is not really a file path |
|
It's the path to the proto that was seen when the descriptor file was generated. |
|
""" |
|
path = proto.path |
|
root = proto.root.path |
|
ws = proto.owner.workspace_root |
|
if path.startswith(root): path = path[len(root):] |
|
if path.startswith("/"): path = path[1:] |
|
if path.startswith(ws): path = path[len(ws):] |
|
if path.startswith("/"): path = path[1:] |
|
return path |
|
|
|
# Bazel aspect (https://docs.bazel.build/versions/master/skylark/aspects.html) |
|
# that can be invoked from the CLI to produce docs via //tools/protodoc for |
|
# proto_library targets. Example use: |
|
# |
|
# bazel build //api --aspects tools/protodoc/protodoc.bzl%proto_doc_aspect \ |
|
# --output_groups=rst |
|
# |
|
# The aspect builds the transitive docs, so any .proto in the dependency graph |
|
# get docs created. |
|
def _proto_doc_aspect_impl(target, ctx): |
|
# Compute RST files from the current proto_library node's dependencies. |
|
transitive_outputs = depset() |
|
for dep in ctx.rule.attr.deps: |
|
transitive_outputs = transitive_outputs | dep.output_groups["rst"] |
|
proto_sources = target.proto.direct_sources |
|
# If this proto_library doesn't actually name any sources, e.g. //api:api, |
|
# but just glues together other libs, we just need to follow the graph. |
|
if not proto_sources: |
|
return [OutputGroupInfo(rst=transitive_outputs)] |
|
# Figure out the set of import paths. Ideally we would use descriptor sets |
|
# built by proto_library, which avoid having to do nasty path mangling, but |
|
# these don't include source_code_info, which we need for comment |
|
# extractions. See https://github.com/bazelbuild/bazel/issues/3971. |
|
import_paths = [] |
|
for f in target.proto.transitive_sources: |
|
if f.root.path: |
|
import_path = f.root.path + "/" + f.owner.workspace_root |
|
else: |
|
import_path = f.owner.workspace_root |
|
if import_path: |
|
import_paths += [import_path] |
|
# The outputs live in the ctx.label's package root. We add some additional |
|
# path information to match with protoc's notion of path relative locations. |
|
outputs = [ctx.actions.declare_file(ctx.label.name + "/" + _proto_path(f) + |
|
".rst") for f in proto_sources] |
|
# Create the protoc command-line args. |
|
ctx_path = ctx.label.package + "/" + ctx.label.name |
|
output_path = outputs[0].root.path + "/" + outputs[0].owner.workspace_root + "/" + ctx_path |
|
args = ["-I./" + ctx.label.workspace_root] |
|
args += ["-I" + import_path for import_path in import_paths] |
|
args += ["--plugin=protoc-gen-protodoc=" + ctx.executable._protodoc.path, "--protodoc_out=" + output_path] |
|
args += [_proto_path(src) for src in target.proto.direct_sources] |
|
ctx.action(executable=ctx.executable._protoc, |
|
arguments=args, |
|
inputs=[ctx.executable._protodoc] + target.proto.transitive_sources.to_list(), |
|
outputs=outputs, |
|
mnemonic="ProtoDoc", |
|
use_default_shell_env=True) |
|
transitive_outputs = depset(outputs) | transitive_outputs |
|
return [OutputGroupInfo(rst=transitive_outputs)] |
|
|
|
proto_doc_aspect = aspect(implementation = _proto_doc_aspect_impl, |
|
attr_aspects = ["deps"], |
|
attrs = { |
|
"_protoc": attr.label(default=Label("@com_google_protobuf//:protoc"), |
|
executable=True, |
|
cfg="host"), |
|
"_protodoc": attr.label(default=Label("//tools/protodoc"), |
|
executable=True, |
|
cfg="host"), |
|
} |
|
)
|
|
|