xref: /aosp_15_r20/external/bazelbuild-rules_python/sphinxdocs/private/sphinx_stardoc.bzl (revision 60517a1edbc8ecf509223e9af94a7adec7d736b8)
1*60517a1eSAndroid Build Coastguard Worker# Copyright 2023 The Bazel Authors. All rights reserved.
2*60517a1eSAndroid Build Coastguard Worker#
3*60517a1eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*60517a1eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*60517a1eSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*60517a1eSAndroid Build Coastguard Worker#
7*60517a1eSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*60517a1eSAndroid Build Coastguard Worker#
9*60517a1eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*60517a1eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*60517a1eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*60517a1eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*60517a1eSAndroid Build Coastguard Worker# limitations under the License.
14*60517a1eSAndroid Build Coastguard Worker
15*60517a1eSAndroid Build Coastguard Worker"""Rules to generate Sphinx-compatible documentation for bzl files."""
16*60517a1eSAndroid Build Coastguard Worker
17*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//:bzl_library.bzl", "StarlarkLibraryInfo")
18*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths")
19*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:types.bzl", "types")
20*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:build_test.bzl", "build_test")
21*60517a1eSAndroid Build Coastguard Workerload("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
22*60517a1eSAndroid Build Coastguard Workerload("//python/private:util.bzl", "add_tag", "copy_propagating_kwargs")  # buildifier: disable=bzl-visibility
23*60517a1eSAndroid Build Coastguard Workerload("//sphinxdocs/private:sphinx_docs_library_macro.bzl", "sphinx_docs_library")
24*60517a1eSAndroid Build Coastguard Worker
25*60517a1eSAndroid Build Coastguard Worker_StardocInputHelperInfo = provider(
26*60517a1eSAndroid Build Coastguard Worker    doc = "Extracts the single source file from a bzl library.",
27*60517a1eSAndroid Build Coastguard Worker    fields = {
28*60517a1eSAndroid Build Coastguard Worker        "file": """
29*60517a1eSAndroid Build Coastguard Worker:type: File
30*60517a1eSAndroid Build Coastguard Worker
31*60517a1eSAndroid Build Coastguard WorkerThe sole output file from the wrapped target.
32*60517a1eSAndroid Build Coastguard Worker""",
33*60517a1eSAndroid Build Coastguard Worker    },
34*60517a1eSAndroid Build Coastguard Worker)
35*60517a1eSAndroid Build Coastguard Worker
36*60517a1eSAndroid Build Coastguard Workerdef sphinx_stardocs(
37*60517a1eSAndroid Build Coastguard Worker        *,
38*60517a1eSAndroid Build Coastguard Worker        name,
39*60517a1eSAndroid Build Coastguard Worker        srcs = [],
40*60517a1eSAndroid Build Coastguard Worker        deps = [],
41*60517a1eSAndroid Build Coastguard Worker        docs = {},
42*60517a1eSAndroid Build Coastguard Worker        prefix = None,
43*60517a1eSAndroid Build Coastguard Worker        strip_prefix = None,
44*60517a1eSAndroid Build Coastguard Worker        **kwargs):
45*60517a1eSAndroid Build Coastguard Worker    """Generate Sphinx-friendly Markdown docs using Stardoc for bzl libraries.
46*60517a1eSAndroid Build Coastguard Worker
47*60517a1eSAndroid Build Coastguard Worker    A `build_test` for the docs is also generated to ensure Stardoc is able
48*60517a1eSAndroid Build Coastguard Worker    to process the files.
49*60517a1eSAndroid Build Coastguard Worker
50*60517a1eSAndroid Build Coastguard Worker    NOTE: This generates MyST-flavored Markdown.
51*60517a1eSAndroid Build Coastguard Worker
52*60517a1eSAndroid Build Coastguard Worker    Args:
53*60517a1eSAndroid Build Coastguard Worker        name: {type}`Name`, the name of the resulting file group with the generated docs.
54*60517a1eSAndroid Build Coastguard Worker        srcs: {type}`list[label]` Each source is either the bzl file to process
55*60517a1eSAndroid Build Coastguard Worker            or a `bzl_library` target with one source file of the bzl file to
56*60517a1eSAndroid Build Coastguard Worker            process.
57*60517a1eSAndroid Build Coastguard Worker        deps: {type}`list[label]` Targets that provide files loaded by `src`
58*60517a1eSAndroid Build Coastguard Worker        docs: {type}`dict[str, str|dict]` of the bzl files to generate documentation
59*60517a1eSAndroid Build Coastguard Worker            for. The `output` key is the path of the output filename, e.g.,
60*60517a1eSAndroid Build Coastguard Worker            `foo/bar.md`. The `source` values can be either of:
61*60517a1eSAndroid Build Coastguard Worker            * A `str` label that points to a `bzl_library` target. The target
62*60517a1eSAndroid Build Coastguard Worker              name will replace `_bzl` with `.bzl` and use that as the input
63*60517a1eSAndroid Build Coastguard Worker              bzl file to generate docs for. The target itself provides the
64*60517a1eSAndroid Build Coastguard Worker              necessary dependencies.
65*60517a1eSAndroid Build Coastguard Worker            * A `dict` with keys `input` and `dep`. The `input` key is a string
66*60517a1eSAndroid Build Coastguard Worker              label to the bzl file to generate docs for. The `dep` key is a
67*60517a1eSAndroid Build Coastguard Worker              string label to a `bzl_library` providing the necessary dependencies.
68*60517a1eSAndroid Build Coastguard Worker        prefix: {type}`str` Prefix to add to the output file path. It is prepended
69*60517a1eSAndroid Build Coastguard Worker            after `strip_prefix` is removed.
70*60517a1eSAndroid Build Coastguard Worker        strip_prefix: {type}`str | None` Prefix to remove from the input file path;
71*60517a1eSAndroid Build Coastguard Worker            it is removed before `prefix` is prepended. If not specified, then
72*60517a1eSAndroid Build Coastguard Worker            {any}`native.package_name` is used.
73*60517a1eSAndroid Build Coastguard Worker        **kwargs: Additional kwargs to pass onto each `sphinx_stardoc` target
74*60517a1eSAndroid Build Coastguard Worker    """
75*60517a1eSAndroid Build Coastguard Worker    internal_name = "_{}".format(name)
76*60517a1eSAndroid Build Coastguard Worker    add_tag(kwargs, "@rules_python//sphinxdocs:sphinx_stardocs")
77*60517a1eSAndroid Build Coastguard Worker    common_kwargs = copy_propagating_kwargs(kwargs)
78*60517a1eSAndroid Build Coastguard Worker    common_kwargs["target_compatible_with"] = kwargs.get("target_compatible_with")
79*60517a1eSAndroid Build Coastguard Worker
80*60517a1eSAndroid Build Coastguard Worker    stardocs = []
81*60517a1eSAndroid Build Coastguard Worker    for out_name, entry in docs.items():
82*60517a1eSAndroid Build Coastguard Worker        stardoc_kwargs = {}
83*60517a1eSAndroid Build Coastguard Worker        stardoc_kwargs.update(kwargs)
84*60517a1eSAndroid Build Coastguard Worker
85*60517a1eSAndroid Build Coastguard Worker        if types.is_string(entry):
86*60517a1eSAndroid Build Coastguard Worker            stardoc_kwargs["deps"] = [entry]
87*60517a1eSAndroid Build Coastguard Worker            stardoc_kwargs["src"] = entry.replace("_bzl", ".bzl")
88*60517a1eSAndroid Build Coastguard Worker        else:
89*60517a1eSAndroid Build Coastguard Worker            stardoc_kwargs.update(entry)
90*60517a1eSAndroid Build Coastguard Worker
91*60517a1eSAndroid Build Coastguard Worker            # input is accepted for backwards compatiblity. Remove when ready.
92*60517a1eSAndroid Build Coastguard Worker            if "src" not in stardoc_kwargs and "input" in stardoc_kwargs:
93*60517a1eSAndroid Build Coastguard Worker                stardoc_kwargs["src"] = stardoc_kwargs.pop("input")
94*60517a1eSAndroid Build Coastguard Worker            stardoc_kwargs["deps"] = [stardoc_kwargs.pop("dep")]
95*60517a1eSAndroid Build Coastguard Worker
96*60517a1eSAndroid Build Coastguard Worker        doc_name = "{}_{}".format(internal_name, _name_from_label(out_name))
97*60517a1eSAndroid Build Coastguard Worker        sphinx_stardoc(
98*60517a1eSAndroid Build Coastguard Worker            name = doc_name,
99*60517a1eSAndroid Build Coastguard Worker            output = out_name,
100*60517a1eSAndroid Build Coastguard Worker            create_test = False,
101*60517a1eSAndroid Build Coastguard Worker            **stardoc_kwargs
102*60517a1eSAndroid Build Coastguard Worker        )
103*60517a1eSAndroid Build Coastguard Worker        stardocs.append(doc_name)
104*60517a1eSAndroid Build Coastguard Worker
105*60517a1eSAndroid Build Coastguard Worker    for label in srcs:
106*60517a1eSAndroid Build Coastguard Worker        doc_name = "{}_{}".format(internal_name, _name_from_label(label))
107*60517a1eSAndroid Build Coastguard Worker        sphinx_stardoc(
108*60517a1eSAndroid Build Coastguard Worker            name = doc_name,
109*60517a1eSAndroid Build Coastguard Worker            src = label,
110*60517a1eSAndroid Build Coastguard Worker            # NOTE: We set prefix/strip_prefix here instead of
111*60517a1eSAndroid Build Coastguard Worker            # on the sphinx_docs_library so that building the
112*60517a1eSAndroid Build Coastguard Worker            # target produces markdown files in the expected location, which
113*60517a1eSAndroid Build Coastguard Worker            # is convenient.
114*60517a1eSAndroid Build Coastguard Worker            prefix = prefix,
115*60517a1eSAndroid Build Coastguard Worker            strip_prefix = strip_prefix,
116*60517a1eSAndroid Build Coastguard Worker            deps = deps,
117*60517a1eSAndroid Build Coastguard Worker            create_test = False,
118*60517a1eSAndroid Build Coastguard Worker            **common_kwargs
119*60517a1eSAndroid Build Coastguard Worker        )
120*60517a1eSAndroid Build Coastguard Worker        stardocs.append(doc_name)
121*60517a1eSAndroid Build Coastguard Worker
122*60517a1eSAndroid Build Coastguard Worker    sphinx_docs_library(
123*60517a1eSAndroid Build Coastguard Worker        name = name,
124*60517a1eSAndroid Build Coastguard Worker        deps = stardocs,
125*60517a1eSAndroid Build Coastguard Worker        **common_kwargs
126*60517a1eSAndroid Build Coastguard Worker    )
127*60517a1eSAndroid Build Coastguard Worker    if stardocs:
128*60517a1eSAndroid Build Coastguard Worker        build_test(
129*60517a1eSAndroid Build Coastguard Worker            name = name + "_build_test",
130*60517a1eSAndroid Build Coastguard Worker            targets = stardocs,
131*60517a1eSAndroid Build Coastguard Worker            **common_kwargs
132*60517a1eSAndroid Build Coastguard Worker        )
133*60517a1eSAndroid Build Coastguard Worker
134*60517a1eSAndroid Build Coastguard Workerdef sphinx_stardoc(
135*60517a1eSAndroid Build Coastguard Worker        name,
136*60517a1eSAndroid Build Coastguard Worker        src,
137*60517a1eSAndroid Build Coastguard Worker        deps = [],
138*60517a1eSAndroid Build Coastguard Worker        public_load_path = None,
139*60517a1eSAndroid Build Coastguard Worker        prefix = None,
140*60517a1eSAndroid Build Coastguard Worker        strip_prefix = None,
141*60517a1eSAndroid Build Coastguard Worker        create_test = True,
142*60517a1eSAndroid Build Coastguard Worker        output = None,
143*60517a1eSAndroid Build Coastguard Worker        **kwargs):
144*60517a1eSAndroid Build Coastguard Worker    """Generate Sphinx-friendly Markdown for a single bzl file.
145*60517a1eSAndroid Build Coastguard Worker
146*60517a1eSAndroid Build Coastguard Worker    Args:
147*60517a1eSAndroid Build Coastguard Worker        name: {type}`Name` name for the target.
148*60517a1eSAndroid Build Coastguard Worker        src: {type}`label` The bzl file to process, or a `bzl_library`
149*60517a1eSAndroid Build Coastguard Worker            target with one source file of the bzl file to process.
150*60517a1eSAndroid Build Coastguard Worker        deps: {type}`list[label]` Targets that provide files loaded by `src`
151*60517a1eSAndroid Build Coastguard Worker        public_load_path: {type}`str | None` override the file name that
152*60517a1eSAndroid Build Coastguard Worker            is reported as the file being.
153*60517a1eSAndroid Build Coastguard Worker        prefix: {type}`str | None` prefix to add to the output file path
154*60517a1eSAndroid Build Coastguard Worker        strip_prefix: {type}`str | None` Prefix to remove from the input file path.
155*60517a1eSAndroid Build Coastguard Worker            If not specified, then {any}`native.package_name` is used.
156*60517a1eSAndroid Build Coastguard Worker        create_test: {type}`bool` True if a test should be defined to verify the
157*60517a1eSAndroid Build Coastguard Worker            docs are buildable, False if not.
158*60517a1eSAndroid Build Coastguard Worker        output: {type}`str | None` Optional explicit output file to use. If
159*60517a1eSAndroid Build Coastguard Worker            not set, the output name will be derived from `src`.
160*60517a1eSAndroid Build Coastguard Worker        **kwargs: {type}`dict` common args passed onto rules.
161*60517a1eSAndroid Build Coastguard Worker    """
162*60517a1eSAndroid Build Coastguard Worker    internal_name = "_{}".format(name.lstrip("_"))
163*60517a1eSAndroid Build Coastguard Worker    add_tag(kwargs, "@rules_python//sphinxdocs:sphinx_stardoc")
164*60517a1eSAndroid Build Coastguard Worker    common_kwargs = copy_propagating_kwargs(kwargs)
165*60517a1eSAndroid Build Coastguard Worker    common_kwargs["target_compatible_with"] = kwargs.get("target_compatible_with")
166*60517a1eSAndroid Build Coastguard Worker
167*60517a1eSAndroid Build Coastguard Worker    input_helper_name = internal_name + ".primary_bzl_src"
168*60517a1eSAndroid Build Coastguard Worker    _stardoc_input_helper(
169*60517a1eSAndroid Build Coastguard Worker        name = input_helper_name,
170*60517a1eSAndroid Build Coastguard Worker        target = src,
171*60517a1eSAndroid Build Coastguard Worker        **common_kwargs
172*60517a1eSAndroid Build Coastguard Worker    )
173*60517a1eSAndroid Build Coastguard Worker
174*60517a1eSAndroid Build Coastguard Worker    stardoc_name = internal_name + "_stardoc"
175*60517a1eSAndroid Build Coastguard Worker
176*60517a1eSAndroid Build Coastguard Worker    # NOTE: The .binaryproto suffix is an optimization. It makes the stardoc()
177*60517a1eSAndroid Build Coastguard Worker    # call avoid performing a copy of the output to the desired name.
178*60517a1eSAndroid Build Coastguard Worker    stardoc_pb = stardoc_name + ".binaryproto"
179*60517a1eSAndroid Build Coastguard Worker
180*60517a1eSAndroid Build Coastguard Worker    stardoc(
181*60517a1eSAndroid Build Coastguard Worker        name = stardoc_name,
182*60517a1eSAndroid Build Coastguard Worker        input = input_helper_name,
183*60517a1eSAndroid Build Coastguard Worker        out = stardoc_pb,
184*60517a1eSAndroid Build Coastguard Worker        format = "proto",
185*60517a1eSAndroid Build Coastguard Worker        deps = [src] + deps,
186*60517a1eSAndroid Build Coastguard Worker        **common_kwargs
187*60517a1eSAndroid Build Coastguard Worker    )
188*60517a1eSAndroid Build Coastguard Worker
189*60517a1eSAndroid Build Coastguard Worker    pb2md_name = internal_name + "_pb2md"
190*60517a1eSAndroid Build Coastguard Worker    _stardoc_proto_to_markdown(
191*60517a1eSAndroid Build Coastguard Worker        name = pb2md_name,
192*60517a1eSAndroid Build Coastguard Worker        src = stardoc_pb,
193*60517a1eSAndroid Build Coastguard Worker        output = output,
194*60517a1eSAndroid Build Coastguard Worker        output_name_from = input_helper_name if not output else None,
195*60517a1eSAndroid Build Coastguard Worker        public_load_path = public_load_path,
196*60517a1eSAndroid Build Coastguard Worker        strip_prefix = strip_prefix,
197*60517a1eSAndroid Build Coastguard Worker        prefix = prefix,
198*60517a1eSAndroid Build Coastguard Worker        **common_kwargs
199*60517a1eSAndroid Build Coastguard Worker    )
200*60517a1eSAndroid Build Coastguard Worker    sphinx_docs_library(
201*60517a1eSAndroid Build Coastguard Worker        name = name,
202*60517a1eSAndroid Build Coastguard Worker        srcs = [pb2md_name],
203*60517a1eSAndroid Build Coastguard Worker        **common_kwargs
204*60517a1eSAndroid Build Coastguard Worker    )
205*60517a1eSAndroid Build Coastguard Worker    if create_test:
206*60517a1eSAndroid Build Coastguard Worker        build_test(
207*60517a1eSAndroid Build Coastguard Worker            name = name + "_build_test",
208*60517a1eSAndroid Build Coastguard Worker            targets = [name],
209*60517a1eSAndroid Build Coastguard Worker            **common_kwargs
210*60517a1eSAndroid Build Coastguard Worker        )
211*60517a1eSAndroid Build Coastguard Worker
212*60517a1eSAndroid Build Coastguard Workerdef _stardoc_input_helper_impl(ctx):
213*60517a1eSAndroid Build Coastguard Worker    target = ctx.attr.target
214*60517a1eSAndroid Build Coastguard Worker    if StarlarkLibraryInfo in target:
215*60517a1eSAndroid Build Coastguard Worker        files = ctx.attr.target[StarlarkLibraryInfo].srcs
216*60517a1eSAndroid Build Coastguard Worker    else:
217*60517a1eSAndroid Build Coastguard Worker        files = target[DefaultInfo].files.to_list()
218*60517a1eSAndroid Build Coastguard Worker
219*60517a1eSAndroid Build Coastguard Worker    if len(files) == 0:
220*60517a1eSAndroid Build Coastguard Worker        fail("Target {} produces no files, but must produce exactly 1 file".format(
221*60517a1eSAndroid Build Coastguard Worker            ctx.attr.target.label,
222*60517a1eSAndroid Build Coastguard Worker        ))
223*60517a1eSAndroid Build Coastguard Worker    elif len(files) == 1:
224*60517a1eSAndroid Build Coastguard Worker        primary = files[0]
225*60517a1eSAndroid Build Coastguard Worker    else:
226*60517a1eSAndroid Build Coastguard Worker        fail("Target {} produces {} files, but must produce exactly 1 file.".format(
227*60517a1eSAndroid Build Coastguard Worker            ctx.attr.target.label,
228*60517a1eSAndroid Build Coastguard Worker            len(files),
229*60517a1eSAndroid Build Coastguard Worker        ))
230*60517a1eSAndroid Build Coastguard Worker
231*60517a1eSAndroid Build Coastguard Worker    return [
232*60517a1eSAndroid Build Coastguard Worker        DefaultInfo(
233*60517a1eSAndroid Build Coastguard Worker            files = depset([primary]),
234*60517a1eSAndroid Build Coastguard Worker        ),
235*60517a1eSAndroid Build Coastguard Worker        _StardocInputHelperInfo(
236*60517a1eSAndroid Build Coastguard Worker            file = primary,
237*60517a1eSAndroid Build Coastguard Worker        ),
238*60517a1eSAndroid Build Coastguard Worker    ]
239*60517a1eSAndroid Build Coastguard Worker
240*60517a1eSAndroid Build Coastguard Worker_stardoc_input_helper = rule(
241*60517a1eSAndroid Build Coastguard Worker    implementation = _stardoc_input_helper_impl,
242*60517a1eSAndroid Build Coastguard Worker    attrs = {
243*60517a1eSAndroid Build Coastguard Worker        "target": attr.label(allow_files = True),
244*60517a1eSAndroid Build Coastguard Worker    },
245*60517a1eSAndroid Build Coastguard Worker)
246*60517a1eSAndroid Build Coastguard Worker
247*60517a1eSAndroid Build Coastguard Workerdef _stardoc_proto_to_markdown_impl(ctx):
248*60517a1eSAndroid Build Coastguard Worker    args = ctx.actions.args()
249*60517a1eSAndroid Build Coastguard Worker    args.use_param_file("@%s")
250*60517a1eSAndroid Build Coastguard Worker    args.set_param_file_format("multiline")
251*60517a1eSAndroid Build Coastguard Worker
252*60517a1eSAndroid Build Coastguard Worker    inputs = [ctx.file.src]
253*60517a1eSAndroid Build Coastguard Worker    args.add("--proto", ctx.file.src)
254*60517a1eSAndroid Build Coastguard Worker
255*60517a1eSAndroid Build Coastguard Worker    if not ctx.outputs.output:
256*60517a1eSAndroid Build Coastguard Worker        output_name = ctx.attr.output_name_from[_StardocInputHelperInfo].file.short_path
257*60517a1eSAndroid Build Coastguard Worker        output_name = paths.replace_extension(output_name, ".md")
258*60517a1eSAndroid Build Coastguard Worker        output_name = ctx.attr.prefix + output_name.removeprefix(ctx.attr.strip_prefix)
259*60517a1eSAndroid Build Coastguard Worker        output = ctx.actions.declare_file(output_name)
260*60517a1eSAndroid Build Coastguard Worker    else:
261*60517a1eSAndroid Build Coastguard Worker        output = ctx.outputs.output
262*60517a1eSAndroid Build Coastguard Worker
263*60517a1eSAndroid Build Coastguard Worker    args.add("--output", output)
264*60517a1eSAndroid Build Coastguard Worker
265*60517a1eSAndroid Build Coastguard Worker    if ctx.attr.public_load_path:
266*60517a1eSAndroid Build Coastguard Worker        args.add("--public-load-path={}".format(ctx.attr.public_load_path))
267*60517a1eSAndroid Build Coastguard Worker
268*60517a1eSAndroid Build Coastguard Worker    ctx.actions.run(
269*60517a1eSAndroid Build Coastguard Worker        executable = ctx.executable._proto_to_markdown,
270*60517a1eSAndroid Build Coastguard Worker        arguments = [args],
271*60517a1eSAndroid Build Coastguard Worker        inputs = inputs,
272*60517a1eSAndroid Build Coastguard Worker        outputs = [output],
273*60517a1eSAndroid Build Coastguard Worker        mnemonic = "SphinxStardocProtoToMd",
274*60517a1eSAndroid Build Coastguard Worker        progress_message = "SphinxStardoc: converting proto to markdown: %{input} -> %{output}",
275*60517a1eSAndroid Build Coastguard Worker    )
276*60517a1eSAndroid Build Coastguard Worker    return [DefaultInfo(
277*60517a1eSAndroid Build Coastguard Worker        files = depset([output]),
278*60517a1eSAndroid Build Coastguard Worker    )]
279*60517a1eSAndroid Build Coastguard Worker
280*60517a1eSAndroid Build Coastguard Worker_stardoc_proto_to_markdown = rule(
281*60517a1eSAndroid Build Coastguard Worker    implementation = _stardoc_proto_to_markdown_impl,
282*60517a1eSAndroid Build Coastguard Worker    attrs = {
283*60517a1eSAndroid Build Coastguard Worker        "output": attr.output(mandatory = False),
284*60517a1eSAndroid Build Coastguard Worker        "output_name_from": attr.label(),
285*60517a1eSAndroid Build Coastguard Worker        "prefix": attr.string(),
286*60517a1eSAndroid Build Coastguard Worker        "public_load_path": attr.string(),
287*60517a1eSAndroid Build Coastguard Worker        "src": attr.label(allow_single_file = True, mandatory = True),
288*60517a1eSAndroid Build Coastguard Worker        "strip_prefix": attr.string(),
289*60517a1eSAndroid Build Coastguard Worker        "_proto_to_markdown": attr.label(
290*60517a1eSAndroid Build Coastguard Worker            default = "//sphinxdocs/private:proto_to_markdown",
291*60517a1eSAndroid Build Coastguard Worker            executable = True,
292*60517a1eSAndroid Build Coastguard Worker            cfg = "exec",
293*60517a1eSAndroid Build Coastguard Worker        ),
294*60517a1eSAndroid Build Coastguard Worker    },
295*60517a1eSAndroid Build Coastguard Worker)
296*60517a1eSAndroid Build Coastguard Worker
297*60517a1eSAndroid Build Coastguard Workerdef _name_from_label(label):
298*60517a1eSAndroid Build Coastguard Worker    label = label.lstrip("/").lstrip(":").replace(":", "/")
299*60517a1eSAndroid Build Coastguard Worker    return label
300