bazel: refactor shell rules into own package

Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
Paul Meyer 2023-03-14 17:29:54 +01:00
parent e3f37e9a38
commit a0fddd44eb
6 changed files with 14 additions and 19 deletions

9
bazel/sh/BUILD.bazel Normal file
View file

@ -0,0 +1,9 @@
exports_files(["repo_command.sh.in"])
sh_library(
name = "base_lib",
srcs = [
"lib.bash",
],
visibility = ["//visibility:public"],
)

92
bazel/sh/def.bzl Normal file
View file

@ -0,0 +1,92 @@
"""Bazel rules for CI and dev tooling"""
load("@bazel_skylib//lib:shell.bzl", "shell")
def _sh_template_impl(ctx):
out_file = ctx.actions.declare_file(ctx.label.name + ".bash")
substitutions = {}
for k, v in ctx.attr.substitutions.items():
sub = ctx.expand_location(v, ctx.attr.data)
substitutions[k] = sub
ctx.actions.expand_template(
template = ctx.file.template,
output = out_file,
substitutions = substitutions,
is_executable = True,
)
return [DefaultInfo(
files = depset([out_file]),
executable = out_file,
)]
_sh_template = rule(
implementation = _sh_template_impl,
attrs = {
"data": attr.label_list(
allow_files = True,
),
"substitutions": attr.string_dict(),
"template": attr.label(
allow_single_file = True,
),
},
)
def sh_template(name, **kwargs):
"""Build a sh_binary from a template
Args:
name: name
**kwargs: **kwargs
"""
script_name = name + "-script"
tags = kwargs.get("tags", [])
data = kwargs.get("data", [])
data.append("//bazel/sh:base_lib")
substitutions = kwargs.pop("substitutions", [])
substitutions["@@BASE_LIB@@"] = "$(rootpath //bazel/sh:base_lib)"
template = kwargs.pop("template", [])
_sh_template(
name = script_name,
tags = tags,
data = data,
substitutions = substitutions,
template = template,
)
native.sh_binary(
name = name,
srcs = [script_name],
**kwargs
)
def repo_command(name, **kwargs):
"""Build a sh_binary that executes a single command.
Args:
name: name
**kwargs: **kwargs
"""
cmd = kwargs.pop("command")
args = shell.array_literal(kwargs.pop("args", []))
substitutions = {
"@@ARGS@@": args,
"@@CMD@@": "$(rootpath %s)" % cmd,
}
data = kwargs.pop("data", [])
data.append(cmd)
sh_template(
name = name,
data = data,
substitutions = substitutions,
template = "//bazel/sh:repo_command.sh.in",
**kwargs
)

62
bazel/sh/lib.bash Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
set -o errtrace
shopt -s inherit_errexit
function printErr {
echo -e "\033[0;31mERROR:\033[0m ${1}"
}
function _exitHandler {
local exit_code=$1
if [[ ${exit_code} -ne 0 ]]; then
printErr "$0: exit status ${exit_code}"
fi
}
function _errorHandler {
local line=$1
local linecallfunc=$2
local command="$3"
local funcstack="$4"
printErr "$0: '${command}' failed at line ${line}"
if [[ ${funcstack} != "::" ]]; then
echo -ne "\tin ${funcstack} "
if [[ ${linecallfunc} != "" ]]; then
echo "called at line ${linecallfunc}"
else
echo
fi
fi
}
_exitHandlers=()
_errorHandlers=()
function registerExitHandler {
_exitHandlers+=("$1")
}
function registerErrorHandler {
_errorHandler+=("$1")
}
function _callExitHandlers {
_exitHandlers+=(_exitHandler) # Add our handler last.
for h in "${_exitHandlers[@]}"; do
${h} "$@"
done
}
function _callErrorHandlers {
_errorHandlers+=(_errorHandler) # Add our handler last.
for h in "${_errorHandlers[@]}"; do
${h} "$@"
done
}
trap '_callErrorHandlers $LINENO $BASH_LINENO "$BASH_COMMAND" $(printf "::%s" ${FUNCNAME[@]:-})' ERR
trap '_callExitHandlers $?' EXIT

View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
lib=$(realpath @@BASE_LIB@@) || exit 1
cmd=$(realpath @@CMD@@) || exit 1
args=@@ARGS@@
# shellcheck source=lib.bash
if ! source "${lib}"; then
echo "Error: could not find import"
exit 1
fi
cd "${BUILD_WORKSPACE_DIRECTORY}" || exit 1
"${cmd}" "${args[@]}"