1# Copyright (C) 2022 The Android Open Source Project 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"""Impl of `exec`.""" 16 17load(":exec_aspect.bzl", "ExecAspectInfo", "exec_aspect") 18 19visibility([ 20 "//build/bazel_common_rules/exec/...", 21 "//build/kernel/kleaf/...", 22]) 23 24_DEFAULT_HASHBANG = "/bin/bash -e" 25 26def _impl(ctx): 27 out_file = ctx.actions.declare_file(ctx.label.name) 28 29 for target in ctx.attr.data: 30 if ExecAspectInfo not in target: 31 continue 32 if target[ExecAspectInfo].args: 33 fail("{}: {} must not have args. Use embedded_exec to wrap it.".format(ctx.label, target.label)) 34 if target[ExecAspectInfo].env: 35 fail("{}: {} must not have env. Use embedded_exec to wrap it.".format(ctx.label, target.label)) 36 37 content = "#!{}\n".format(ctx.attr.hashbang) 38 content += ctx.attr.script 39 40 content = ctx.expand_location(content, ctx.attr.data) 41 ctx.actions.write(out_file, content, is_executable = True) 42 43 runfiles = ctx.runfiles(files = ctx.files.data + [out_file]) 44 runfiles = runfiles.merge_all([target[DefaultInfo].default_runfiles for target in ctx.attr.data]) 45 46 return DefaultInfo( 47 files = depset([out_file]), 48 executable = out_file, 49 runfiles = runfiles, 50 ) 51 52exec = rule( 53 implementation = _impl, 54 doc = """Run a script when `bazel run` this target. 55 56See [documentation] for the `args` attribute. 57 58**NOTE**: Like [genrule](https://bazel.build/reference/be/general#genrule)s, 59hermeticity is not enforced or guaranteed, especially if `script` accesses PATH. 60See [`Genrule Environment`](https://bazel.build/reference/be/general#genrule-environment) 61for details. 62""", 63 attrs = { 64 "data": attr.label_list(aspects = [exec_aspect], allow_files = True, doc = """A list of labels providing runfiles. Labels may be used in `script`. 65 66Executables in `data` must not have the `args` and `env` attribute. Use 67[`embedded_exec`](#embedded_exec) to wrap the depended target so its env and args 68are preserved. 69"""), 70 "hashbang": attr.string(default = _DEFAULT_HASHBANG, doc = "Hashbang of the script."), 71 "script": attr.string(doc = """The script. 72 73Use `$(rootpath <label>)` to refer to the path of a target specified in `data`. See 74[documentation](https://bazel.build/reference/be/make-variables#predefined_label_variables). 75 76Use `$@` to refer to the args attribute of this target. 77 78See `build/bazel_common_rules/exec/tests/BUILD` for examples. 79"""), 80 }, 81 executable = True, 82) 83 84exec_test = rule( 85 implementation = _impl, 86 doc = """Run a test script when `bazel test` this target. 87 88See [documentation] for the `args` attribute. 89 90**NOTE**: Like [genrule](https://bazel.build/reference/be/general#genrule)s, 91hermeticity is not enforced or guaranteed, especially if `script` accesses PATH. 92See [`Genrule Environment`](https://bazel.build/reference/be/general#genrule-environment) 93for details. 94""", 95 attrs = { 96 "data": attr.label_list(aspects = [exec_aspect], allow_files = True, doc = """A list of labels providing runfiles. Labels may be used in `script`. 97 98Executables in `data` must not have the `args` and `env` attribute. Use 99[`embedded_exec`](#embedded_exec) to wrap the depended target so its env and args 100are preserved. 101"""), 102 "hashbang": attr.string(default = _DEFAULT_HASHBANG, doc = "Hashbang of the script."), 103 "script": attr.string(doc = """The script. 104 105Use `$(rootpath <label>)` to refer to the path of a target specified in `data`. See 106[documentation](https://bazel.build/reference/be/make-variables#predefined_label_variables). 107 108Use `$@` to refer to the args attribute of this target. 109 110See `build/bazel_common_rules/exec/tests/BUILD` for examples. 111"""), 112 }, 113 test = True, 114) 115