buck2 icon indicating copy to clipboard operation
buck2 copied to clipboard

Provide some way in the CLI to execute providers and get values out of them

Open lf- opened this issue 5 months ago • 4 comments

buck2 audit providers exists which can give you some details about providers:

$ buck audit providers toolchains//:hspec-discover
toolchains//:hspec-discover (<unspecified>):
  Providers([
    DefaultInfo(
      sub_targets={},
      default_outputs=[ <build artifact out.link bound to toolchains//:hspec-discover (<unspecified>)> ],
      other_outputs=[]
    ),
    BinDirInfo( args=cmd_args(
      <build artifact out.link bound to toolchains//:hspec-discover (<unspecified>)>,
      "bin",
      delimiter="/"
    ) ),
    NixDynamicInfo( dynamic=DynamicValue<toolchains//:hspec-discover (<unspecified>)_0> ),
    RunInfo( args=cmd_args( cmd_args(
      <build artifact out.link bound to toolchains//:hspec-discover (<unspecified>)>,
      "bin",
      "hspec-discover",
      delimiter="/"
    ) ) )
  ])

However, I can't figure out a way to actually build one of those and get the result if it's not a subtarget. Is this a thing in the CLI? I would like to be able to interactively poke around the build graph.

lf- avatar Jul 11 '25 01:07 lf-

As I understand it, it doesn't exactly make sense to "build" a provider, rather a provider is a piece of data, and that data might be a/contain some cmd_args that one could run, or some artifact that was bound in the rule implementation.

The CLI treats DefaultInfo and RunInfo as first-class providers that you can respectively build and run, but you can build arbitrary artifacts using BXL:

load("@prelude//linking:link_info.bzl", "LinkCommandDebugOutputInfo")

def _main(ctx: bxl.Context):
    # Replace with any C++ target.
    res = ctx.analysis(ctx.configured_targets("//compiler:compiler"))
    # Pick any artifact from any provider.
    artifact = res.providers()[LinkCommandDebugOutputInfo].debug_outputs[0].argsfile
    # Build it and print its path.
    ctx.output.print("Here's your argsfile!", ctx.output.ensure(artifact))

main = bxl_main(
    impl = _main,
    cli_args = {},
)

Which you run with buck2 bxl main.bxl:main --console simple --verbose 0 (the flags being optional, of course).

It's not really in the CLI itself, but it's interactive enough I guess?

cbarrete avatar Jul 11 '25 02:07 cbarrete

Right, I guess I mean here to indeed do the equivalent of calling ensure on them from the CLI so you can look at them. I am going to just write the bxl to do this exact thing but I was hoping that I could interactively poke at it first somehow.

This type of interactive exploration is regularly done in nix with stuff like nix repl, nix eval --expr and similar. But the buck language is definitely a bit more wordy than nix and Python doesn't lend itself to one liners.

Another possibility I suppose is yoinking the target into BXL and then messing around with the repl in the DAP server (which was what led me to try it out today, it seems very helpful!).

lf- avatar Jul 11 '25 04:07 lf-

We don't have such command. But as @cbarrete said, you can use bxl to do that. If a standard command doesn't meet your needs, creating a bxl script is often a solution.

Nero5023 avatar Jul 11 '25 17:07 Nero5023

Hm, I think I will try to make a tools/debug_provider.bxl.

lf- avatar Jul 11 '25 17:07 lf-