How can I wrap all files of a filegroup
in a directory and create a new target out of that?
My use case is that I have a filegroup inside test-data/BUILD.bazel but the test runner expects the files inside a directory called test-data
.
filegroup(
name = "render-test-files",
srcs = glob([
"integration/**",
"tests/**",
"linux-gcc8-release/**",
"expectations/platform-all/**",
"ignores/**",
], allow_empty = False)
visibility = [
"//render-test:__subpackages__",
],
)
I cannot use a genrule
because it requires all output files to be listed explicitly.
To collect files into a directory and have that considered a build artifact, you can write a custom rule returning TreeArtifact
using declare_directory
action. In a very naive/trivial form (not portable, not checking if sources contain any files, ...) something like:
def _impl(ctx):
outdir = ctx.actions.declare_directory("{}.dir".format(ctx.attr.name))
args = ctx.actions.args()
args.add(outdir.path)
args.add_all(ctx.files.srcs)
ctx.actions.run_shell(
outputs = [outdir],
inputs = ctx.files.srcs,
arguments = [args],
command = """
outdir="$1";
shift;
cp "$@" "${outdir}"
""",
)
return [
DefaultInfo(files = depset([outdir])),
]
dirrule = rule(
_impl,
attrs = {
"srcs": attr.label_list(
allow_files = True,
mandatory = True,
),
},
)
Which could then be used in a BUILD
file with mydir
now being directory containing copies of file0[12]
:
load(":dirrule.bzl", "dirrule")
dirrule(
name = "mydir",
srcs = [
"//myfiles:file01",
"//myfiles:file02",
],
)
I would personally rather try to adapt the receiving tool to actually handle list of inputs... or if impossible (beyond my control), probably rather wrap its use (call) from (I presume already the case anyways) custom rule which would take that list and populate the tree (preferably symlink even if the tool isn't way broken) in shape it expects.