bazel-lib/lib/private/utils.bzl

124 lines
3.8 KiB
Python

"""General utility functions"""
def _propagate_well_known_tags(tags = []):
"""Returns a list of tags filtered from the input set that only contains the ones that are considered "well known"
These are listed in Bazel's documentation:
https://docs.bazel.build/versions/main/test-encyclopedia.html#tag-conventions
https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes
Args:
tags: List of tags to filter
Returns:
List of tags that only contains the well known set
"""
WELL_KNOWN_TAGS = [
"no-sandbox",
"no-cache",
"no-remote-cache",
"no-remote-exec",
"no-remote",
"local",
"requires-network",
"block-network",
"requires-fakeroot",
"exclusive",
"manual",
"external",
]
# cpu:n tags allow setting the requested number of CPUs for a test target.
# More info at https://docs.bazel.build/versions/main/test-encyclopedia.html#other-resources
CPU_PREFIX = "cpu:"
return [
tag
for tag in tags
if tag in WELL_KNOWN_TAGS or tag.startswith(CPU_PREFIX)
]
def _to_label(param):
"""Converts a string to a Label. If Label is supplied, the same label is returned.
Args:
param: a string representing a label or a Label
Returns:
a Label
"""
param_type = type(param)
if param_type == "string":
if param.startswith("@"):
return Label(param)
if param.startswith("//"):
return Label("@" + param)
# resolve the relative label from the current package
# if 'param' is in another workspace, then this would return the label relative to that workspace, eg:
# `Label("@my//foo:bar").relative("@other//baz:bill") == Label("@other//baz:bill")`
if param.startswith(":"):
param = param[1:]
if native.package_name():
return Label("@//" + native.package_name()).relative(param)
else:
return Label("@//:" + param)
elif param_type == "Label":
return param
else:
msg = "Expected 'string' or 'Label' but got '{}'".format(param_type)
fail(msg)
def _is_external_label(param):
"""Returns True if the given Label (or stringy version of a label) represents a target outside of the workspace
Args:
param: a string or label
Returns:
a bool
"""
return len(_to_label(param).workspace_root) > 0
# Path to the root of the workspace
def _path_to_workspace_root():
""" Returns the path to the workspace root under bazel
Returns:
Path to the workspace root
"""
return "/".join([".."] * len(native.package_name().split("/")))
# Like glob() but returns directories only
def _glob_directories(include, **kwargs):
all = native.glob(include, exclude_directories = 0, **kwargs)
files = native.glob(include, **kwargs)
directories = [p for p in all if p not in files]
return directories
def _file_exists(path):
"""Check whether a file exists.
Useful in macros to set defaults for a configuration file if it is present.
This can only be called during the loading phase, not from a rule implementation.
Args:
path: a label, or a string which is a path relative to this package
"""
label = _to_label(path)
file_abs = "%s/%s" % (label.package, label.name)
file_rel = file_abs[len(native.package_name()) + 1:]
file_glob = native.glob([file_rel], exclude_directories = 1)
return len(file_glob) > 0
utils = struct(
is_external_label = _is_external_label,
file_exists = _file_exists,
glob_directories = _glob_directories,
path_to_workspace_root = _path_to_workspace_root,
propagate_well_known_tags = _propagate_well_known_tags,
to_label = _to_label,
)