如何将Bazel文件组中的所有文件打包到一个目录中?

huangapple go评论61阅读模式
英文:

How do I wrap all files from a Bazel filegroup into a directory?

问题

如何将`filegroup`中的所有文件放入一个名为`test-data`的目录中并创建一个新的目标

我的使用情况是在test-data/BUILD.bazel文件中有一个名为`render-test-files``filegroup`,但测试运行器希望将文件放在一个名为`test-data`的目录中

```bzl
filegroup(
    name = "render-test-files",
    srcs = glob([
        "integration/**",
        "tests/**",
        "linux-gcc8-release/**",
        "expectations/platform-all/**",
        "ignores/**",
    ], allow_empty = False)
    visibility = [
        "//render-test:__subpackages__",
    ],
)

我无法使用genrule,因为它要求将所有输出文件明确列出。


<details>
<summary>英文:</summary>

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`.

```bzl
filegroup(
    name = &quot;render-test-files&quot;,
    srcs = glob([
        &quot;integration/**&quot;,
        &quot;tests/**&quot;,
        &quot;linux-gcc8-release/**&quot;,
        &quot;expectations/platform-all/**&quot;,
        &quot;ignores/**&quot;,
    ], allow_empty = False)
    visibility = [
        &quot;//render-test:__subpackages__&quot;,
    ],
)

I cannot use a genrule because it requires all output files to be listed explicitly.

答案1

得分: 1

要将文件收集到一个目录并将其视为构建产物,您可以编写一个自定义规则,使用declare_directory操作返回TreeArtifact。在一个非常朴素/简单的形式中(不可移植,不检查源文件是否包含任何文件,...),可以像这样:

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,
        ),
    },
)

然后可以在BUILD文件中使用它,mydir现在是包含file0[12]副本的目录:

load(":dirrule.bzl", "dirrule")

dirrule(
    name = "mydir",
    srcs = [
        "//myfiles:file01",
        "//myfiles:file02",
    ],
)

我个人更愿意尝试调整接收工具以实际处理输入列表...或者如果不可能(超出我的控制),可能更愿意在已经采取的自定义规则中包装其使用(调用),该规则将接受该列表并以期望的形状填充树(最好是符号链接,即使工具没有太大问题)。

英文:

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(&quot;{}.dir&quot;.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 = &quot;&quot;&quot;
outdir=&quot;$1&quot;;
shift;
cp &quot;$@&quot; &quot;${outdir}&quot;
                &quot;&quot;&quot;,
    )
    return [
        DefaultInfo(files = depset([outdir])),
    ]

dirrule = rule(
    _impl,
    attrs = {
        &quot;srcs&quot;: 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(&quot;:dirrule.bzl&quot;, &quot;dirrule&quot;)

dirrule(
    name = &quot;mydir&quot;,
    srcs = [
        &quot;//myfiles:file01&quot;,
        &quot;//myfiles:file02&quot;,
    ],
)

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.

huangapple
  • 本文由 发表于 2023年6月26日 01:58:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定