1*7887bec8SAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7887bec8SAndroid Build Coastguard Worker# 3*7887bec8SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7887bec8SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7887bec8SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7887bec8SAndroid Build Coastguard Worker# 7*7887bec8SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7887bec8SAndroid Build Coastguard Worker# 9*7887bec8SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7887bec8SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7887bec8SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7887bec8SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7887bec8SAndroid Build Coastguard Worker# limitations under the License. 14*7887bec8SAndroid Build Coastguard Worker 15*7887bec8SAndroid Build Coastguard Worker"""Impl of `exec`.""" 16*7887bec8SAndroid Build Coastguard Worker 17*7887bec8SAndroid Build Coastguard Workerload(":exec_aspect.bzl", "ExecAspectInfo", "exec_aspect") 18*7887bec8SAndroid Build Coastguard Worker 19*7887bec8SAndroid Build Coastguard Workervisibility([ 20*7887bec8SAndroid Build Coastguard Worker "//build/bazel_common_rules/exec/...", 21*7887bec8SAndroid Build Coastguard Worker "//build/kernel/kleaf/...", 22*7887bec8SAndroid Build Coastguard Worker]) 23*7887bec8SAndroid Build Coastguard Worker 24*7887bec8SAndroid Build Coastguard Worker_DEFAULT_HASHBANG = "/bin/bash -e" 25*7887bec8SAndroid Build Coastguard Worker 26*7887bec8SAndroid Build Coastguard Workerdef _impl(ctx): 27*7887bec8SAndroid Build Coastguard Worker out_file = ctx.actions.declare_file(ctx.label.name) 28*7887bec8SAndroid Build Coastguard Worker 29*7887bec8SAndroid Build Coastguard Worker for target in ctx.attr.data: 30*7887bec8SAndroid Build Coastguard Worker if ExecAspectInfo not in target: 31*7887bec8SAndroid Build Coastguard Worker continue 32*7887bec8SAndroid Build Coastguard Worker if target[ExecAspectInfo].args: 33*7887bec8SAndroid Build Coastguard Worker fail("{}: {} must not have args. Use embedded_exec to wrap it.".format(ctx.label, target.label)) 34*7887bec8SAndroid Build Coastguard Worker if target[ExecAspectInfo].env: 35*7887bec8SAndroid Build Coastguard Worker fail("{}: {} must not have env. Use embedded_exec to wrap it.".format(ctx.label, target.label)) 36*7887bec8SAndroid Build Coastguard Worker 37*7887bec8SAndroid Build Coastguard Worker content = "#!{}\n".format(ctx.attr.hashbang) 38*7887bec8SAndroid Build Coastguard Worker content += ctx.attr.script 39*7887bec8SAndroid Build Coastguard Worker 40*7887bec8SAndroid Build Coastguard Worker content = ctx.expand_location(content, ctx.attr.data) 41*7887bec8SAndroid Build Coastguard Worker ctx.actions.write(out_file, content, is_executable = True) 42*7887bec8SAndroid Build Coastguard Worker 43*7887bec8SAndroid Build Coastguard Worker runfiles = ctx.runfiles(files = ctx.files.data + [out_file]) 44*7887bec8SAndroid Build Coastguard Worker runfiles = runfiles.merge_all([target[DefaultInfo].default_runfiles for target in ctx.attr.data]) 45*7887bec8SAndroid Build Coastguard Worker 46*7887bec8SAndroid Build Coastguard Worker return DefaultInfo( 47*7887bec8SAndroid Build Coastguard Worker files = depset([out_file]), 48*7887bec8SAndroid Build Coastguard Worker executable = out_file, 49*7887bec8SAndroid Build Coastguard Worker runfiles = runfiles, 50*7887bec8SAndroid Build Coastguard Worker ) 51*7887bec8SAndroid Build Coastguard Worker 52*7887bec8SAndroid Build Coastguard Workerexec = rule( 53*7887bec8SAndroid Build Coastguard Worker implementation = _impl, 54*7887bec8SAndroid Build Coastguard Worker doc = """Run a script when `bazel run` this target. 55*7887bec8SAndroid Build Coastguard Worker 56*7887bec8SAndroid Build Coastguard WorkerSee [documentation] for the `args` attribute. 57*7887bec8SAndroid Build Coastguard Worker 58*7887bec8SAndroid Build Coastguard Worker**NOTE**: Like [genrule](https://bazel.build/reference/be/general#genrule)s, 59*7887bec8SAndroid Build Coastguard Workerhermeticity is not enforced or guaranteed, especially if `script` accesses PATH. 60*7887bec8SAndroid Build Coastguard WorkerSee [`Genrule Environment`](https://bazel.build/reference/be/general#genrule-environment) 61*7887bec8SAndroid Build Coastguard Workerfor details. 62*7887bec8SAndroid Build Coastguard Worker""", 63*7887bec8SAndroid Build Coastguard Worker attrs = { 64*7887bec8SAndroid Build Coastguard Worker "data": attr.label_list(aspects = [exec_aspect], allow_files = True, doc = """A list of labels providing runfiles. Labels may be used in `script`. 65*7887bec8SAndroid Build Coastguard Worker 66*7887bec8SAndroid Build Coastguard WorkerExecutables in `data` must not have the `args` and `env` attribute. Use 67*7887bec8SAndroid Build Coastguard Worker[`embedded_exec`](#embedded_exec) to wrap the depended target so its env and args 68*7887bec8SAndroid Build Coastguard Workerare preserved. 69*7887bec8SAndroid Build Coastguard Worker"""), 70*7887bec8SAndroid Build Coastguard Worker "hashbang": attr.string(default = _DEFAULT_HASHBANG, doc = "Hashbang of the script."), 71*7887bec8SAndroid Build Coastguard Worker "script": attr.string(doc = """The script. 72*7887bec8SAndroid Build Coastguard Worker 73*7887bec8SAndroid Build Coastguard WorkerUse `$(rootpath <label>)` to refer to the path of a target specified in `data`. See 74*7887bec8SAndroid Build Coastguard Worker[documentation](https://bazel.build/reference/be/make-variables#predefined_label_variables). 75*7887bec8SAndroid Build Coastguard Worker 76*7887bec8SAndroid Build Coastguard WorkerUse `$@` to refer to the args attribute of this target. 77*7887bec8SAndroid Build Coastguard Worker 78*7887bec8SAndroid Build Coastguard WorkerSee `build/bazel_common_rules/exec/tests/BUILD` for examples. 79*7887bec8SAndroid Build Coastguard Worker"""), 80*7887bec8SAndroid Build Coastguard Worker }, 81*7887bec8SAndroid Build Coastguard Worker executable = True, 82*7887bec8SAndroid Build Coastguard Worker) 83*7887bec8SAndroid Build Coastguard Worker 84*7887bec8SAndroid Build Coastguard Workerexec_test = rule( 85*7887bec8SAndroid Build Coastguard Worker implementation = _impl, 86*7887bec8SAndroid Build Coastguard Worker doc = """Run a test script when `bazel test` this target. 87*7887bec8SAndroid Build Coastguard Worker 88*7887bec8SAndroid Build Coastguard WorkerSee [documentation] for the `args` attribute. 89*7887bec8SAndroid Build Coastguard Worker 90*7887bec8SAndroid Build Coastguard Worker**NOTE**: Like [genrule](https://bazel.build/reference/be/general#genrule)s, 91*7887bec8SAndroid Build Coastguard Workerhermeticity is not enforced or guaranteed, especially if `script` accesses PATH. 92*7887bec8SAndroid Build Coastguard WorkerSee [`Genrule Environment`](https://bazel.build/reference/be/general#genrule-environment) 93*7887bec8SAndroid Build Coastguard Workerfor details. 94*7887bec8SAndroid Build Coastguard Worker""", 95*7887bec8SAndroid Build Coastguard Worker attrs = { 96*7887bec8SAndroid Build Coastguard Worker "data": attr.label_list(aspects = [exec_aspect], allow_files = True, doc = """A list of labels providing runfiles. Labels may be used in `script`. 97*7887bec8SAndroid Build Coastguard Worker 98*7887bec8SAndroid Build Coastguard WorkerExecutables in `data` must not have the `args` and `env` attribute. Use 99*7887bec8SAndroid Build Coastguard Worker[`embedded_exec`](#embedded_exec) to wrap the depended target so its env and args 100*7887bec8SAndroid Build Coastguard Workerare preserved. 101*7887bec8SAndroid Build Coastguard Worker"""), 102*7887bec8SAndroid Build Coastguard Worker "hashbang": attr.string(default = _DEFAULT_HASHBANG, doc = "Hashbang of the script."), 103*7887bec8SAndroid Build Coastguard Worker "script": attr.string(doc = """The script. 104*7887bec8SAndroid Build Coastguard Worker 105*7887bec8SAndroid Build Coastguard WorkerUse `$(rootpath <label>)` to refer to the path of a target specified in `data`. See 106*7887bec8SAndroid Build Coastguard Worker[documentation](https://bazel.build/reference/be/make-variables#predefined_label_variables). 107*7887bec8SAndroid Build Coastguard Worker 108*7887bec8SAndroid Build Coastguard WorkerUse `$@` to refer to the args attribute of this target. 109*7887bec8SAndroid Build Coastguard Worker 110*7887bec8SAndroid Build Coastguard WorkerSee `build/bazel_common_rules/exec/tests/BUILD` for examples. 111*7887bec8SAndroid Build Coastguard Worker"""), 112*7887bec8SAndroid Build Coastguard Worker }, 113*7887bec8SAndroid Build Coastguard Worker test = True, 114*7887bec8SAndroid Build Coastguard Worker) 115