diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java index 7dbba89f7759dc..c715129c70da39 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java @@ -602,11 +602,14 @@ private StructImpl completeDownload(PendingDownload pendingDownload) name = "download", doc = """ - Downloads a file to the output path for the provided url and returns a struct \ - containing success, a flag which is true if the \ - download completed successfully, and if successful, a hash of the file \ - with the fields sha256 and integrity. - """, +Downloads a file to the output path for the provided url and returns a struct \ +containing success, a flag which is true if the \ +download completed successfully, and if successful, a hash of the file \ +with the fields sha256 and integrity. \ +When sha256 or integrity is user specified, setting an explicit \ +canonical_id is highly recommended. e.g. \ +get_default_canonical_id +""", useStarlarkThread = true, parameters = { @Param( @@ -801,11 +804,14 @@ public Object download( name = "download_and_extract", doc = """ - Downloads a file to the output path for the provided url, extracts it, and returns a \ - struct containing success, a flag which is true if the \ - download completed successfully, and if successful, a hash of the file with the \ - fields sha256 and integrity. - """, +Downloads a file to the output path for the provided url, extracts it, and returns a \ +struct containing success, a flag which is true if the \ +download completed successfully, and if successful, a hash of the file with the \ +fields sha256 and integrity. \ +When sha256 or integrity is user specified, setting an explicit \ +canonical_id is highly recommended. e.g. \ +get_default_canonical_id +""", useStarlarkThread = true, parameters = { @Param( diff --git a/src/test/shell/bazel/external_integration_test.sh b/src/test/shell/bazel/external_integration_test.sh index a36fc10e29583c..e1c75c33bb678d 100755 --- a/src/test/shell/bazel/external_integration_test.sh +++ b/src/test/shell/bazel/external_integration_test.sh @@ -3036,6 +3036,50 @@ EOF test -h "$execroot/external/+_repo_rules+ext" || fail "Expected symlink to external repo." } +function test_default_canonical_id_enabled() { + cat > repo.bzl < MODULE.bazel <$TEST_log || fail 'Expected fetch to succeed' + expect_log "canonical_id \"url-1 url-2\"" +} + +function test_default_canonical_id_disabled() { + cat > repo.bzl < MODULE.bazel <$TEST_log || fail 'Expected fetch to succeed' + expect_log "canonical_id \"\"" +} + function test_environ_incrementally() { # Set up workspace with a repository rule to examine env vars. Assert that undeclared # env vars don't trigger reevaluations. diff --git a/src/test/tools/bzlmod/MODULE.bazel.lock b/src/test/tools/bzlmod/MODULE.bazel.lock index 4d7e3f148d0c0a..c7e00769146abe 100644 --- a/src/test/tools/bzlmod/MODULE.bazel.lock +++ b/src/test/tools/bzlmod/MODULE.bazel.lock @@ -78,7 +78,7 @@ }, "@@rules_jvm_external+//:extensions.bzl%maven": { "general": { - "bzlTransitiveDigest": "ktqZUWl2nBo/3HEhakOj9tfmT3+/Z90z7ldq8XwxYnE=", + "bzlTransitiveDigest": "tgBpQFC46MaT8n2UeSnG4GNQ8M01bKKTeEWQX+cuoSA=", "usagesDigest": "G7bV9l+zJ2RkplFf3E987nj8RPcxAqfzTHS5Zdc3rZw=", "recordedFileInputs": { "@@rules_jvm_external+//rules_jvm_external_deps_install.json": "10442a5ae27d9ff4c2003e5ab71643bf0d8b48dcf968b4173fa274c3232a8c06" @@ -1102,7 +1102,7 @@ }, "@@rules_jvm_external+//:non-module-deps.bzl%non_module_deps": { "general": { - "bzlTransitiveDigest": "4VF2Z/DNZaLHTP3izo0uTvnjS8it3dSViL5+ack4ogE=", + "bzlTransitiveDigest": "7dxAT2NQpsWXJNV5Sy6o7E78vgRhVEN1vlZdrexTMZY=", "usagesDigest": "Ogn82YkpKa5kvheD/dv6YN0tP3nfvTIqAuPJrebCbWM=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -1130,7 +1130,7 @@ }, "@@rules_python+//python/extensions:python.bzl%python": { "general": { - "bzlTransitiveDigest": "e3ZmjG1ZEg3xSbspFPC5afi43pqfpAU89V2ghTtcNug=", + "bzlTransitiveDigest": "z35lvtk23Cj8pA0OHXIWJQ+sP4WORVrujhMDtWGyqo8=", "usagesDigest": "dMk5TOHswAZLEIKE5VenuXubFWbTzMdJplFIkYHPSSU=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -1160,7 +1160,7 @@ }, "@@rules_python+//python/extensions/private:internal_deps.bzl%internal_deps": { "general": { - "bzlTransitiveDigest": "f4sn8DF0csno6nVTa/bU1ixR43r+jYeZRRCD3xniTxQ=", + "bzlTransitiveDigest": "59ucGaK2UFzBbVlrE4x4O1jM4EWKd3zAXRUH63T4j68=", "usagesDigest": "B/G2N6d9Y4VpHFgkQT4wRYFBJ9RP+vFT/Ngiwz7Ejt8=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, diff --git a/tools/build_defs/repo/BUILD b/tools/build_defs/repo/BUILD index 5106cd4aa4a06e..7f4421ec4a22bf 100644 --- a/tools/build_defs/repo/BUILD +++ b/tools/build_defs/repo/BUILD @@ -40,6 +40,7 @@ genrule( ) REPO_BZL_FILES = [ + "cache", "git", "http", "local", diff --git a/tools/build_defs/repo/cache.bzl b/tools/build_defs/repo/cache.bzl index 8381446da242ff..578ed72c6fabfb 100644 --- a/tools/build_defs/repo/cache.bzl +++ b/tools/build_defs/repo/cache.bzl @@ -20,7 +20,7 @@ """Returns the default canonical id to use for downloads.""" -visibility("private") +visibility("public") DEFAULT_CANONICAL_ID_ENV = "BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID" @@ -37,7 +37,28 @@ machines without the file in the cache. This behavior can be disabled with """.format(env = DEFAULT_CANONICAL_ID_ENV) def get_default_canonical_id(repository_ctx, urls): - """Returns the default canonical id to use for downloads.""" + """Returns the default canonical id to use for downloads. + + Returns `""` (empty string) when Bazel is run with + `--repo_env=BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID=0`. + + e.g. + ```python + load("@bazel_tools//tools/build_defs/repo:cache.bzl", "get_default_canonical_id") + # ... + repository_ctx.download_and_extract( + url = urls, + integrity = integrity + canonical_id = get_default_canonical_id(repository_ctx, urls), + ), + ``` + + Args: + repository_ctx: The repository context of the repository rule calling this utility + function. + urls: A list of URLs matching what is passed to `repository_ctx.download` and + `repository_ctx.download_and_extract`. + """ if repository_ctx.os.environ.get(DEFAULT_CANONICAL_ID_ENV) == "0": return ""