Adds cycle detection errors when top-level dynamic
configuration creation fails because transitive fragment
visitation hits these cycles.
This makes CircularDependencyTest pass with dynamic
configurations.
It's a little bit unfortunate that BuildViewTestCase
follows a different code path to create configured targets
than production (BuildView.getConfiguredTargetForTesting
vs. BuildView.update). As a result, doing an actual build over
the rules defined in CircularDependencyTest#testTwoCycles
correctly reports the cycle, while the test itself doesn't.
That means the test isn't 100% faithfully testing production
logic.
But I'm not interested in fixing the gap between
BuildView.update and BuildView.getConfiguredTargetForTesting
in this change. That's part of a larger refactoring effort
on the various forked ways of acccessing configured targets
and dependencies in BuildView.
--
MOS_MIGRATED_REVID=125118553
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 63486e6..d497c30 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -1201,10 +1201,7 @@
EvaluationResult<SkyValue> result = evaluateSkyKeys(eventHandler, skyKeys);
for (Map.Entry<SkyKey, ErrorInfo> entry : result.errorMap().entrySet()) {
- getCyclesReporter().reportCycles(
- entry.getValue().getCycleInfo(),
- entry.getKey(),
- eventHandler);
+ reportCycles(eventHandler, entry.getValue().getCycleInfo(), entry.getKey());
}
ImmutableMap.Builder<Dependency, ConfiguredTarget> cts = ImmutableMap.builder();
@@ -1274,6 +1271,9 @@
}
EvaluationResult<SkyValue> fragmentsResult = evaluateSkyKeys(
eventHandler, transitiveFragmentSkyKeys, /*keepGoing=*/true);
+ for (Map.Entry<SkyKey, ErrorInfo> entry : fragmentsResult.errorMap().entrySet()) {
+ reportCycles(eventHandler, entry.getValue().getCycleInfo(), entry.getKey());
+ }
for (Dependency key : keys) {
if (!depsToEvaluate.contains(key)) {
// No fragments to compute here.
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
index 51ba85f..525c55b 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
@@ -478,7 +478,15 @@
assertContainsEvent("and referenced by '//foo:bad'");
assertContainsEvent("in sh_library rule //foo");
assertContainsEvent("cycle in dependency graph");
- assertEventCount(3, eventCollector);
+ // Dynamic configurations trigger this error both in configuration trimming (which visits
+ // the transitive target closure) and in the normal configured target cycle detection path.
+ // So we get an additional instance of this check (which varies depending on whether Skyframe
+ // loading phase is enabled).
+ // TODO(gregce): refactor away this variation. Note that the duplicate doesn't make it into
+ // real user output (it only affects tests).
+ if (!getTargetConfiguration().useDynamicConfigurations()) {
+ assertEventCount(3, eventCollector);
+ }
}
@Test