Skip to content

Commit

Permalink
[6.4.0] Print dep chain leading to a module that is in error (#19543)
Browse files Browse the repository at this point in the history
When a module file has an error, this now results in an error such as:

```
ERROR: Error computing the main repository mapping: in module dependency chain <root> -> grpc@1.48.1.bcr.1 -> re2@2021-09-01: the MODULE.bazel file of re2@2021-09-01 declares a different version (2021-09-02)
```

Closes #19535.

Commit
184796d

PiperOrigin-RevId: 565759770
Change-Id: I8ec788de4e83f59cc5ff5dc6f9fac19322181c08

Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
  • Loading branch information
bazel-io and fmeum authored Sep 15, 2023
1 parent d17f5e9 commit 3142438
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ private static Selection.Result discoverAndSelect(
ImmutableMap<ModuleKey, InterimModule> initialDepGraph;
try (SilentCloseable c = Profiler.instance().profile(ProfilerTask.BZLMOD, "discovery")) {
initialDepGraph = Discovery.run(env, root);
} catch (ExternalDepsException e) {
throw new BazelModuleResolutionFunctionException(e, Transience.PERSISTENT);
}
if (initialDepGraph == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@

package com.google.devtools.build.lib.bazel.bzlmod;

import static java.util.stream.Collectors.joining;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.bazel.bzlmod.InterimModule.DepSpec;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue.RootModuleFileValue;
import com.google.devtools.build.lib.server.FailureDetails;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyframeLookupResult;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
Expand All @@ -43,12 +49,14 @@ private Discovery() {}
*/
@Nullable
public static ImmutableMap<ModuleKey, InterimModule> run(
Environment env, RootModuleFileValue root) throws InterruptedException {
Environment env, RootModuleFileValue root)
throws InterruptedException, ExternalDepsException {
String rootModuleName = root.getModule().getName();
ImmutableMap<String, ModuleOverride> overrides = root.getOverrides();
Map<ModuleKey, InterimModule> depGraph = new HashMap<>();
depGraph.put(ModuleKey.ROOT, rewriteDepSpecs(root.getModule(), overrides, rootModuleName));
Queue<ModuleKey> unexpanded = new ArrayDeque<>();
Map<ModuleKey, ModuleKey> predecessors = new HashMap<>();
unexpanded.add(ModuleKey.ROOT);
while (!unexpanded.isEmpty()) {
Set<SkyKey> unexpandedSkyKeys = new HashSet<>();
Expand All @@ -58,14 +66,36 @@ public static ImmutableMap<ModuleKey, InterimModule> run(
if (depGraph.containsKey(depSpec.toModuleKey())) {
continue;
}
predecessors.putIfAbsent(depSpec.toModuleKey(), module.getKey());
unexpandedSkyKeys.add(
ModuleFileValue.key(depSpec.toModuleKey(), overrides.get(depSpec.getName())));
}
}
SkyframeLookupResult result = env.getValuesAndExceptions(unexpandedSkyKeys);
for (SkyKey skyKey : unexpandedSkyKeys) {
ModuleKey depKey = ((ModuleFileValue.Key) skyKey).getModuleKey();
ModuleFileValue moduleFileValue = (ModuleFileValue) result.get(skyKey);
ModuleFileValue moduleFileValue;
try {
moduleFileValue =
(ModuleFileValue) result.getOrThrow(skyKey, ExternalDepsException.class);
} catch (ExternalDepsException e) {
// Trace back a dependency chain to the root module. There can be multiple paths to the
// failing module, but any of those is useful for debugging.
List<ModuleKey> depChain = new ArrayList<>();
depChain.add(depKey);
ModuleKey predecessor = depKey;
while ((predecessor = predecessors.get(predecessor)) != null) {
depChain.add(predecessor);
}
Collections.reverse(depChain);
String depChainString =
depChain.stream().map(ModuleKey::toString).collect(joining(" -> "));
throw ExternalDepsException.withCauseAndMessage(
FailureDetails.ExternalDeps.Code.BAD_MODULE,
e,
"in module dependency chain %s",
depChainString);
}
if (moduleFileValue == null) {
// Don't return yet. Try to expand any other unexpanded nodes before returning.
depGraph.put(depKey, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,13 @@ public SkyValue compute(SkyKey skyKey, Environment env)
if (root == null) {
return null;
}
ImmutableMap<ModuleKey, InterimModule> depGraph = Discovery.run(env, root);
ImmutableMap<ModuleKey, InterimModule> depGraph;
try {
depGraph = Discovery.run(env, root);
} catch (ExternalDepsException e) {
throw new BazelModuleResolutionFunction.BazelModuleResolutionFunctionException(
e, SkyFunctionException.Transience.PERSISTENT);
}
return depGraph == null ? null : DiscoveryValue.create(depGraph);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/test/py/bazel/bzlmod/bazel_lockfile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ def testChangeModuleInRegistryWithoutLockfile(self):
self.AssertExitCode(exit_code, 48, stderr)
self.assertIn(
(
'ERROR: Error computing the main repository mapping: error parsing'
' MODULE.bazel file for sss@1.3'
'ERROR: Error computing the main repository mapping: in module '
'dependency chain <root> -> sss@1.3: error parsing MODULE.bazel '
'file for sss@1.3'
),
stderr,
)
Expand Down

0 comments on commit 3142438

Please sign in to comment.