diff --git a/.bcr/patches/go_dev_dep.patch b/.bcr/patches/go_dev_dep.patch index 99b1bc48a..1ade7b2c6 100644 --- a/.bcr/patches/go_dev_dep.patch +++ b/.bcr/patches/go_dev_dep.patch @@ -1,27 +1,27 @@ diff --git a/MODULE.bazel b/MODULE.bazel -index 07a6eff..26702ad 100644 +index e63fa5b..9d78a88 100644 --- a/MODULE.bazel +++ b/MODULE.bazel -@@ -34,19 +34,19 @@ register_toolchains( +@@ -50,19 +50,19 @@ use_repo(host, "aspect_bazel_lib_host") bazel_dep( name = "gazelle", version = "0.33.0", - # In released versions: dev_dependency = True -+ dev_dependency = True ++ dev_dependency = True, ) bazel_dep( name = "rules_go", version = "0.41.0", repo_name = "io_bazel_rules_go", - # In released versions: dev_dependency = True -+ dev_dependency = True ++ dev_dependency = True, ) - + go_deps = use_extension( "@gazelle//:extensions.bzl", "go_deps", - # In released versions: dev_dependency = True -+ dev_dependency = True ++ dev_dependency = True, ) go_deps.from_file(go_mod = "//:go.mod") use_repo( diff --git a/.github/workflows/release_prep.sh b/.github/workflows/release_prep.sh index 6389995a4..c24d21d9a 100755 --- a/.github/workflows/release_prep.sh +++ b/.github/workflows/release_prep.sh @@ -48,25 +48,16 @@ http_archive( url = "https://github.com/aspect-build/bazel-lib/releases/download/${TAG}/${ARCHIVE}", ) -load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies") +load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains") -aspect_bazel_lib_dependencies() - -\`\`\` +# Required bazel-lib dependencies -Optional toolchains: - -\`\`\`starlark -# Register the following toolchain to use jq - -load("@aspect_bazel_lib//lib:repositories.bzl", "register_jq_toolchains") - -register_jq_toolchains() +aspect_bazel_lib_dependencies() -# Register the following toolchain to use yq +# Register bazel-lib toolchains -load("@aspect_bazel_lib//lib:repositories.bzl", "register_yq_toolchains") +aspect_bazel_lib_register_toolchains() -register_yq_toolchains() \`\`\` + EOF diff --git a/MODULE.bazel b/MODULE.bazel index c62c27698..e63fa5b03 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,8 +14,15 @@ bazel_dep(name = "platforms", version = "0.0.7") # 0.5.4 is the first version with bzlmod support bazel_dep(name = "stardoc", version = "0.5.4", repo_name = "io_bazel_stardoc") -ext = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "ext") -use_repo(ext, "bsd_tar_toolchains", "copy_directory_toolchains", "copy_to_directory_toolchains", "coreutils_toolchains", "expand_template_toolchains", "jq_toolchains", "yq_toolchains") +bazel_lib_toolchains = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "toolchains") +bazel_lib_toolchains.copy_directory() +bazel_lib_toolchains.copy_to_directory() +bazel_lib_toolchains.jq() +bazel_lib_toolchains.yq() +bazel_lib_toolchains.coreutils() +bazel_lib_toolchains.tar() +bazel_lib_toolchains.expand_template() +use_repo(bazel_lib_toolchains, "bsd_tar_toolchains", "copy_directory_toolchains", "copy_to_directory_toolchains", "coreutils_toolchains", "expand_template_toolchains", "jq_toolchains", "yq_toolchains") register_toolchains( "@copy_directory_toolchains//:all", @@ -32,6 +39,10 @@ register_toolchains( "@bsd_tar_toolchains//:host_toolchain", ) +host = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "host", dev_dependency = True) +host.host() +use_repo(host, "aspect_bazel_lib_host") + # To allow /tools to be built from source # NOTE: when publishing to BCR, we patch this to be dev_dependency, as we publish pre-built binaries # along with our releases. diff --git a/WORKSPACE b/WORKSPACE index 3d5374de1..9b127f4bb 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,10 +10,12 @@ load(":internal_deps.bzl", "bazel_lib_internal_deps") # Fetch deps needed only locally for development bazel_lib_internal_deps() -load("//lib:repositories.bzl", "aspect_bazel_lib_dependencies") +load("//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains") aspect_bazel_lib_dependencies() +aspect_bazel_lib_register_toolchains() + # For running our own unit tests load("@bazel_skylib//lib:unittest.bzl", "register_unittest_toolchains") diff --git a/docs/jq.md b/docs/jq.md index 3b1af89f7..068262f36 100644 --- a/docs/jq.md +++ b/docs/jq.md @@ -14,14 +14,6 @@ Invoke jq with a filter on a set of json input files. For jq documentation, see https://stedolan.github.io/jq/. -To use this rule you must register the jq toolchain in your WORKSPACE: - -```starlark -load("@aspect_bazel_lib//lib:repositories.bzl", "register_jq_toolchains") - -register_jq_toolchains() -``` - Usage examples: ```starlark diff --git a/docs/repositories.md b/docs/repositories.md index bc7e64dde..f5310b450 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -14,6 +14,21 @@ Load dependencies required by aspect rules + + +## aspect_bazel_lib_register_toolchains + +
+aspect_bazel_lib_register_toolchains() ++ +Register all bazel-lib toolchains at their default versions. + +To be more selective about which toolchains and versions to register, +call the individual toolchain registration macros. + + + ## register_copy_directory_toolchains diff --git a/docs/yq.md b/docs/yq.md index bd1dc2aab..79663a710 100644 --- a/docs/yq.md +++ b/docs/yq.md @@ -14,14 +14,6 @@ Invoke yq with an expression on a set of input files. For yq documentation, see https://mikefarah.gitbook.io/yq. -To use this rule you must register the yq toolchain in your WORKSPACE: - -```starlark -load("@aspect_bazel_lib//lib:repositories.bzl", "register_yq_toolchains") - -register_yq_toolchains() -``` - Usage examples: ```starlark diff --git a/e2e/copy_to_directory/MODULE.bazel b/e2e/copy_to_directory/MODULE.bazel index 33a7fca6d..09d89cf06 100644 --- a/e2e/copy_to_directory/MODULE.bazel +++ b/e2e/copy_to_directory/MODULE.bazel @@ -10,7 +10,3 @@ local_path_override( module_name = "aspect_bazel_lib", path = "../..", ) - -ext = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "ext") -ext.host() -use_repo(ext, "aspect_bazel_lib_host") diff --git a/e2e/copy_to_directory/WORKSPACE b/e2e/copy_to_directory/WORKSPACE index 5238a87a0..e6dddf340 100644 --- a/e2e/copy_to_directory/WORKSPACE +++ b/e2e/copy_to_directory/WORKSPACE @@ -3,10 +3,12 @@ local_repository( path = "../..", ) -load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies") +load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "register_copy_to_directory_toolchains") aspect_bazel_lib_dependencies() +register_copy_to_directory_toolchains() + ############################################ # rules_go is needed to consume tools from sources diff --git a/e2e/coreutils/MODULE.bazel b/e2e/coreutils/MODULE.bazel index b4da586da..abba35543 100644 --- a/e2e/coreutils/MODULE.bazel +++ b/e2e/coreutils/MODULE.bazel @@ -10,5 +10,5 @@ local_path_override( path = "../..", ) -ext = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "ext") -use_repo(ext, "coreutils_toolchains") +bazel_lib_toolchains = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "toolchains") +use_repo(bazel_lib_toolchains, "coreutils_toolchains") diff --git a/e2e/coreutils/WORKSPACE b/e2e/coreutils/WORKSPACE index 880fc9293..4f6c4851a 100644 --- a/e2e/coreutils/WORKSPACE +++ b/e2e/coreutils/WORKSPACE @@ -3,6 +3,8 @@ local_repository( path = "../..", ) -load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies") +load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "register_coreutils_toolchains") aspect_bazel_lib_dependencies() + +register_coreutils_toolchains() diff --git a/e2e/smoke/WORKSPACE b/e2e/smoke/WORKSPACE index 51c5b19e6..85b270732 100644 --- a/e2e/smoke/WORKSPACE +++ b/e2e/smoke/WORKSPACE @@ -3,13 +3,11 @@ local_repository( path = "../..", ) -load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "register_jq_toolchains", "register_yq_toolchains") +load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains") aspect_bazel_lib_dependencies() -register_jq_toolchains() - -register_yq_toolchains() +aspect_bazel_lib_register_toolchains() ############################################ # rules_go is needed to consume tools from sources diff --git a/lib/extensions.bzl b/lib/extensions.bzl index 3fd6fe89f..d3c46dc85 100644 --- a/lib/extensions.bzl +++ b/lib/extensions.bzl @@ -2,6 +2,16 @@ load( "@aspect_bazel_lib//lib:repositories.bzl", + "DEFAULT_COPY_DIRECTORY_REPOSITORY", + "DEFAULT_COPY_TO_DIRECTORY_REPOSITORY", + "DEFAULT_COREUTILS_REPOSITORY", + "DEFAULT_COREUTILS_VERSION", + "DEFAULT_EXPAND_TEMPLATE_REPOSITORY", + "DEFAULT_JQ_REPOSITORY", + "DEFAULT_JQ_VERSION", + "DEFAULT_TAR_REPOSITORY", + "DEFAULT_YQ_REPOSITORY", + "DEFAULT_YQ_VERSION", "register_copy_directory_toolchains", "register_copy_to_directory_toolchains", "register_coreutils_toolchains", @@ -10,17 +20,10 @@ load( "register_tar_toolchains", "register_yq_toolchains", ) +load("//lib/private:extension_utils.bzl", "extension_utils") load("//lib/private:host_repo.bzl", "host_repo") -def _toolchain_extension(mctx): - register_copy_directory_toolchains(register = False) - register_copy_to_directory_toolchains(register = False) - register_jq_toolchains(register = False) - register_yq_toolchains(register = False) - register_coreutils_toolchains(register = False) - register_tar_toolchains(register = False) - register_expand_template_toolchains(register = False) - +def _host_extension_impl(mctx): create_host_repo = False for module in mctx.modules: if len(module.tags.host) > 0: @@ -29,8 +32,77 @@ def _toolchain_extension(mctx): if create_host_repo: host_repo(name = "aspect_bazel_lib_host") -# TODO: some way for users to control repo name/version of the tools installed -ext = module_extension( - implementation = _toolchain_extension, - tag_classes = {"host": tag_class(attrs = {})}, +host = module_extension( + implementation = _host_extension_impl, + tag_classes = { + "host": tag_class(attrs = {}), + }, +) + +def _toolchains_extension_impl(mctx): + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.copy_directory, + toolchain_name = "copy_directory", + toolchain_repos_fn = lambda name, version: register_copy_directory_toolchains(name = name, register = False), + get_version_fn = lambda attr: None, + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.copy_to_directory, + toolchain_name = "copy_to_directory", + toolchain_repos_fn = lambda name, version: register_copy_to_directory_toolchains(name = name, register = False), + get_version_fn = lambda attr: None, + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.jq, + toolchain_name = "jq", + toolchain_repos_fn = lambda name, version: register_jq_toolchains(name = name, version = version, register = False), + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.yq, + toolchain_name = "yq", + toolchain_repos_fn = lambda name, version: register_yq_toolchains(name = name, version = version, register = False), + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.coreutils, + toolchain_name = "coreutils", + toolchain_repos_fn = lambda name, version: register_coreutils_toolchains(name = name, version = version, register = False), + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.tar, + toolchain_name = "tar", + default_repository = DEFAULT_TAR_REPOSITORY, + toolchain_repos_fn = lambda name, version: register_tar_toolchains(name = name, register = False), + get_version_fn = lambda attr: None, + ) + + extension_utils.toolchain_repos_bfs( + mctx = mctx, + get_tag_fn = lambda tags: tags.expand_template, + toolchain_name = "expand_template", + toolchain_repos_fn = lambda name, version: register_expand_template_toolchains(name = name, register = False), + get_version_fn = lambda attr: None, + ) + +toolchains = module_extension( + implementation = _toolchains_extension_impl, + tag_classes = { + "copy_directory": tag_class(attrs = {"name": attr.string(default = DEFAULT_COPY_DIRECTORY_REPOSITORY)}), + "copy_to_directory": tag_class(attrs = {"name": attr.string(default = DEFAULT_COPY_TO_DIRECTORY_REPOSITORY)}), + "jq": tag_class(attrs = {"name": attr.string(default = DEFAULT_JQ_REPOSITORY), "version": attr.string(default = DEFAULT_JQ_VERSION)}), + "yq": tag_class(attrs = {"name": attr.string(default = DEFAULT_YQ_REPOSITORY), "version": attr.string(default = DEFAULT_YQ_VERSION)}), + "coreutils": tag_class(attrs = {"name": attr.string(default = DEFAULT_COREUTILS_REPOSITORY), "version": attr.string(default = DEFAULT_COREUTILS_VERSION)}), + "tar": tag_class(attrs = {"name": attr.string(default = DEFAULT_TAR_REPOSITORY)}), + "expand_template": tag_class(attrs = {"name": attr.string(default = DEFAULT_EXPAND_TEMPLATE_REPOSITORY)}), + }, ) diff --git a/lib/jq.bzl b/lib/jq.bzl index 0a9ce3939..80203c28c 100644 --- a/lib/jq.bzl +++ b/lib/jq.bzl @@ -13,14 +13,6 @@ def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, **k For jq documentation, see https://stedolan.github.io/jq/. - To use this rule you must register the jq toolchain in your WORKSPACE: - - ```starlark - load("@aspect_bazel_lib//lib:repositories.bzl", "register_jq_toolchains") - - register_jq_toolchains() - ``` - Usage examples: ```starlark diff --git a/lib/private/extension_utils.bzl b/lib/private/extension_utils.bzl new file mode 100644 index 000000000..b97e5c7b3 --- /dev/null +++ b/lib/private/extension_utils.bzl @@ -0,0 +1,104 @@ +"""Utility functions for bzlmod extensions""" + +def _toolchain_repos_bfs(mctx, get_tag_fn, toolchain_name, toolchain_repos_fn, default_repository = None, get_name_fn = None, get_version_fn = None): + """Create toolchain repositories from bzlmod extensions using a breadth-first resolution strategy. + + Toolchains are assumed to have a "default" or canonical repository name so that across + all invocations of the module extension with that name only a single toolchain repository + is created. As such, it is recommended to default the toolchain name in the extension's + tag class attributes so that diverging from the canonical name is a special case. + + The resolved toolchain version will be the one invoked closest to the root module, following + Bazel's breadth-first ordering of modules in the dependency graph. + + For example, given the module extension usage in a MODULE file: + + ```starlark + ext = use_extension("@my_lib//lib:extensions.bzl", "ext") + + ext.foo_toolchain(version = "1.2.3") # Default `name = "foo"` + + use_repo(ext, "foo") + + register_toolchains( + "@foo//:all", + ) + ``` + + This macro would be used in the module extension implementation as follows: + + ```starlark + extension_utils.toolchain_repos( + mctx = mctx, + get_tag_fn = lambda tags: tags.foo_toolchain, + toolchain_name = "foo", + toolchain_repos_fn = lambda name, version: register_foo_toolchains(name = name, register = False), + get_version_fn = lambda attr: None, + ) + ``` + + Where `register_foo_toolchains` is a typical WORKSPACE macro used to register + the foo toolchain for a particular version, minus the actual registration step + which is done separately in the MODULE file. + + This macro enforces that only root MODULEs may use a different name for the toolchain + in case several versions of the toolchain repository is desired. + + Args: + mctx: The module context + get_tag_fn: A function that takes in `module.tags` and returns the tag used for the toolchain. + For example, `tag: lambda tags: tags.foo_toolchain`. This is required because `foo_toolchain` + cannot be accessed as a simple string key from `module.tags`. + toolchain_name: Name of the toolchain to use in error messages + toolchain_repos_fn: A function that takes (name, version) and creates a toolchain repository. This lambda + should call a typical reposotiory rule to create toolchains. + default_repository: Default name of the toolchain repository to pass to the repos_fn. + By default, it equals `toolchain_name`. + get_name_fn: A function that extracts the module name from the toolchain tag's attributes. Defaults + to grabbing the `name` attribute. + get_version_fn: A function that extracts the module version from the a tag's attributes. Defaults + to grabbing the `version` attribute. Override this to a lambda that returns `None` if + version isn't used as an attribute. + """ + if default_repository == None: + default_repository = toolchain_name + + if get_name_fn == None: + get_name_fn = lambda attr: attr.name + if get_version_fn == None: + get_version_fn = lambda attr: attr.version + + registrations = {} + for mod in mctx.modules: + for attr in get_tag_fn(mod.tags): + name = get_name_fn(attr) + version = get_version_fn(attr) + if name != default_repository and not mod.is_root: + fail("Only the root module may provide a name for the {} toolchain.".format(toolchain_name)) + + if name in registrations.keys(): + if name == default_repository: + # Prioritize the root-most registration of the default toolchain version and + # ignore any further registrations (modules are processed breadth-first) + continue + if version == registrations[name]: + # No problem to register a matching toolchain twice + continue + fail("Multiple conflicting {} toolchains declared for name {} ({} and {})".format( + toolchain_name, + name, + version, + registrations[name], + )) + else: + registrations[name] = version + + for name, version in registrations.items(): + toolchain_repos_fn( + name = name, + version = version, + ) + +extension_utils = struct( + toolchain_repos_bfs = _toolchain_repos_bfs, +) diff --git a/lib/repositories.bzl b/lib/repositories.bzl index af3dbb3aa..de9312ac7 100644 --- a/lib/repositories.bzl +++ b/lib/repositories.bzl @@ -23,23 +23,10 @@ def aspect_bazel_lib_dependencies(): ], ) - # Always register the copy_to_directory toolchain - register_copy_directory_toolchains() - register_copy_to_directory_toolchains() - - # Always register the expand_template toolchain - register_expand_template_toolchains() - - # Always register the coreutils toolchain and the tar toolchain - register_coreutils_toolchains() - register_tar_toolchains() - -# Re-export the default versions +DEFAULT_JQ_REPOSITORY = "jq" DEFAULT_JQ_VERSION = _DEFAULT_JQ_VERSION -DEFAULT_YQ_VERSION = _DEFAULT_YQ_VERSION -DEFAULT_COREUTILS_VERSION = _DEFAULT_COREUTILS_VERSION -def register_jq_toolchains(name = "jq", version = DEFAULT_JQ_VERSION, register = True): +def register_jq_toolchains(name = DEFAULT_JQ_REPOSITORY, version = DEFAULT_JQ_VERSION, register = True): """Registers jq toolchain and repositories Args: @@ -64,7 +51,10 @@ def register_jq_toolchains(name = "jq", version = DEFAULT_JQ_VERSION, register = user_repository_name = name, ) -def register_yq_toolchains(name = "yq", version = DEFAULT_YQ_VERSION, register = True): +DEFAULT_YQ_REPOSITORY = "yq" +DEFAULT_YQ_VERSION = _DEFAULT_YQ_VERSION + +def register_yq_toolchains(name = DEFAULT_YQ_REPOSITORY, version = DEFAULT_YQ_VERSION, register = True): """Registers yq toolchain and repositories Args: @@ -89,7 +79,9 @@ def register_yq_toolchains(name = "yq", version = DEFAULT_YQ_VERSION, register = user_repository_name = name, ) -def register_tar_toolchains(name = "bsd_tar", register = True): +DEFAULT_TAR_REPOSITORY = "bsd_tar" + +def register_tar_toolchains(name = DEFAULT_TAR_REPOSITORY, register = True): """Registers bsdtar toolchain and repositories Args: @@ -110,7 +102,10 @@ def register_tar_toolchains(name = "bsd_tar", register = True): user_repository_name = name, ) -def register_coreutils_toolchains(name = "coreutils", version = DEFAULT_COREUTILS_VERSION, register = True): +DEFAULT_COREUTILS_REPOSITORY = "coreutils" +DEFAULT_COREUTILS_VERSION = _DEFAULT_COREUTILS_VERSION + +def register_coreutils_toolchains(name = DEFAULT_COREUTILS_REPOSITORY, version = DEFAULT_COREUTILS_VERSION, register = True): """Registers coreutils toolchain and repositories Args: @@ -133,7 +128,9 @@ def register_coreutils_toolchains(name = "coreutils", version = DEFAULT_COREUTIL user_repository_name = name, ) -def register_copy_directory_toolchains(name = "copy_directory", register = True): +DEFAULT_COPY_DIRECTORY_REPOSITORY = "copy_directory" + +def register_copy_directory_toolchains(name = DEFAULT_COPY_DIRECTORY_REPOSITORY, register = True): """Registers copy_directory toolchain and repositories Args: @@ -166,7 +163,9 @@ def register_copy_directory_toolchains(name = "copy_directory", register = True) user_repository_name = name, ) -def register_copy_to_directory_toolchains(name = "copy_to_directory", register = True): +DEFAULT_COPY_TO_DIRECTORY_REPOSITORY = "copy_to_directory" + +def register_copy_to_directory_toolchains(name = DEFAULT_COPY_TO_DIRECTORY_REPOSITORY, register = True): """Registers copy_to_directory toolchain and repositories Args: @@ -199,7 +198,9 @@ def register_copy_to_directory_toolchains(name = "copy_to_directory", register = user_repository_name = name, ) -def register_expand_template_toolchains(name = "expand_template", register = True): +DEFAULT_EXPAND_TEMPLATE_REPOSITORY = "expand_template" + +def register_expand_template_toolchains(name = DEFAULT_EXPAND_TEMPLATE_REPOSITORY, register = True): """Registers expand_template toolchain and repositories Args: @@ -231,3 +232,18 @@ def register_expand_template_toolchains(name = "expand_template", register = Tru name = "%s_toolchains" % name, user_repository_name = name, ) + +# buildifier: disable=unnamed-macro +def aspect_bazel_lib_register_toolchains(): + """Register all bazel-lib toolchains at their default versions. + + To be more selective about which toolchains and versions to register, + call the individual toolchain registration macros. + """ + register_copy_directory_toolchains() + register_copy_to_directory_toolchains() + register_expand_template_toolchains() + register_coreutils_toolchains() + register_jq_toolchains() + register_yq_toolchains() + register_tar_toolchains() diff --git a/lib/yq.bzl b/lib/yq.bzl index 495844604..644912608 100644 --- a/lib/yq.bzl +++ b/lib/yq.bzl @@ -13,14 +13,6 @@ def yq(name, srcs, expression = ".", args = [], outs = None, **kwargs): For yq documentation, see https://mikefarah.gitbook.io/yq. - To use this rule you must register the yq toolchain in your WORKSPACE: - - ```starlark - load("@aspect_bazel_lib//lib:repositories.bzl", "register_yq_toolchains") - - register_yq_toolchains() - ``` - Usage examples: ```starlark