Support disabling the repository cache
Support disabling the repository cache in cases where caching is
not necessary, but the additional disk operations are a problem.
This is achieved by interpreting --repository_cache= as a request
to disable the cache; technically, this is an incompatible change,
as currently the empty string is interpreted as "put the cache
top-level into the workspace". However, it is unlikely that this
use of the option is widely used.
Fixes #6229.
Change-Id: I082e814fc36b60b35e6e0ea6c5db8e892f46c4ef
PiperOrigin-RevId: 215365431
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
index 8aebb29..b6e4167 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
@@ -244,16 +244,19 @@
repositoryCache.setHardlink(repoOptions.useHardlinks);
skylarkRepositoryFunction.setTimeoutScaling(repoOptions.experimentalScaleTimeouts);
if (repoOptions.experimentalRepositoryCache != null) {
- Path repositoryCachePath;
- if (repoOptions.experimentalRepositoryCache.isAbsolute()) {
- repositoryCachePath = filesystem.getPath(repoOptions.experimentalRepositoryCache);
- } else {
- repositoryCachePath =
- env.getBlazeWorkspace()
- .getWorkspace()
- .getRelative(repoOptions.experimentalRepositoryCache);
+ // A set but empty path indicates a request to disable the repository cache.
+ if (!repoOptions.experimentalRepositoryCache.isEmpty()) {
+ Path repositoryCachePath;
+ if (repoOptions.experimentalRepositoryCache.isAbsolute()) {
+ repositoryCachePath = filesystem.getPath(repoOptions.experimentalRepositoryCache);
+ } else {
+ repositoryCachePath =
+ env.getBlazeWorkspace()
+ .getWorkspace()
+ .getRelative(repoOptions.experimentalRepositoryCache);
+ }
+ repositoryCache.setRepositoryCachePath(repositoryCachePath);
}
- repositoryCache.setRepositoryCachePath(repositoryCachePath);
} else {
Path repositoryCachePath =
env.getDirectories()
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
index 39decbc..fbe2348 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
@@ -34,16 +34,16 @@
public class RepositoryOptions extends OptionsBase {
@Option(
- name = "repository_cache",
- oldName = "experimental_repository_cache",
- defaultValue = "null",
- documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS,
- effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
- converter = OptionsUtils.PathFragmentConverter.class,
- help =
- "Specifies the cache location of the downloaded values obtained "
- + "during the fetching of external repositories."
- )
+ name = "repository_cache",
+ oldName = "experimental_repository_cache",
+ defaultValue = "null",
+ documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS,
+ effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
+ converter = OptionsUtils.PathFragmentConverter.class,
+ help =
+ "Specifies the cache location of the downloaded values obtained "
+ + "during the fetching of external repositories. An empty string "
+ + "as argument requests the cache to be disabled.")
public PathFragment experimentalRepositoryCache;
@Option(
diff --git a/src/test/shell/bazel/external_integration_test.sh b/src/test/shell/bazel/external_integration_test.sh
index 5c93100..3cb8c96 100755
--- a/src/test/shell/bazel/external_integration_test.sh
+++ b/src/test/shell/bazel/external_integration_test.sh
@@ -1242,6 +1242,97 @@
expect_log '@ext//:foo'
}
+function test_repository_cache_default() {
+ # Verify that the repository cache is enabled by default.
+ WRKDIR=$(mktemp -d "${TEST_TMPDIR}/testXXXXXX")
+ cd "${WRKDIR}"
+ mkdir ext
+ cat > ext/BUILD <<'EOF'
+genrule(
+ name="foo",
+ outs=["foo.txt"],
+ cmd="echo Hello World > $@",
+ visibility = ["//visibility:public"],
+)
+EOF
+ TOPDIR=`pwd`
+ zip ext.zip ext/*
+ rm -rf ext
+ sha256=$(sha256sum ext.zip | head -c 64)
+
+ rm -rf main
+ mkdir main
+ cd main
+ cat > WORKSPACE <<EOF
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+http_archive(
+ name="ext",
+ strip_prefix="ext",
+ urls=["file://${TOPDIR}/ext.zip"],
+ sha256="${sha256}",
+)
+EOF
+ # Use the external repository once to make sure it is cached.
+ bazel build '@ext//:foo' || fail "expected sucess"
+
+ # Now "go offline" and clean local resources.
+ rm -f "${TOPDIR}/ext.zip"
+ bazel clean --expunge
+
+ # Still, the file should be cached.
+ bazel build '@ext//:foo' || fail "expected success"
+}
+
+function test_cache_disable {
+ # Verify that the repository cache can be disabled.
+ WRKDIR=$(mktemp -d "${TEST_TMPDIR}/testXXXXXX")
+ cd "${WRKDIR}"
+ mkdir ext
+ cat > ext/BUILD <<'EOF'
+genrule(
+ name="foo",
+ outs=["foo.txt"],
+ cmd="echo Hello World > $@",
+ visibility = ["//visibility:public"],
+)
+EOF
+ TOPDIR=`pwd`
+ zip ext.zip ext/*
+ rm -rf ext
+ sha256=$(sha256sum ext.zip | head -c 64)
+
+ rm -rf main
+ mkdir main
+ cd main
+ cat > WORKSPACE <<EOF
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+http_archive(
+ name="ext",
+ strip_prefix="ext",
+ urls=["file://${TOPDIR}/ext.zip"],
+ sha256="${sha256}",
+)
+EOF
+ # Use `--repository_cache` with no path to explicitly disable repository cache
+ bazel build --repository_cache= '@ext//:foo' || fail "expected sucess"
+
+ # make sure, the empty path is not interpreted relative to `pwd`; i.e., we do
+ # not expect any new directories generated in the workspace, in particular
+ # none named conent_adressable, which is the directory where the cache puts
+ # its artifacts into.
+ ls -al | grep content_addressable \
+ && fail "Should not interpret empty path as cache directly in the work space" || :
+
+ # Now "go offline" and clean local resources.
+ rm -f "${TOPDIR}/ext.zip"
+ bazel clean --expunge
+
+ # The build should fail since we are not using the repository cache, but the
+ # original file can no longer be "downloaded".
+ bazel build --repository_cache= '@ext//:foo' \
+ && fail "Should fail for lack of fetchable faile" || :
+}
+
function test_repository_cache() {
# Verify that --repository_cache works for query and caches soly
# based on the predicted hash.