bazelbazel-rulesbazel-aspect

Is there a way to pass the 'bazel run' result file to the next rule file in bazel?


I created a first rule file to geneate a scirpt using the ctx.actions.expand_template and ran it. and I wanted that pass the result of bazel run with first rule to the next 2nd rule file as a resource. But, I could't get the result which is generated by bazel run 1st rule in the 2nd rule. It does not mean the script created by the first rule, but the file created when the script is executed.

Below example is what I tested.

This is bazel rule file

def _1st_rule_impl(ctx):

...

    out = ctx.outputs.executable
    template = ctx.file.my_template

    ctx.actions.expand_template(
        output = out,
        template = template,
        substitutions = {
            "{ARG1}: ctx.attr.my_file_name,
            "{ARG2}: ctx.attr.my_file_content,
        }

    return [
        DefaultInfo(
            files = depset([out]),
            runfiles = ctx.runfiles(files = [out])
        )
    ]

1st_rule = rule(
    implementation = _1st_rule_impl,
    attrs = {
        "my_template":attr.label(
            allow_single_file = True,
            default = Label("@my_test//my_rules:my_script.sh.template"),
        ),
        "my_file_name": attr.string(
            default = "myfile.txt",
        ),
        "my_file_content": attr.string(
            default = "hello world",
        ),
    },
    executable = True,
)

def _2nd_rule_impl(ctx):

...

    for dep in ctx.attr.deps:
        //
        // HOW CAN I GET THE RESULT OF `bazel run` THE '1st_rule'?
        // I WANT TO GET THE `myfile.txt` WHICH IS GENERATED BY '1st_rule'
        //

    return [
        DefaultInfo(
            files = depset([out]),
            runfiles = ctx.runfiles(files = [out]),
        )
    ]

2nd_rule = rule(
    implementation = _2nd_rule_impl,
    attrs = {
        "dep":attr.label_list(
            mandatory= True,
        ),
        ...
    },
    executable = True,
)

This is BUILD file

1st_rule(
    name = "my_1st_rule",
    my_file_name = "myfile.txt",
    my_file_content = "hello world",
)


2nd_rule(
    name = "my_2nd_rule",
    dep = [
        ":my_1st_rule",
    ],
)

This is template shell script

...
function create_file() {
    echo "{ARG2}" > "{ARG1}"
}
...

I tested with the example described above.


Solution

  • There are several ways to access the outputs of dependencies. Perhaps, the simplest is ctx.files. For example, print(ctx.files.dep) in _2nd_rule_impl should show the output of my_1st_rule when my_2nd_rule is analyzed.