Skip to content

Commit f15e0c7

Browse files
Add --experimental_repository_cache_urls_as_default_canonical_id to help detect broken repository URLs (bazelbuild#14989)
This new flag can be used to force redownloading when repository URLs are changed. Otherwise, it's possible broken URLs can be masked by the presence of a repository cache entry with the same hash. Specifying a `canonical_id` works as before, overriding this behavior. Closes bazelbuild#14128. Closes bazelbuild#14268. PiperOrigin-RevId: 420976730 (cherry picked from commit f9882e4) Co-authored-by: Ken Micklas <[email protected]>
1 parent 0764821 commit f15e0c7

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
274274
if (repoOptions.repositoryDownloaderRetries >= 0) {
275275
downloadManager.setRetries(repoOptions.repositoryDownloaderRetries);
276276
}
277+
downloadManager.setUrlsAsDefaultCanonicalId(repoOptions.urlsAsDefaultCanonicalId);
277278

278279
repositoryCache.setHardlink(repoOptions.useHardlinks);
279280
if (repoOptions.experimentalScaleTimeouts > 0.0) {

src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java

+13
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,19 @@ public class RepositoryOptions extends OptionsBase {
215215
+ " to escalate it to a resolution failure.")
216216
public CheckDirectDepsMode checkDirectDependencies;
217217

218+
@Option(
219+
name = "experimental_repository_cache_urls_as_default_canonical_id",
220+
defaultValue = "false",
221+
documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS,
222+
effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
223+
metadataTags = {OptionMetadataTag.EXPERIMENTAL},
224+
help =
225+
"If true, use a string derived from the URLs of repository downloads as the canonical_id "
226+
+ "if not specified. This causes a change in the URLs to result in a redownload even "
227+
+ "if the cache contains a download with the same hash. This can be used to verify "
228+
+ "that URL changes don't result in broken repositories being masked by the cache.")
229+
public boolean urlsAsDefaultCanonicalId;
230+
218231
/** An enum for specifying different modes for checking direct dependency accuracy. */
219232
public enum CheckDirectDepsMode {
220233
OFF, // Don't check direct dependency accuracy.

src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/DownloadManager.java

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.net.URL;
3737
import java.util.List;
3838
import java.util.Map;
39+
import java.util.stream.Collectors;
3940
import javax.annotation.Nullable;
4041

4142
/**
@@ -52,6 +53,7 @@ public class DownloadManager {
5253
private final Downloader downloader;
5354
private boolean disableDownload = false;
5455
private int retries = 0;
56+
private boolean urlsAsDefaultCanonicalId;
5557

5658
public DownloadManager(RepositoryCache repositoryCache, Downloader downloader) {
5759
this.repositoryCache = repositoryCache;
@@ -75,6 +77,10 @@ public void setRetries(int retries) {
7577
this.retries = retries;
7678
}
7779

80+
public void setUrlsAsDefaultCanonicalId(boolean urlsAsDefaultCanonicalId) {
81+
this.urlsAsDefaultCanonicalId = urlsAsDefaultCanonicalId;
82+
}
83+
7884
/**
7985
* Downloads file to disk and returns path.
8086
*
@@ -109,6 +115,10 @@ public Path download(
109115
throw new InterruptedException();
110116
}
111117

118+
if (Strings.isNullOrEmpty(canonicalId) && urlsAsDefaultCanonicalId) {
119+
canonicalId = originalUrls.stream().map(URL::toExternalForm).collect(Collectors.joining(" "));
120+
}
121+
112122
ImmutableList<URL> rewrittenUrls = ImmutableList.copyOf(originalUrls);
113123
Map<URI, Map<String, String>> rewrittenAuthHeaders = authHeaders;
114124

src/test/shell/bazel/bazel_repository_cache_test.sh

+64
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,68 @@ EOF
465465
expect_log "Error downloading"
466466
}
467467

468+
function test_break_url() {
469+
setup_repository
470+
471+
bazel fetch --repository_cache="$repo_cache_dir" //zoo:breeding-program >& $TEST_log \
472+
|| echo "Expected fetch to succeed"
473+
474+
shutdown_server
475+
476+
bazel fetch --repository_cache="$repo_cache_dir" //zoo:breeding-program >& $TEST_log \
477+
|| echo "Expected fetch to succeed"
478+
479+
# Break url in WORKSPACE
480+
rm WORKSPACE
481+
cat >> $(create_workspace_with_default_repos WORKSPACE) <<EOF
482+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
483+
484+
http_archive(
485+
name = 'endangered',
486+
url = 'http://localhost:$nc_port/bleh.broken',
487+
sha256 = '$sha256',
488+
type = 'zip',
489+
)
490+
EOF
491+
492+
# By default, cache entry will still match by sha256, even if url is changed.
493+
bazel fetch --repository_cache="$repo_cache_dir" //zoo:breeding-program >& $TEST_log \
494+
|| echo "Expected fetch to succeed"
495+
}
496+
497+
function test_experimental_repository_cache_urls_as_default_canonical_id() {
498+
setup_repository
499+
500+
bazel fetch --repository_cache="$repo_cache_dir" \
501+
--experimental_repository_cache_urls_as_default_canonical_id \
502+
//zoo:breeding-program >& $TEST_log \
503+
|| echo "Expected fetch to succeed"
504+
505+
shutdown_server
506+
507+
bazel fetch --repository_cache="$repo_cache_dir" \
508+
--experimental_repository_cache_urls_as_default_canonical_id \
509+
//zoo:breeding-program >& $TEST_log \
510+
|| echo "Expected fetch to succeed"
511+
512+
# Break url in WORKSPACE
513+
rm WORKSPACE
514+
cat >> $(create_workspace_with_default_repos WORKSPACE) <<EOF
515+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
516+
517+
http_archive(
518+
name = 'endangered',
519+
url = 'http://localhost:$nc_port/bleh.broken',
520+
sha256 = '$sha256',
521+
type = 'zip',
522+
)
523+
EOF
524+
525+
# As repository cache key should depend on urls, we expect fetching to fail now.
526+
bazel fetch --repository_cache="$repo_cache_dir" \
527+
--experimental_repository_cache_urls_as_default_canonical_id \
528+
//zoo:breeding-program >& $TEST_log \
529+
&& fail "expected failure" || :
530+
}
531+
468532
run_suite "repository cache tests"

0 commit comments

Comments
 (0)