mirror of
https://github.com/bazel-contrib/bazel-lib
synced 2024-11-27 17:43:27 +00:00
1df2becc7a
In particular this makes our bazelrc presets more compliant with client codebases, ensuring they can copy these files and not trip on their own pre-commit check
89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
"""output_files implementation
|
|
"""
|
|
|
|
load("//lib:utils.bzl", _to_label = "to_label")
|
|
|
|
def _output_files(ctx):
|
|
files = []
|
|
files_depset = depset()
|
|
if ctx.attr.output_group:
|
|
if OutputGroupInfo not in ctx.attr.target:
|
|
msg = "%s output_group is specified but %s does not provide an OutputGroupInfo" % (ctx.attr.output_group, ctx.attr.target)
|
|
fail(msg)
|
|
if ctx.attr.output_group not in ctx.attr.target[OutputGroupInfo]:
|
|
msg = "%s output_group is specified but %s does not provide this output group" % (ctx.attr.output_group, ctx.attr.target)
|
|
fail(msg)
|
|
files_depset = ctx.attr.target[OutputGroupInfo][ctx.attr.output_group]
|
|
else:
|
|
files_depset = ctx.attr.target[DefaultInfo].files
|
|
|
|
files_list = files_depset.to_list()
|
|
|
|
for path in ctx.attr.paths:
|
|
file = _find_short_path_in_files_list(files_list, path)
|
|
if not file:
|
|
if ctx.attr.output_group:
|
|
msg = "%s file not found within the %s output group of %s" % (path, ctx.attr.output_group, ctx.attr.target)
|
|
else:
|
|
msg = "%s file not found within the DefaultInfo of %s" % (path, ctx.attr.target)
|
|
fail(msg)
|
|
files.append(file)
|
|
return [DefaultInfo(
|
|
files = depset(direct = files),
|
|
runfiles = ctx.runfiles(files = files),
|
|
)]
|
|
|
|
output_files = rule(
|
|
doc = "A rule that provides file(s) specific via DefaultInfo from a given target's DefaultInfo or OutputGroupInfo",
|
|
implementation = _output_files,
|
|
attrs = {
|
|
"target": attr.label(
|
|
doc = "the target to look in for requested paths in its' DefaultInfo or OutputGroupInfo",
|
|
mandatory = True,
|
|
),
|
|
"paths": attr.string_list(
|
|
doc = "the paths of the file(s), relative to their roots, to provide via DefaultInfo from the given target's DefaultInfo or OutputGroupInfo",
|
|
mandatory = True,
|
|
allow_empty = False,
|
|
),
|
|
"output_group": attr.string(
|
|
doc = "if set, we look in the specified output group for paths instead of DefaultInfo",
|
|
),
|
|
},
|
|
provides = [DefaultInfo],
|
|
)
|
|
|
|
def make_output_files(name, target, paths, **kwargs):
|
|
"""Helper function to generate a output_files target and return its label.
|
|
|
|
Args:
|
|
name: unique name for the generated `output_files` target
|
|
target: `target` attribute passed to generated `output_files` target
|
|
paths: `paths` attribute passed to generated `output_files` target
|
|
**kwargs: parameters to pass to generated `output_files` target
|
|
|
|
Returns:
|
|
The label `name`
|
|
"""
|
|
output_files(
|
|
name = name,
|
|
target = target,
|
|
paths = paths,
|
|
**kwargs
|
|
)
|
|
return _to_label(name)
|
|
|
|
def _find_short_path_in_files_list(files_list, short_path):
|
|
"""Helper function find a file in a DefaultInfo by short path
|
|
|
|
Args:
|
|
files_list: a list of files
|
|
short_path: the short path (path relative to root) to search for
|
|
Returns:
|
|
The File if found else None
|
|
"""
|
|
for file in files_list:
|
|
if file.short_path == short_path:
|
|
return file
|
|
return None
|