Enable analysis caching codepaths only for commands that execute actions.
For example, this includes `test` and `build`, but does not include `cquery`.
This prevents the use case where the someone adds `build
--experimental_remote_analysis_cache_mode=download` by default into their
bazelrc, and runs a cquery command (which, WAI, picks up the flag, because
`CqueryCommand` inherits options from `TestCommand`, which inherits from
`BuildCommand`), and fails to this cryptic error:
```
$ bazel cquery 'somepath(//foo, //bar)'
ERROR: Failed to find PROJECT.scl file for: [//foo:foo, //bar:bar]
INFO: Elapsed time: 0.078s
ERROR: Build did NOT complete successfully
```
It also doesn't make sense to support analysis caching with cquery anyway, because correct results require a complete, unpruned analysis graph.
Same goes for `aquery`.
PiperOrigin-RevId: 689397164
Change-Id: Ib63ab41450b84e782d69e148196b2bfa6413e65f
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/AnalysisPhaseRunner.java b/src/main/java/com/google/devtools/build/lib/buildtool/AnalysisPhaseRunner.java
index b0ce8b4..c15e337 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/AnalysisPhaseRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/AnalysisPhaseRunner.java
@@ -208,7 +208,8 @@
throws LoadingFailedException, InvalidConfigurationException {
EnumSet<ProjectFileFeature> featureFlags = EnumSet.noneOf(ProjectFileFeature.class);
- if (env.getOptions().getOptions(RemoteAnalysisCachingOptions.class).mode != OFF) {
+ if (env.getCommand().buildPhase().executes()
+ && env.getOptions().getOptions(RemoteAnalysisCachingOptions.class).mode != OFF) {
// RemoteAnalysisCachingOptions is never null because it's a build command flag, and this
// method only runs for build commands.
featureFlags.add(ANALYSIS_CACHING);
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index 53333e1..1718530 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -850,7 +850,7 @@
}
RemoteAnalysisCachingOptions options = request.getOptions(RemoteAnalysisCachingOptions.class);
- if (options == null) {
+ if (options == null || !env.getCommand().buildPhase().executes()) {
return;
}
@@ -1108,6 +1108,7 @@
CommandEnvironment env, Optional<PathFragmentPrefixTrie> activeDirectoriesMatcher) {
var options = env.getOptions().getOptions(RemoteAnalysisCachingOptions.class);
if (options == null
+ || !env.getCommand().buildPhase().executes()
|| !options.mode.downloadForAnalysis()
|| activeDirectoriesMatcher.isEmpty()) {
return DisabledDependenciesProvider.INSTANCE;
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/BUILD
index e062e57..ee48774 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/BUILD
@@ -15,6 +15,7 @@
"//src/main/java/com/google/devtools/build/lib/analysis:configured_target_value",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/pkgcache",
+ "//src/main/java/com/google/devtools/build/lib/runtime/commands",
"//src/main/java/com/google/devtools/build/lib/skyframe:aspect_key_creator",
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_key",
"//src/main/java/com/google/devtools/build/lib/skyframe:rule_configured_target_value",
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/FrontierSerializerTestBase.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/FrontierSerializerTestBase.java
index edee016..d74be69 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/FrontierSerializerTestBase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/analysis/FrontierSerializerTestBase.java
@@ -31,6 +31,7 @@
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.pkgcache.LoadingFailedException;
+import com.google.devtools.build.lib.runtime.commands.CqueryCommand;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectBaseKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.RemoteConfiguredTargetValue;
@@ -534,6 +535,37 @@
.hasCount(SkyFunctions.CONFIGURED_TARGET, serializedConfiguredTargetCount - 1);
}
+ @Test
+ public void cquery_succeedsAndDoesNotTriggerUpload() throws Exception {
+ setupScenarioWithConfiguredTargets();
+ addOptions("--experimental_remote_analysis_cache_mode=upload");
+ runtimeWrapper.newCommand(CqueryCommand.class);
+ buildTarget("//foo:A"); // passes, even though there's no PROJECT.scl
+ assertThat(
+ getCommandEnvironment()
+ .getRemoteAnalysisCachingEventListener()
+ .getSerializedKeysCount())
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void cquery_succeedsAndDoesNotTriggerUploadWithProjectScl() throws Exception {
+ setupScenarioWithConfiguredTargets();
+ write(
+ "foo/PROJECT.scl",
+ """
+active_directories = { "default": ["foo"] }
+""");
+ addOptions("--experimental_remote_analysis_cache_mode=upload");
+ runtimeWrapper.newCommand(CqueryCommand.class);
+ buildTarget("//foo:A");
+ assertThat(
+ getCommandEnvironment()
+ .getRemoteAnalysisCachingEventListener()
+ .getSerializedKeysCount())
+ .isEqualTo(0);
+ }
+
protected void setupScenarioWithConfiguredTargets() throws Exception {
// ┌───────┐ ┌───────┐
// │ bar:C │ ◀── │ foo:A │