load_arbitrary_tool uses tool_suburl to look up sha256 (#1695)
* load_arbitrary_tool uses tool_suburl to look up sha256
In load_arbitrary_tool, use the suburl (which contains the a
subdirectory containing the date, if the version is beta or nightly) to
look up the sha256 to to download a specific archive. This allows Bazel
to cache the downloaded archive by hash, and supports the correct
behavior for dated nightly builds, as provided in the FILE_KEY_TO_SHA
dict in //rust:known_shas.bzl.
The most recent nightly entry is given in FILE_KEY_TO_SHA as:
```
"2022-11-02/cargo-nightly-x86_64-unknown-linux-gnu.tar.gz": "d32e0a9f78ece567627b9b572912b000c53099c0dd9c9f5cea54848de02c6486",
```
This change fixes downloaded archive caching when using the nightly
toolchains, including the default nightly toolchain.
* Refactor load_arbitrary_tool()
Move the sha256 code out of load_arbitrary_tool() into a new function,
lookup_tool_sha256().
Implement a new unit test to confirm that the sha256 lookup code behaves
as expected, and returns the expected sha256 hash from the static list
of known tool hashes.
diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl
index 5262e9c..50968b5 100644
--- a/rust/private/repository_utils.bzl
+++ b/rust/private/repository_utils.bzl
@@ -630,6 +630,30 @@
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 @@
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 10b0f52..76143d2 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 @@
)
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,
)