From fc601ba32f21ec034baebc487646dea92afbcd04 Mon Sep 17 00:00:00 2001 From: Eric McBride Date: Tue, 26 Mar 2024 12:11:50 -0500 Subject: [PATCH] Fix cargo-bazel recompile for MODULE.bazel (#2570) - Addresses https://github.com/bazelbuild/rules_rust/issues/2531 - Wrote a function, thats basically copy / pasted from `crates_universe/private/generate_utils.bzl` to account for the `module_ctx` Can probably make the original function more generic if thats more desired. I'm not sure if the maintainers would prefer a one off, since the `MODULE.bazel `feature set for `crates_universe` isn't exactly "Stable" yet. - Noticed theres no way to "bootstrap" the new `cargo` features in `MODULE.bazel` , like you can for `crates_universe`. May need to open an issue for this. Tested by using the `CARGO_BAZEL_GENERATOR_URL` and `CARGO_BAZEL_GENERATOR_SHA256` environmentals. This looks to cause some failing unit tests. Not sure how to get support on this - Failsafe of using the cargo buildstrap `cargo-bazel` if no URLs are found, and if theres no environmentals. --------- Co-authored-by: UebelAndre --- crate_universe/extension.bzl | 56 ++++++++++++++++++- .../cargo_bazel_bootstrap.bzl | 5 +- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/crate_universe/extension.bzl b/crate_universe/extension.bzl index 0fddfa30c2..a1c6a3615a 100644 --- a/crate_universe/extension.bzl +++ b/crate_universe/extension.bzl @@ -5,8 +5,10 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("//crate_universe:defs.bzl", _crate_universe_crate = "crate") load("//crate_universe/private:crates_vendor.bzl", "CRATES_VENDOR_ATTRS", "generate_config_file", "generate_splicing_manifest") -load("//crate_universe/private:generate_utils.bzl", "render_config") +load("//crate_universe/private:generate_utils.bzl", "CARGO_BAZEL_GENERATOR_SHA256", "CARGO_BAZEL_GENERATOR_URL", "GENERATOR_ENV_VARS", "render_config") +load("//crate_universe/private:urls.bzl", "CARGO_BAZEL_SHA256S", "CARGO_BAZEL_URLS") load("//crate_universe/private/module_extensions:cargo_bazel_bootstrap.bzl", "get_cargo_bazel_runner") +load("//rust/platform:triple.bzl", "get_host_triple") # A list of labels which may be relative (and if so, is within the repo the rule is generated in). # @@ -220,8 +222,58 @@ def _package_to_json(p): if v }) +def _get_generator(module_ctx): + """Query Network Resources to local a `cargo-bazel` binary. + + Based off get_generator in crates_universe/private/generate_utils.bzl + + Args: + module_ctx (module_ctx): The rules context object + + Returns: + tuple(path, dict) The path to a 'cargo-bazel' binary. The pairing (dict) + may be `None` if there is not need to update the attribute + """ + host_triple = get_host_triple(module_ctx) + use_environ = False + for var in GENERATOR_ENV_VARS: + if var in module_ctx.os.environ: + use_environ = True + + if use_environ: + generator_sha256 = module_ctx.os.environ.get(CARGO_BAZEL_GENERATOR_SHA256) + generator_url = module_ctx.os.environ.get(CARGO_BAZEL_GENERATOR_URL) + elif len(CARGO_BAZEL_URLS) == 0: + return module_ctx.path(Label("@cargo_bazel_bootstrap//:cargo-bazel")) + else: + generator_sha256 = CARGO_BAZEL_SHA256S.get(host_triple) + generator_url = CARGO_BAZEL_URLS.get(host_triple) + + if not generator_url: + fail(( + "No generator URL was found either in the `CARGO_BAZEL_GENERATOR_URL` " + + "environment variable or for the `{}` triple in the `generator_urls` attribute" + ).format(host_triple)) + + output = module_ctx.path("cargo-bazel.exe" if "win" in module_ctx.os.name else "cargo-bazel") + + # Download the file into place + download_kwargs = { + "executable": True, + "output": output, + "url": generator_url, + } + + if generator_sha256: + download_kwargs.update({"sha256": generator_sha256}) + + module_ctx.download(**download_kwargs) + return output + def _crate_impl(module_ctx): - cargo_bazel = get_cargo_bazel_runner(module_ctx) + cargo_bazel_output = _get_generator(module_ctx) + cargo_bazel = get_cargo_bazel_runner(module_ctx, cargo_bazel_output) + all_repos = [] for mod in module_ctx.modules: module_annotations = {} diff --git a/crate_universe/private/module_extensions/cargo_bazel_bootstrap.bzl b/crate_universe/private/module_extensions/cargo_bazel_bootstrap.bzl index ae98cb8a8c..e5b639100d 100644 --- a/crate_universe/private/module_extensions/cargo_bazel_bootstrap.bzl +++ b/crate_universe/private/module_extensions/cargo_bazel_bootstrap.bzl @@ -15,12 +15,12 @@ cargo_bazel_bootstrap = module_extension( doc = """Module extension to generate the cargo_bazel binary.""", ) -def get_cargo_bazel_runner(module_ctx): +def get_cargo_bazel_runner(module_ctx, cargo_bazel): """A helper function to allow executing cargo_bazel in module extensions. Args: module_ctx: The module extension's context. - + cargo_bazel: Path The path to a `cargo-bazel` binary Returns: A function that can be called to execute cargo_bazel. """ @@ -30,7 +30,6 @@ def get_cargo_bazel_runner(module_ctx): cargo_path = str(module_ctx.path(Label("@rust_host_tools//:bin/cargo{}".format(binary_ext)))) rustc_path = str(module_ctx.path(Label("@rust_host_tools//:bin/rustc{}".format(binary_ext)))) - cargo_bazel = module_ctx.path(Label("@cargo_bazel_bootstrap//:cargo-bazel")) # Placing this as a nested function allows users to call this right at the # start of a module extension, thus triggering any restarts as early as