Search code examples
bazelbazel-rules

Feed Bazel output to another Bazel rule


I am pretty new to Bazel and have a difficult time figuring out a solution for this:

Say I have this nodejs_binary rule:

nodejs_binary(
    name = "js_scirpt",
    data = [
        "@npm//some_lib",
    ],
    entry_point = ":some_js_script.js",
)

Now I need the output from :js_script be fed to a go_test rule which does something else. The sequence matters: nodejs rule should finishes first and then go_test uses the output.

I think this should be possible by writing a json file from the nodejs_binary to the disk and read it from some_js_script.js, though I cannot control the sequence of executions and I don't know how to pass it to go_test rule. Any idea on how this is possible (or maybe there is a better approach)?


Solution

  • A dependency is the way to make one thing happen before another with Bazel. genrule is the easiest way to run a command and have the output available.

    Putting them together looks like this:

    genrule(
        name = "run_js_script",
        tools = [
            ":js_script",
        ],
        outs = [
            "something.json",
        ],
        cmd = "$(location :js_script) --output $(location something.json)",
    )
    
    go_test(
        data = [
            ":something.json",
        ],
        [name, srcs, deps, etc]
    )
    

    The Go code should use runfiles.go to find the path to the file.

    Also, the Node code should take a command-line flag for the destination to write its output. If it can't do that, then use shell commands to move the output to $(location something.json).