This repository has been archived by the owner on Mar 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
def.bzl
163 lines (146 loc) · 5.15 KB
/
def.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
load("@bazel_skylib//lib:shell.bzl", "shell")
_CONTENT_PREFIX = """#!/usr/bin/env bash
# --- begin runfiles.bash initialization ---
# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
set -euo pipefail
if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
if [[ -f "$0.runfiles_manifest" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
export RUNFILES_DIR="$0.runfiles"
fi
fi
if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
"$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
else
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
exit 1
fi
# --- end runfiles.bash initialization ---
# Export RUNFILES_* envvars (and a couple more) for subprocesses.
runfiles_export_envvars
"""
def _multirun_impl(ctx):
runfiles = ctx.runfiles().merge(ctx.attr._bash_runfiles[DefaultInfo].default_runfiles)
content = [_CONTENT_PREFIX]
for command in ctx.attr.commands:
defaultInfo = command[DefaultInfo]
if defaultInfo.files_to_run == None:
fail("%s is not executable" % command.label, attr = "commands")
exe = defaultInfo.files_to_run.executable
if exe == None:
fail("%s does not have an executable file" % command.label, attr = "commands")
default_runfiles = defaultInfo.default_runfiles
if default_runfiles != None:
runfiles = runfiles.merge(default_runfiles)
content.append("echo Running %s\n./%s $@\n" % (shell.quote(str(command.label)), shell.quote(exe.short_path)))
out_file = ctx.actions.declare_file(ctx.label.name + ".bash")
ctx.actions.write(
output = out_file,
content = "".join(content),
is_executable = True,
)
return [DefaultInfo(
files = depset([out_file]),
runfiles = runfiles,
executable = out_file,
)]
_multirun = rule(
implementation = _multirun_impl,
attrs = {
"commands": attr.label_list(
allow_empty = True, # this is explicitly allowed - generated invocations may need to run 0 targets
mandatory = True,
allow_files = True,
doc = "Targets to run in specified order",
cfg = "target",
),
"_bash_runfiles": attr.label(
default = Label("@bazel_tools//tools/bash/runfiles"),
),
},
executable = True,
)
def multirun(**kwargs):
tags = kwargs.get("tags", [])
if "manual" not in tags:
tags.append("manual")
kwargs["tags"] = tags
_multirun(
**kwargs
)
def _command_impl(ctx):
runfiles = ctx.runfiles().merge(ctx.attr._bash_runfiles[DefaultInfo].default_runfiles)
defaultInfo = ctx.attr.command[DefaultInfo]
default_runfiles = defaultInfo.default_runfiles
if default_runfiles != None:
runfiles = runfiles.merge(default_runfiles)
str_env = [
"%s=%s" % (k, shell.quote(v))
for k, v in ctx.attr.environment.items()
]
str_unqouted_env = [
"%s=%s" % (k, v)
for k, v in ctx.attr.raw_environment.items()
]
str_args = [
"%s" % shell.quote(v)
for v in ctx.attr.arguments
]
command_elements = ["exec env"] + \
str_env + \
str_unqouted_env + \
["./%s" % shell.quote(defaultInfo.files_to_run.executable.short_path)] + \
str_args + \
["$@\n"]
out_file = ctx.actions.declare_file(ctx.label.name + ".bash")
ctx.actions.write(
output = out_file,
content = _CONTENT_PREFIX + " ".join(command_elements),
is_executable = True,
)
return [
DefaultInfo(
files = depset([out_file]),
runfiles = runfiles,
executable = out_file,
),
]
_command = rule(
implementation = _command_impl,
attrs = {
"arguments": attr.string_list(
doc = "List of command line arguments",
),
"environment": attr.string_dict(
doc = "Dictionary of environment variables",
),
"raw_environment": attr.string_dict(
doc = "Dictionary of unqouted environment variables",
),
"command": attr.label(
mandatory = True,
allow_files = True,
executable = True,
doc = "Target to run",
cfg = "target",
),
"_bash_runfiles": attr.label(
default = Label("@bazel_tools//tools/bash/runfiles"),
),
},
executable = True,
)
def command(**kwargs):
tags = kwargs.get("tags", [])
if "manual" not in tags:
tags.append("manual")
kwargs["tags"] = tags
_command(
**kwargs
)