| # Copyright 2024 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """A filegroup grouping .proto and .options files.""" |
| |
| PwProtoOptionsInfo = provider( |
| "Allows `pw_proto_filegroup` targets to pass along `.options` files " + |
| "without polluting the `DefaultInfo` provider, which means they can " + |
| "still be used in the `srcs` of `proto_library` targets.", |
| fields = { |
| "options_files": (".options file(s) associated with a proto_library " + |
| "for Pigweed codegen."), |
| }, |
| ) |
| |
| def _pw_proto_filegroup_impl(ctx): |
| source_files = list() |
| options_files = list() |
| |
| for src in ctx.attr.srcs: |
| source_files += src.files.to_list() |
| |
| for options_src in ctx.attr.options_files: |
| for file in options_src.files.to_list(): |
| if file.extension == "options" or file.extension == "pwpb_options": |
| options_files.append(file) |
| else: |
| fail(( |
| "Files provided as `options_files` to a " + |
| "`pw_proto_filegroup` must have the `.options` or " + |
| "`.pwpb_options` extensions; the file `{}` was provided." |
| ).format(file.basename)) |
| |
| return [ |
| DefaultInfo(files = depset(source_files)), |
| PwProtoOptionsInfo(options_files = depset(options_files)), |
| ] |
| |
| pw_proto_filegroup = rule( |
| doc = ( |
| "Acts like a `filegroup`, but with an additional `options_files` " + |
| "attribute that accepts a list of `.options` files. These `.options` " + |
| "files should typically correspond to `.proto` files provided under " + |
| "the `srcs` attribute." + |
| "\n\n" + |
| "A `pw_proto_filegroup` is intended to be passed into the `srcs` of " + |
| "a `proto_library` target as if it were a normal `filegroup` " + |
| "containing only `.proto` files. For the purposes of the " + |
| "`proto_library` itself, the `pw_proto_filegroup` does indeed act " + |
| "just like a normal `filegroup`; the `options_files` attribute is " + |
| "ignored. However, if that `proto_library` target is then passed " + |
| "(directly or transitively) into the `deps` of a `pw_proto_library` " + |
| "for code generation, the `pw_proto_library` target will have access " + |
| "to the provided `.options` files and will pass them to the code " + |
| "generator." + |
| "\n\n" + |
| "Note that, in order for a `pw_proto_filegroup` to be a valid `srcs` " + |
| "entry for a `proto_library`, it must meet the same conditions " + |
| "required of a standard `filegroup` in that context. Namely, its " + |
| "`srcs` must provide at least one `.proto` (or `.protodevel`) file. " + |
| "Put simply, a `pw_proto_filegroup` cannot be used as a vector for " + |
| "injecting solely `.options` files; it must contain at least one " + |
| "proto as well (generally one associated with an included `.options` " + |
| "file in the interest of clarity)." + |
| "\n\n" + |
| "Regarding the somewhat unusual usage, this feature's design was " + |
| "mostly preordained by the combination of Bazel's strict access " + |
| "controls, the restrictions imposed on inputs to the `proto_library` " + |
| "rule, and the need to support `.options` files from transitive " + |
| "dependencies." |
| ), |
| implementation = _pw_proto_filegroup_impl, |
| attrs = { |
| "options_files": attr.label_list( |
| allow_files = True, |
| ), |
| "srcs": attr.label_list( |
| allow_files = True, |
| ), |
| }, |
| provides = [PwProtoOptionsInfo], |
| ) |