diff --git a/private/rules/v3_lock_file.bzl b/private/rules/v3_lock_file.bzl index 43b43694d..43f605a3c 100644 --- a/private/rules/v3_lock_file.bzl +++ b/private/rules/v3_lock_file.bzl @@ -151,10 +151,12 @@ def _compute_lock_file_hash_v3(lock_file_contents): for repo, artifacts in lock_file_contents["repositories"].items(): for artifact in artifacts: - all_infos[artifact]["repository"] = repo + if artifact in all_infos: + all_infos[artifact]["repository"] = repo for dep, dep_info in lock_file_contents["dependencies"].items(): - all_infos[dep]["dependencies"] = sorted(dep_info) + if dep in all_infos: + all_infos[dep]["dependencies"] = sorted(dep_info) return _compute_final_hash(all_infos) diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/cmd/AbstractMain.java b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/cmd/AbstractMain.java index d33cacd7b..6bd7cd663 100644 --- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/cmd/AbstractMain.java +++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/cmd/AbstractMain.java @@ -345,14 +345,20 @@ public static Map calculateArtifactHash(Map ren for (Map.Entry> repo : repositories.entrySet()) { Iterable repoArtifacts = repo.getValue(); for (String art : repoArtifacts) { - allInfos.get(art).put("repository", repo.getKey()); + Map info = allInfos.get(art); + if (info != null) { + info.put("repository", repo.getKey()); + } } } Map> dependencies = sortMapRecursively((Map) rendered.get("dependencies")); for (Map.Entry> dep : dependencies.entrySet()) { - allInfos.get(dep.getKey()).put("dependencies", dep.getValue()); + Map info = allInfos.get(dep.getKey()); + if (info != null) { + info.put("dependencies", dep.getValue()); + } } Map finalHash = new TreeMap<>(); diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/lockfile/V3LockFileTest.java b/tests/com/github/bazelbuild/rules_jvm_external/resolver/lockfile/V3LockFileTest.java index 0dd390dc7..31fa6ca8d 100644 --- a/tests/com/github/bazelbuild/rules_jvm_external/resolver/lockfile/V3LockFileTest.java +++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/lockfile/V3LockFileTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import com.github.bazelbuild.rules_jvm_external.Coordinates; import com.github.bazelbuild.rules_jvm_external.resolver.Conflict; @@ -252,6 +253,68 @@ public void testCalculateArtifactHashMatchesStoredHash() throws IOException { } } + @Test + @SuppressWarnings("unchecked") + public void calculateArtifactHashShouldHandleSkippedArtifacts() { + Coordinates mainCoords = new Coordinates("com.example:item:1.0.0"); + Coordinates depCoords = new Coordinates("com.example:dep:1.0.0"); + Coordinates sourcesCoords = mainCoords.setClassifier("sources"); + String sourcesKey = sourcesCoords.asKey(); + + DependencyInfo dep = + new DependencyInfo( + depCoords, + repos, + Optional.empty(), + Optional.of("deadbeef"), + Set.of(), + Set.of(), + Set.of(), + new TreeMap<>()); + + DependencyInfo mainJar = + new DependencyInfo( + mainCoords, + repos, + Optional.empty(), + Optional.of("cafebabe"), + Set.of(depCoords), + Set.of(), + Set.of(), + new TreeMap<>()); + + DependencyInfo skippedSources = + new DependencyInfo( + sourcesCoords, + repos, + Optional.empty(), + Optional.empty(), + Set.of(depCoords), + Set.of(), + Set.of(), + new TreeMap<>()); + + Map rendered = + new V3LockFile(repos, Set.of(mainJar, dep, skippedSources), Set.of(), true).render(); + + Set skipped = (Set) rendered.get("skipped"); + assertTrue("sources artifact should be skipped", skipped.contains(sourcesKey)); + + Map> renderedRepos = + (Map>) rendered.get("repositories"); + boolean foundInRepos = + renderedRepos.values().stream().anyMatch(arts -> arts.contains(sourcesKey)); + assertTrue("skipped artifact should still appear in repositories", foundInRepos); + + Map> renderedDeps = + (Map>) rendered.get("dependencies"); + assertTrue( + "skipped artifact should still appear in dependencies", + renderedDeps.containsKey(sourcesKey)); + + AbstractMain.calculateArtifactHash(rendered); + } + private V3LockFile roundTrip(V3LockFile lockFile) { Map rendered = lockFile.render(); String converted =