bazel-lib/lib/private/bats.bzl

110 lines
3.6 KiB
Python

"bats_test"
load("//lib:paths.bzl", "BASH_RLOCATION_FUNCTION", "to_rlocation_path")
load("//lib:windows_utils.bzl", "create_windows_native_launcher_script")
load(":expand_locations.bzl", "expand_locations")
load(":expand_variables.bzl", "expand_variables")
_LAUNCHER_TMPL = """#!/usr/bin/env bash
set -o errexit -o nounset -o pipefail
{BASH_RLOCATION_FUNCTION}
readonly core_path="$(rlocation {core})"
readonly bats="$core_path/bin/bats"
readonly libs=( {libraries} )
{envs}
NEW_LIBS=()
for lib in "${{libs[@]}}"; do
NEW_LIBS+=( $(cd "$(rlocation $lib)/.." && pwd) )
done
export BATS_LIB_PATH=$(
IFS=:
echo "${{NEW_LIBS[*]}}"
)
export BATS_TEST_TIMEOUT="$TEST_TIMEOUT"
export BATS_TMPDIR="$TEST_TMPDIR"
exec $bats {tests} $@
"""
_ENV_SET = """export {key}=\"{value}\""""
def _bats_test_impl(ctx):
toolchain = ctx.toolchains["@aspect_bazel_lib//lib:bats_toolchain_type"]
batsinfo = toolchain.batsinfo
is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo])
envs = []
for (key, value) in ctx.attr.env.items():
envs.append(_ENV_SET.format(
key = key,
value = " ".join([expand_variables(ctx, exp, attribute_name = "env") for exp in expand_locations(ctx, value, ctx.attr.data).split(" ")]),
))
# See https://www.msys2.org/wiki/Porting/:
# > Setting MSYS2_ARG_CONV_EXCL=* prevents any path transformation.
if is_windows:
envs.append(_ENV_SET.format(
key = "MSYS2_ARG_CONV_EXCL",
value = "*",
))
envs.append(_ENV_SET.format(
key = "MSYS_NO_PATHCONV",
value = "1",
))
bash_launcher = ctx.actions.declare_file("%s_bats.sh" % ctx.label.name)
ctx.actions.write(
output = bash_launcher,
content = _LAUNCHER_TMPL.format(
core = to_rlocation_path(ctx, batsinfo.core),
libraries = " ".join([to_rlocation_path(ctx, lib) for lib in batsinfo.libraries]),
tests = " ".join(["$(rlocation %s)" % to_rlocation_path(ctx, test) for test in ctx.files.srcs]),
envs = "\n".join(envs),
BASH_RLOCATION_FUNCTION = BASH_RLOCATION_FUNCTION,
),
is_executable = True,
)
launcher = create_windows_native_launcher_script(ctx, bash_launcher) if is_windows else bash_launcher
runfiles = ctx.runfiles(ctx.files.srcs + ctx.files.data + [bash_launcher])
runfiles = runfiles.merge(toolchain.default.default_runfiles)
runfiles = runfiles.merge(ctx.attr._runfiles.default_runfiles)
return DefaultInfo(
executable = launcher,
runfiles = runfiles,
)
bats_test = rule(
implementation = _bats_test_impl,
attrs = {
"srcs": attr.label_list(
allow_files = [".bats"],
doc = "Test files",
),
"data": attr.label_list(
allow_files = True,
doc = "Runtime dependencies of the test.",
),
"env": attr.string_dict(
doc = """Environment variables of the action.
Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables)
and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution.
""",
),
"_runfiles": attr.label(default = "@bazel_tools//tools/bash/runfiles"),
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
},
toolchains = [
"@aspect_bazel_lib//lib:bats_toolchain_type",
"@bazel_tools//tools/sh:toolchain_type",
],
test = True,
)