Skip to main content

Context

The bxl context that the top level bxl implementation receives as parameter. This context contains all the core bxl functions to query, build, create actions, etc.

Context.analysis

def Context.analysis(
labels: bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | label | providers_label | str | target_label | target_set | target_set | list[bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | label | providers_label | str | target_label],
target_platform: None | str | target_label = ...,
*,
skip_incompatible: bool = True,
) -> None | bxl.AnalysisResult | dict[label, bxl.AnalysisResult]

Runs analysis on the given labels, accepting an optional target_platform which is the target platform configuration used to resolve configurations of any unconfigured target nodes, and an optional skip_incompatible boolean that indicates whether to skip analysis of nodes that are incompatible with the target platform. The target_platform is either a string that can be parsed as a target label, or a target label.

The given labels is a providers expression, which is either:

  • a single string that is a target pattern.
  • a single target node or label, configured or unconfigured
  • a single sub target label, configured or unconfigured
  • a list of the two options above.

This returns either a single analysis_result if the given labels argument is "singular", or a dict keyed by sub target labels of analysis if the given labels argument is list-like


Context.aquery

def Context.aquery(
target_platform: None | str | target_label = ...,
) -> bxl.AqueryContext

Returns the aqueryctx that holds all the aquery functions. This function takes an optional parameter target_platform, which is the target platform configuration used to configured any unconfigured target nodes.

The target_platform is a target label, or a string that is a target label.


Context.audit

def Context.audit(
) -> bxl.AuditContext

Returns the audit_ctx that holds all the audit functions.


Context.build

def Context.build(
labels: bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | label | providers_label | str | target_label | target_set | target_set | list[bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | label | providers_label | str | target_label],
target_platform: None | str | target_label = ...,
*,
materializations: str = "default",
) -> dict[label, bxl.BuildResult]

Runs a build on the given labels, accepting an optional target_platform which is the target platform configuration used to resolve configurations. Note that when build() is called, the artifacts are materialized without needing to additionally call ensure() on them.

The given labels is a providers expression, which is either:

  • a single string that is a target pattern.
  • a single target node or label, configured or unconfigured
  • a single provider label, configured or unconfigured
  • a list of the two options above.

This returns a dict keyed by sub target labels mapped to bxl_build_results if the given labels argument is list-like.

This function is not available on the bxl_ctx when called from dynamic_output.


Context.bxl_actions

def Context.bxl_actions(
*,
exec_deps: None | bxl.UnconfiguredTargetNode | providers_label | str | target_label | target_set | list[bxl.UnconfiguredTargetNode | providers_label | str | target_label] = None,
toolchains: None | bxl.UnconfiguredTargetNode | providers_label | str | target_label | target_set | list[bxl.UnconfiguredTargetNode | providers_label | str | target_label] = None,
target_platform: None | str | target_label = ...,
exec_compatible_with: None | bxl.UnconfiguredTargetNode | str | target_label | target_set | list[bxl.UnconfiguredTargetNode | str | target_label] = None,
) -> bxl.Actions

Returns the bxl actions to create and register actions for this bxl function. This will have the execution platform resolved according to the execution deps and toolchains you pass into this function. You'll be able to access the analysis action factory of the correct execution platform, toolchains, and execution deps of the corresponding configuration via this context.

Actions created by bxl will not be built by default. Instead, they are marked to be built by ctx.output.ensure(artifact) on the output module of the bxl_ctx. Only artifacts marked by ensure will be built.

Sample usage:

def _impl_write_action(ctx):
    bxl_actions = ctx.bxl_actions()
    output = bxl_actions.actions.write("my_output", "my_content")
    ensured = ctx.output.ensure(output)
    ctx.output.print(ensured)

There are several optional named parameters:

exec_deps - These are dependencies you wish to access as executables for creating the action. This is usually the same set of targets one would pass to rule's attr.exec_dep. toolchains - The set of toolchains needed for the actions you intend to create. target_platform - The intended target platform for your toolchains exec_compatible_with - Explicit list of configuration nodes (like platforms or constraints) that these actions are compatible with. This is the 'exec_compatible_with' attribute of a target.

If you passed in exec_deps or toolchains, you can access the resolved dependencies using the exec_deps and toolchains attributes on the bxl_actions, which both return a dict of unconfigured subtarget labels and their configured/resolved dependency objects.

Note that the keys of exec_deps and toolchains must be unconfigured subtarget labels (providers_labels), and not unconfigured target labels. You can use ctx.unconfigured_sub_targets(...) or with_sub_target() on target_label to create the label.

def _impl_run_action(ctx):
   my_exec_dep = ctx.unconfigured_sub_targets("foo//bar:baz") # has some provider that you would use in the action
   bxl_actions = ctx.bxl_actions(exec_deps = [my_exec_dep]) # call once, reuse wherever needed
   output = bxl_actions.actions.run(
       [
           "python3",
           bxl_actions.exec_deps[my_exec_dep][RunInfo], # access resolved exec_deps on the `bxl_actions`
           out.as_output(),
       ],
       category = "command",
       local_only = True,
   )
   ctx.output.ensure(output)

When called from a dynamic_output, bxl_actions() cannot be configured with a different execution platform resolution from the parent BXL.


Context.cell_root

def Context.cell_root() -> str

Returns the absolute path to the cell of the repository

This function is not available on the bxl_ctx when called from dynamic_output.


Context.cli_args

Context.cli_args: struct(..)

A struct of the command line args as declared using the [cli_args] module. These command lines are resolved per the users input on the cli when invoking the bxl script.

If you wish to pass in a kebab-cased arg, the arg accessed from the BXL context's cli_args attrbute will always be in snakecase. For example, if you passed in my-arg, accessing it within BXL would look like ctx.cli_args.my_arg.

This attribute is not available on the bxl context within the a dynamic lambda.


Context.configured_targets

def Context.configured_targets(
labels: bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | str | target_label | target_set | target_set | list[bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | str | target_label],
/,
target_platform: None | str | target_label = ...,
*,
modifiers: None | list[str] = None,
) -> None | bxl.ConfiguredTargetNode | target_set

Gets the target nodes for the labels, accepting an optional target_platform which is the target platform configuration used to resolve configurations of any unconfigured target nodes. The target_platform is either a string that can be parsed as a target label, or a target label.

The given labels is a [TargetListExpr], which is either:

  • a single string that is a target pattern.
  • a single target node or label, configured or unconfigured
  • a list of the two options above.

Note that this function does not accept Label (which is a configured provider label), since this is the label of a subtarget. You can get the underlying configured target label on the Label using configured_targets() (ex: my_label.configured_target()).

This returns either a single target_node if the given labels is "singular", a dict keyed by target labels of target_node if the given labels is list-like


Context.cquery

def Context.cquery(
target_platform: None | str | target_label = ...,
) -> bxl.CqueryContext

Returns the cqueryctx that holds all the cquery functions. This function takes an optional parameter target_platform, which is the target platform configuration used to configured any unconfigured target nodes.

The target_platform is a target label, or a string that is a target label.


Context.fs

Context.fs: bxl.Filesystem

Returns the bxl.Filesystem for performing a basic set of filesystem operations within bxl


Context.instant_event

def Context.instant_event(
*,
id: str,
metadata,
) -> None

Emits a user-defined instant event, taking in a required string id and a metadata dictionary where the keys are strings, and values are either strings, bools, or ints. The id is user-supplied, and used to identify the instant events in the event logs more easily.

You may pass in an ensured artifact as a value in the metadata. The resulting output would be the ensured artifact's relative or absolute path as a string.


Context.lazy

Context.lazy: bxl.LazyContext

Lazy/batch/error handling operations.


Context.modifiers

Context.modifiers: list[str]

The modfiers from the bxl invocation. It is from the --modifier flag.


Context.output

Context.output: bxl.OutputStream

Gets the output stream to the console via stdout. Items written to the output stream are considered to be the results of a bxl script, which will be displayed to stdout by buck2 even when the script is cached.

Prints that are not result of the bxl should be printed via stderr via the stdlib print and pprint.

This function is not available on the bxl_ctx when called from dynamic_output.


Context.resolve

def Context.resolve(
action_factory: actions,
promise: promise,
)

Awaits a promise and returns an optional value of the promise.

Sample usage:

load("//path/to/rules:rules.bzl", "my_anon_targets_rule", "my_map_function")

def _resolve_impl(ctx):
    actions = ctx.bxl_actions().actions
    my_attrs = {
        "false": False,
        "int": 42,
        "list_string": ["a", "b", "c"],
        "string": "a-string",
        "true": True,
    }

    promise = actions.anon_target(my_anon_targets_rule, attrs).promise.map(my_map_function)
    providers_result = ctx.resolve(actions, promise) # result is `provider_collection` type, which is a collection of `provider`s
    ctx.output.print(providers_result[0].my_field)

Context.root

def Context.root() -> str

Returns the absolute path to the root of the repository

This function is not available on the bxl_ctx when called from dynamic_output.


Context.target_exists

def Context.target_exists(
label: str,
) -> bool

Checks if a target label exists. Target label must be a string literal, and an exact target.


Context.target_platform

Context.target_platform: None | target_label

The target_platform from the bxl invocation. It is from the --target-platforms flag.


Context.target_universe

def Context.target_universe(
labels: bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | str | target_label | target_set | target_set | list[bxl.ConfiguredTargetNode | bxl.UnconfiguredTargetNode | configured_target_label | str | target_label],
target_platform: None | str | target_label = ...,
*,
keep_going: bool = False,
) -> bxl.TargetUniverse

Returns the target_universe that can lookup valid configured nodes in the universe.

The given labels is a target expression, which is either:

  • a single string that is a target pattern.
  • a single target node or label, configured or unconfigured
  • a single subtarget label, configured or unconfigured
  • a list of the two options above.

Also takes in an optional target_platform param to configure the nodes with, and a keep_going`` flag to skip any loading or configuration errors. Note that keep_going` currently can only be used if the input labels is a single target pattern as a string literal.


Context.unconfigured_sub_targets

def Context.unconfigured_sub_targets(
labels: bxl.UnconfiguredTargetNode | providers_label | str | target_label | target_set | list[bxl.UnconfiguredTargetNode | providers_label | str | target_label],
) -> providers_label | dict[str, providers_label]

Gets the unconfigured subtargets for the given labels

The given labels is a providers expression, which is either:

  • a single string that is a target pattern.
  • a single target node or label, configured or unconfigured
  • a single subtarget label, configured or unconfigured
  • a list of the two options above.

This returns either a single providers_label if the given labels argument is "singular", or dict of the subtarget string representation to the providers_label if the given labels argument is list-like.

Note that this function does not check that this subtarget exists in the repo.


Context.unconfigured_targets

def Context.unconfigured_targets(
labels: bxl.UnconfiguredTargetNode | str | target_label | target_set | list[bxl.UnconfiguredTargetNode | str | target_label],
) -> bxl.UnconfiguredTargetNode | target_set

Gets the unconfigured target nodes for the labels

The given labels is either:

  • a single string that is a target pattern.
  • a single unconfigured target node or label
  • a list of the two options above.

This returns either a single [StarlarkTargetNode] if the given labels is "singular", a dict keyed by target labels of [StarlarkTargetNode] if the given labels is list-like


Context.uquery

def Context.uquery(
) -> bxl.UqueryContext

Returns the uqueryctx that holds all uquery functions.