xref: /aosp_15_r20/external/bazel-skylib/rules/select_file.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1# Copyright 2020 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://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,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""
16select_file() build rule implementation.
17
18Selects a single file from the outputs of a target by given relative path.
19"""
20
21def _impl(ctx):
22    if ctx.attr.subpath and len(ctx.attr.subpath) == 0:
23        fail("Subpath can not be empty.")
24
25    out = None
26    canonical = ctx.attr.subpath.replace("\\", "/")
27    for file_ in ctx.attr.srcs.files.to_list():
28        if file_.path.replace("\\", "/").endswith(canonical):
29            out = file_
30            break
31    if not out:
32        files_str = ",\n".join([
33            str(f.path)
34            for f in ctx.attr.srcs.files.to_list()
35        ])
36        fail("Can not find specified file in [%s]" % files_str)
37    return [DefaultInfo(files = depset([out]))]
38
39select_file = rule(
40    implementation = _impl,
41    doc = "Selects a single file from the outputs of a target by given relative path",
42    attrs = {
43        "srcs": attr.label(
44            allow_files = True,
45            mandatory = True,
46            doc = "The target producing the file among other outputs",
47        ),
48        "subpath": attr.string(
49            mandatory = True,
50            doc = "Relative path to the file",
51        ),
52    },
53)
54