• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""A filegroup grouping .proto and .options files."""
15
16PwProtoOptionsInfo = provider(
17    "Allows `pw_proto_filegroup` targets to pass along `.options` files " +
18    "without polluting the `DefaultInfo` provider, which means they can " +
19    "still be used in the `srcs` of `proto_library` targets.",
20    fields = {
21        "options_files": (".options file(s) associated with a proto_library " +
22                          "for Pigweed codegen."),
23    },
24)
25
26def _pw_proto_filegroup_impl(ctx):
27    source_files = list()
28    options_files = list()
29
30    for src in ctx.attr.srcs:
31        source_files += src.files.to_list()
32
33    for options_src in ctx.attr.options_files:
34        for file in options_src.files.to_list():
35            if file.extension == "options" or file.extension == "pwpb_options":
36                options_files.append(file)
37            else:
38                fail((
39                    "Files provided as `options_files` to a " +
40                    "`pw_proto_filegroup` must have the `.options` or " +
41                    "`.pwpb_options` extensions; the file `{}` was provided."
42                ).format(file.basename))
43
44    return [
45        DefaultInfo(files = depset(source_files)),
46        PwProtoOptionsInfo(options_files = depset(options_files)),
47    ]
48
49pw_proto_filegroup = rule(
50    doc = (
51        "Acts like a `filegroup`, but with an additional `options_files` " +
52        "attribute that accepts a list of `.options` files. These `.options` " +
53        "files should typically correspond to `.proto` files provided under " +
54        "the `srcs` attribute." +
55        "\n\n" +
56        "A `pw_proto_filegroup` is intended to be passed into the `srcs` of " +
57        "a `proto_library` target as if it were a normal `filegroup` " +
58        "containing only `.proto` files. For the purposes of the " +
59        "`proto_library` itself, the `pw_proto_filegroup` does indeed act " +
60        "just like a normal `filegroup`; the `options_files` attribute is " +
61        "ignored. However, if that `proto_library` target is then passed " +
62        "(directly or transitively) into the `deps` of a `pw_proto_library` " +
63        "for code generation, the `pw_proto_library` target will have access " +
64        "to the provided `.options` files and will pass them to the code " +
65        "generator." +
66        "\n\n" +
67        "Note that, in order for a `pw_proto_filegroup` to be a valid `srcs` " +
68        "entry for a `proto_library`, it must meet the same conditions " +
69        "required of a standard `filegroup` in that context. Namely, its " +
70        "`srcs` must provide at least one `.proto` (or `.protodevel`) file. " +
71        "Put simply, a `pw_proto_filegroup` cannot be used as a vector for " +
72        "injecting solely `.options` files; it must contain at least one " +
73        "proto as well (generally one associated with an included `.options` " +
74        "file in the interest of clarity)." +
75        "\n\n" +
76        "Regarding the somewhat unusual usage, this feature's design was " +
77        "mostly preordained by the combination of Bazel's strict access " +
78        "controls, the restrictions imposed on inputs to the `proto_library` " +
79        "rule, and the need to support `.options` files from transitive " +
80        "dependencies."
81    ),
82    implementation = _pw_proto_filegroup_impl,
83    attrs = {
84        "options_files": attr.label_list(
85            allow_files = True,
86        ),
87        "srcs": attr.label_list(
88            allow_files = True,
89        ),
90    },
91    provides = [PwProtoOptionsInfo],
92)
93