diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl index 5262e9c162..50968b59bf 100644 --- a/rust/private/repository_utils.bzl +++ b/rust/private/repository_utils.bzl @@ -630,6 +630,30 @@ def produce_tool_path(tool_name, target_triple, version): fail("No tool version was provided") return "-".join([e for e in [tool_name, version, target_triple] if e]) +def lookup_tool_sha256(ctx, tool_name, target_triple, version, iso_date, sha256): + """Looks up the sha256 hash of a specific tool archive. + + The lookup order is: + + 1. The sha256s dict in the context attributes; + 2. The list of sha256 hashes populated in //rust:known_shas.bzl; + 3. The sha256 argument to the function + + Args: + ctx (repository_ctx): A repository_ctx (no attrs required). + tool_name (str): The name of the given tool per the archive naming. + target_triple (str): The rust-style target triple of the tool + version (str): The version of the tool among "nightly", "beta', or an exact version. + iso_date (str): The date of the tool (ignored if the version is a specific version). + sha256 (str): The expected hash of hash of the Rust tool. + + Returns: + str: The sha256 of the tool archive, or an empty string if the hash could not be found. + """ + tool_suburl = produce_tool_suburl(tool_name, target_triple, version, iso_date) + archive_path = tool_suburl + _get_tool_extension(ctx) + return getattr(ctx.attr, "sha256s", dict()).get(archive_path) or FILE_KEY_TO_SHA.get(archive_path) or sha256 + def load_arbitrary_tool(ctx, tool_name, tool_subdirectories, version, iso_date, target_triple, sha256 = ""): """Loads a Rust tool, downloads, and extracts into the common workspace. @@ -671,8 +695,8 @@ def load_arbitrary_tool(ctx, tool_name, tool_subdirectories, version, iso_date, urls.append(new_url) tool_path = produce_tool_path(tool_name, target_triple, version) - archive_path = tool_path + _get_tool_extension(ctx) - sha256 = getattr(ctx.attr, "sha256s", dict()).get(archive_path) or FILE_KEY_TO_SHA.get(archive_path) or sha256 + + sha256 = lookup_tool_sha256(ctx, tool_name, target_triple, version, iso_date, sha256) for subdirectory in tool_subdirectories: # As long as the sha256 value is consistent accross calls here the diff --git a/test/unit/repository_utils/repository_utils_test.bzl b/test/unit/repository_utils/repository_utils_test.bzl index 10b0f52192..76143d2ec0 100644 --- a/test/unit/repository_utils/repository_utils_test.bzl +++ b/test/unit/repository_utils/repository_utils_test.bzl @@ -3,7 +3,7 @@ load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") # buildifier: disable=bzl-visibility -load("//rust/private:repository_utils.bzl", "produce_tool_path", "produce_tool_suburl") +load("//rust/private:repository_utils.bzl", "lookup_tool_sha256", "produce_tool_path", "produce_tool_suburl") def _produce_tool_suburl_test_impl(ctx): env = unittest.begin(ctx) @@ -79,12 +79,88 @@ def _produce_tool_path_test_impl(ctx): ) return unittest.end(env) +def _lookup_tool_sha256_test_impl(ctx): + env = unittest.begin(ctx) + + # Release version included in //rust:known_shas.bzl + asserts.equals( + env, + "6a30ffca17a244ad6bfb1d257572155f4e2b08d3ca2d852c2fc7420e264c6baa", + lookup_tool_sha256( + ctx, + tool_name = "rustc", + target_triple = "x86_64-unknown-linux-gnu", + version = "1.65.0", + iso_date = "2022-11-02", + sha256 = "", + ), + ) + + # Values in //rust:known_shas.bzl override sha256 arg + asserts.equals( + env, + "6a30ffca17a244ad6bfb1d257572155f4e2b08d3ca2d852c2fc7420e264c6baa", + lookup_tool_sha256( + ctx, + tool_name = "rustc", + target_triple = "x86_64-unknown-linux-gnu", + version = "1.65.0", + iso_date = "2022-11-02", + sha256 = "FAKE_SHA256_FROM_ARG", + ), + ) + + # Nightly version included in //rust:known_shas.bzl + asserts.equals( + env, + "187f7248dea1c0328e3fb26bb35ad7ba4df901cc34c1c6255260276de8fe3360", + lookup_tool_sha256( + ctx, + tool_name = "rust-std", + target_triple = "x86_64-unknown-linux-gnu", + version = "nightly", + iso_date = "2022-11-02", + sha256 = "", + ), + ) + + # Lookup failure (returns "") for a nightly version not included in //rust:known_shas.bzl + asserts.equals( + env, + "", + lookup_tool_sha256( + ctx, + tool_name = "rust-std", + target_triple = "x86_64-unknown-linux-gnu", + version = "nightly", + iso_date = "2022-11-01", + sha256 = "", + ), + ) + + # A nightly version not included in //rust:known_shas.bzl falls back to sha256 arg + asserts.equals( + env, + "FAKE_SHA256_FROM_ARG", + lookup_tool_sha256( + ctx, + tool_name = "rust-std", + target_triple = "x86_64-unknown-linux-gnu", + version = "nightly", + iso_date = "2022-11-01", + sha256 = "FAKE_SHA256_FROM_ARG", + ), + ) + return unittest.end(env) + produce_tool_suburl_test = unittest.make(_produce_tool_suburl_test_impl) produce_tool_path_test = unittest.make(_produce_tool_path_test_impl) +lookup_tool_sha256_test = unittest.make(_lookup_tool_sha256_test_impl) def repository_utils_test_suite(name): unittest.suite( name, produce_tool_suburl_test, produce_tool_path_test, + lookup_tool_sha256_test, )