diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/ModuleGraphParser.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/ModuleGraphParser.kt index 20dee6c..ac13860 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/ModuleGraphParser.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/ModuleGraphParser.kt @@ -69,6 +69,107 @@ class ModuleGraphParser { } } + /** + * Result of parsing the bzlmod dependency graph as edges keyed by `apparentName`. + * + * @property edges Map from a module's `apparentName` to the set of `apparentName`s of its direct + * bzlmod dependencies. Populated for every module reached when walking the JSON tree. + * @property rootApparentNames `apparentName`s for the root module(s) (key ``). The root is + * the main repo and is always queried via `//...:all-targets`, so dependents-expansion should + * never add it to a fine-grained set. + */ + data class GraphEdges( + val edges: Map>, + val rootApparentNames: Set, + ) + + /** + * Parses `bazel mod graph --output=json` into apparent-name dependency edges. Tolerates a + * non-JSON prefix (e.g. leaked stderr) using the same recovery as [parseModuleGraph]. + * + * Each module in the JSON tree contributes an edge for every entry in its `dependencies` array. + * `unexpanded` dependency stubs (modules that the bzlmod resolver already described elsewhere + * in the graph) still contribute the edge but are not recursed into to avoid duplicate work. + */ + fun parseModuleGraphEdges(json: String): GraphEdges { + val edges = mutableMapOf>() + val rootApparentNames = mutableSetOf() + try { + val root = + try { + JsonParser.parseString(json).asJsonObject + } catch (_: Exception) { + val start = json.indexOf('{') + if (start < 0) return GraphEdges(emptyMap(), emptySet()) + JsonParser.parseString(json.substring(start)).asJsonObject + } + walkEdges(root, edges, rootApparentNames, isRoot = true) + } catch (_: Exception) { + return GraphEdges(emptyMap(), emptySet()) + } + return GraphEdges(edges.mapValues { it.value.toSet() }, rootApparentNames.toSet()) + } + + private fun walkEdges( + obj: JsonObject, + edges: MutableMap>, + rootApparentNames: MutableSet, + isRoot: Boolean, + ) { + val apparentName = obj.get("apparentName")?.asString ?: return + if (isRoot) rootApparentNames.add(apparentName) + val mySet = edges.getOrPut(apparentName) { mutableSetOf() } + val deps = obj.get("dependencies")?.asJsonArray ?: return + for (dep in deps) { + if (!dep.isJsonObject) continue + val depObj = dep.asJsonObject + val depApparent = depObj.get("apparentName")?.asString ?: continue + mySet.add(depApparent) + val unexpanded = depObj.get("unexpanded")?.asBoolean ?: false + if (!unexpanded) { + walkEdges(depObj, edges, rootApparentNames, isRoot = false) + } + } + } + + /** + * Computes the set of `apparentName`s that transitively depend on any module in [targets] by + * traversing [edges] in reverse. Excludes [rootApparentNames] from the result. + * + * Background: `--fineGrainedHashExternalRepos` opts a leaf module (e.g. `@inner_repo`) into + * per-target hashing. When another bzlmod module (`@middle_repo`) wraps it via alias or + * re-export and the main repo depends only on the wrapper, the wrapper's targets must also be + * queried for the hash chain to reach the leaf. This is the engine for that auto-expansion + * (issue #197). The set returned here is what the caller should add to the user-supplied set. + */ + fun findTransitiveDependents( + edges: Map>, + targets: Set, + rootApparentNames: Set, + ): Set { + if (edges.isEmpty() || targets.isEmpty()) return emptySet() + val reverse = mutableMapOf>() + for ((from, deps) in edges) { + for (dep in deps) { + reverse.getOrPut(dep) { mutableSetOf() }.add(from) + } + } + val out = mutableSetOf() + val visited = targets.toMutableSet() + val queue: ArrayDeque = ArrayDeque(targets) + while (queue.isNotEmpty()) { + val cur = queue.removeFirst() + val parents = reverse[cur] ?: continue + for (p in parents) { + if (p in visited) continue + visited.add(p) + if (p !in rootApparentNames) out.add(p) + queue.addLast(p) + } + } + return out + } + /** * Compares two module graphs and returns the keys of modules that changed. * diff --git a/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt b/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt index 4c41399..8beae91 100644 --- a/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt +++ b/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt @@ -3,6 +3,7 @@ package com.bazel_diff.di import com.bazel_diff.bazel.BazelClient import com.bazel_diff.bazel.BazelModService import com.bazel_diff.bazel.BazelQueryService +import com.bazel_diff.bazel.ModuleGraphParser import com.bazel_diff.hash.* import com.bazel_diff.io.ContentHashProvider import com.bazel_diff.log.Logger @@ -40,11 +41,26 @@ fun hasherModule( "Error: fineGrainedHashExternalReposFile and fineGrainedHashExternalRepos are mutually exclusive - please provide only one of them") System.exit(1) } - val updatedFineGrainedHashExternalRepos = + val userSuppliedFineGrainedHashExternalRepos = fineGrainedHashExternalReposFile?.let { file -> file.readLines().filter { it.isNotBlank() }.toSet() } ?: fineGrainedHashExternalRepos + // Auto-expand the user-supplied fine-grained set with any bzlmod module that transitively + // wraps one of those repos (issue #197). Without this, a main-repo target consuming + // `@middle_repo//:wrapped` -- itself an alias for `@inner_repo//:all_files` -- collapses + // `@middle_repo` into an opaque `//external:middle_repo` blob, so source changes inside + // `@inner_repo` never reach the main consumer. Adding the wrapper to the fine-grained set + // keeps `@middle_repo//:wrapped` as a real ruleInput whose `actual` attribute carries the + // chain down to the leaf. + val updatedFineGrainedHashExternalRepos = + expandFineGrainedHashExternalReposWithBzlmodDependents( + userSuppliedFineGrainedHashExternalRepos, + workingDirectory, + bazelPath, + startupOptions, + ) + val cmd: MutableList = ArrayList().apply { add(bazelPath.toString()) @@ -87,6 +103,65 @@ fun hasherModule( single { ContentHashProvider(contentHashPath) } } +/** + * Returns [userSupplied] together with every bzlmod module that transitively depends on a repo in + * [userSupplied]. Each entry is the apparent-name form prefixed with `@`, matching the format + * consumed by [BazelClient]/[com.bazel_diff.bazel.BazelRule] and the user-facing CLI flag. + * + * If `bazel mod graph --output=json` fails (e.g. bzlmod disabled) or the user supplied nothing, + * this is a no-op and returns [userSupplied] unchanged. This intentionally degrades gracefully + * for WORKSPACE-only setups where the bzlmod graph is unavailable -- the wrapped-repo bug + * (issue #197) is bzlmod-specific anyway. + */ +@OptIn(ExperimentalCoroutinesApi::class) +private fun expandFineGrainedHashExternalReposWithBzlmodDependents( + userSupplied: Set, + workingDirectory: Path, + bazelPath: Path, + startupOptions: List, +): Set { + if (userSupplied.isEmpty()) return userSupplied + + val cmd = + mutableListOf().apply { + add(bazelPath.toString()) + addAll(startupOptions) + add("mod") + add("graph") + add("--output=json") + } + val result = + runBlocking { + process( + *cmd.toTypedArray(), + stdout = Redirect.CAPTURE, + stderr = Redirect.SILENT, + workingDirectory = workingDirectory.toFile(), + destroyForcibly = true, + ) + } + if (result.resultCode != 0) return userSupplied + val json = result.output.joinToString("\n").trim() + if (json.isEmpty()) return userSupplied + + val parser = ModuleGraphParser() + val graph = parser.parseModuleGraphEdges(json) + if (graph.edges.isEmpty()) return userSupplied + + // The user-supplied set uses the `@apparentName` form; strip leading `@`/`@@` to match the + // apparent names emitted by `bazel mod graph`. + val apparentTargets = + userSupplied + .map { it.removePrefix("@@").removePrefix("@") } + .filter { it.isNotEmpty() } + .toSet() + val dependents = + parser.findTransitiveDependents(graph.edges, apparentTargets, graph.rootApparentNames) + if (dependents.isEmpty()) return userSupplied + + return userSupplied + dependents.map { "@$it" } +} + fun loggingModule(verbose: Boolean) = module { single { StderrLogger(verbose) } } fun serialisationModule() = module { diff --git a/cli/src/test/kotlin/com/bazel_diff/bazel/ModuleGraphParserTest.kt b/cli/src/test/kotlin/com/bazel_diff/bazel/ModuleGraphParserTest.kt index 192847b..ac1d849 100644 --- a/cli/src/test/kotlin/com/bazel_diff/bazel/ModuleGraphParserTest.kt +++ b/cli/src/test/kotlin/com/bazel_diff/bazel/ModuleGraphParserTest.kt @@ -274,6 +274,128 @@ class ModuleGraphParserTest { assertThat(result).containsExactlyInAnyOrder("root", "abseil-cpp@20240116.2") } + // Edge / transitive-dependents tests are regression coverage for issue #197: when + // `@inner_repo` is the user-listed fine-grained repo and `@middle_repo` wraps it, the + // expansion has to follow `bazel mod graph` backwards to add `@middle_repo` automatically. + + @Test + fun parseModuleGraphEdges_realIssue197Shape_extractsEdgesAndRoot() { + // Mirrors `bazel mod graph --output=json` for the `wrapped_external_repo` fixture: + // -> inner_repo, middle_repo; middle_repo -> inner_repo (unexpanded reference). + val json = + """ + { + "key": "", + "name": "wrapped_external_repo_test", + "version": "0.0.0", + "apparentName": "wrapped_external_repo_test", + "dependencies": [ + { + "key": "inner_repo@_", + "name": "inner_repo", + "version": "0.0.0", + "apparentName": "inner_repo", + "dependencies": [] + }, + { + "key": "middle_repo@_", + "name": "middle_repo", + "version": "0.0.0", + "apparentName": "middle_repo", + "dependencies": [ + { + "key": "inner_repo@_", + "name": "inner_repo", + "version": "0.0.0", + "apparentName": "inner_repo", + "unexpanded": true + } + ] + } + ] + } + """ + .trimIndent() + + val graph = parser.parseModuleGraphEdges(json) + + assertThat(graph.rootApparentNames).containsExactlyInAnyOrder("wrapped_external_repo_test") + assertThat(graph.edges["wrapped_external_repo_test"]) + .isNotNull() + .containsExactlyInAnyOrder("inner_repo", "middle_repo") + assertThat(graph.edges["middle_repo"]) + .isNotNull() + .containsExactlyInAnyOrder("inner_repo") + // inner_repo has no outgoing deps. + assertThat(graph.edges["inner_repo"]).isNotNull().isEmpty() + } + + @Test + fun findTransitiveDependents_issue197_addsMiddleRepoButNotRoot() { + // Same shape as parseModuleGraphEdges_realIssue197Shape: wraps both, middle_repo wraps + // inner_repo. Listing `inner_repo` as a target must surface `middle_repo` (so wrapper-only + // consumers in the main repo get correctly invalidated) and must NOT surface the root + // (the root is the main repo, already queried via `//...:all-targets`). + val edges = + mapOf( + "wrapped_external_repo_test" to setOf("inner_repo", "middle_repo"), + "middle_repo" to setOf("inner_repo"), + "inner_repo" to emptySet(), + ) + + val result = + parser.findTransitiveDependents( + edges, + targets = setOf("inner_repo"), + rootApparentNames = setOf("wrapped_external_repo_test")) + + assertThat(result).containsExactlyInAnyOrder("middle_repo") + } + + @Test + fun findTransitiveDependents_multiLevelWrapping_followsChain() { + // inner -> middle -> outer -> root. Listing inner must add both middle and outer. + val edges = + mapOf( + "root_app" to setOf("outer"), + "outer" to setOf("middle"), + "middle" to setOf("inner"), + "inner" to emptySet(), + ) + + val result = + parser.findTransitiveDependents( + edges, targets = setOf("inner"), rootApparentNames = setOf("root_app")) + + assertThat(result).containsExactlyInAnyOrder("middle", "outer") + } + + @Test + fun findTransitiveDependents_unrelatedRepos_returnsEmpty() { + // A repo with no chain to the targets should not be expanded into. + val edges = + mapOf( + "root_app" to setOf("inner", "unrelated"), + "inner" to emptySet(), + "unrelated" to emptySet(), + ) + + val result = + parser.findTransitiveDependents( + edges, targets = setOf("inner"), rootApparentNames = setOf("root_app")) + + assertThat(result).isEmpty() + } + + @Test + fun findTransitiveDependents_emptyTargets_returnsEmpty() { + val edges = mapOf("a" to setOf("b"), "b" to emptySet()) + + val result = parser.findTransitiveDependents(edges, targets = emptySet(), rootApparentNames = emptySet()) + + assertThat(result).isEmpty() + } + @Test fun findChangedModules_withNewGraphEmpty_returnsAllOldModuleKeys() { val oldGraph = diff --git a/cli/src/test/kotlin/com/bazel_diff/e2e/E2ETest.kt b/cli/src/test/kotlin/com/bazel_diff/e2e/E2ETest.kt index da24e12..0ece4bc 100644 --- a/cli/src/test/kotlin/com/bazel_diff/e2e/E2ETest.kt +++ b/cli/src/test/kotlin/com/bazel_diff/e2e/E2ETest.kt @@ -1701,6 +1701,83 @@ class E2ETest { .isEqualTo("//external:com_github_pkg_errors") } + // ------------------------------------------------------------------------ + // Regression coverage for https://github.com/Tinder/bazel-diff/issues/197 + // ------------------------------------------------------------------------ + // The simple case (a main-repo target consuming a file from a single external repo) already + // worked before this fix. The unfixed shape was the one @Ahajha called out in + // https://github.com/Tinder/bazel-diff/issues/197#issuecomment-2616103349: a target inside + // one external repo is re-wrapped by ANOTHER external repo, and the main repo consumes only + // the wrapping repo. When the inner repo's source file changed, the main-repo consumer was + // not reported as impacted unless the user manually enumerated every wrapping external repo + // in --fineGrainedHashExternalRepos. + // + // The `wrapped_external_repo` fixture wires this up with bzlmod: + // inner_repo -> filegroup wrapping data.txt + // middle_repo -> alias re-exporting @inner_repo//:all_files + // //:consumer -> genrule consuming @middle_repo//:wrapped + // + // The fix in `Modules.kt` auto-expands the fine-grained set with bzlmod modules that + // transitively depend on a user-listed repo, by walking `bazel mod graph --output=json`. + // Listing only `@inner_repo` is now enough: `@middle_repo` is added automatically, its + // alias target is queried as a real rule, and its `actual` attribute carries the dep + // chain down to `@inner_repo//:data.txt`. + @Test + fun testWrappedExternalRepoFileChangeImpactsMainConsumer_regressionForIssue197() { + val workspaceA = copyTestWorkspace("wrapped_external_repo") + val workspaceB = copyTestWorkspace("wrapped_external_repo") + + // Mutate only inner_repo/data.txt in B -- this is the source of truth. + val innerDataInB = File(workspaceB, "inner_repo/data.txt") + innerDataInB.writeText("version two\n") + + val outputDir = temp.newFolder() + val from = File(outputDir, "starting_hashes.json") + val to = File(outputDir, "final_hashes.json") + val impactedTargetsOutput = File(outputDir, "impacted_targets.txt") + + val cli = CommandLine(BazelDiff()) + + // Only enumerate the source-of-truth repo. middle_repo is a transitive wrapper that + // users don't expect to have to manually call out (they may not even know about it). + val fineGrained = "@inner_repo" + + assertThat( + cli.execute( + "generate-hashes", + "-w", workspaceA.absolutePath, + "-b", "bazel", + "--fineGrainedHashExternalRepos", fineGrained, + from.absolutePath)) + .isEqualTo(0) + assertThat( + cli.execute( + "generate-hashes", + "-w", workspaceB.absolutePath, + "-b", "bazel", + "--fineGrainedHashExternalRepos", fineGrained, + to.absolutePath)) + .isEqualTo(0) + assertThat( + cli.execute( + "get-impacted-targets", + "-w", workspaceB.absolutePath, + "-b", "bazel", + "-sh", from.absolutePath, + "-fh", to.absolutePath, + "-o", impactedTargetsOutput.absolutePath)) + .isEqualTo(0) + + val impacted = impactedTargetsOutput.readLines().filter { it.isNotBlank() }.toSet() + // Desired: //:consumer follows the dep chain through @middle_repo:wrapped -> @inner_repo:all_files + // -> data.txt and shows up as impacted. Current behaviour: only @inner_repo:* targets are + // impacted; the chain stops at the unhashed @middle_repo "blob". + val consumerImpacted = impacted.any { it == "//:consumer" || it == "@@//:consumer" } + assertThat(consumerImpacted) + .transform("//:consumer should be impacted (chain: inner_repo/data.txt -> @inner_repo:all_files -> @middle_repo:wrapped -> //:consumer). Got impacted: $impacted") { it } + .isEqualTo(true) + } + private fun copyTestWorkspace(path: String): File { val testProject = temp.newFolder() diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/.bazelignore b/cli/src/test/resources/workspaces/wrapped_external_repo/.bazelignore new file mode 100644 index 0000000..c0b71b9 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/.bazelignore @@ -0,0 +1,2 @@ +inner_repo +middle_repo diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/BUILD b/cli/src/test/resources/workspaces/wrapped_external_repo/BUILD new file mode 100644 index 0000000..f565cd8 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/BUILD @@ -0,0 +1,17 @@ +# Reproducer workspace for https://github.com/Tinder/bazel-diff/issues/197. +# +# Shape: +# inner_repo --> filegroup wrapping data.txt +# middle_repo --> alias re-exporting @inner_repo//:all_files +# //:consumer --> depends on @middle_repo//:wrapped (not directly on inner_repo) +# +# When inner_repo/data.txt changes, //:consumer should be reported as impacted, +# even if --fineGrainedHashExternalRepos only mentions @inner_repo (i.e. users +# do not have to enumerate every wrapping repo). @Ahajha's comment in #197 calls +# this out as the still-broken case after PR #322. +genrule( + name = "consumer", + srcs = ["@middle_repo//:wrapped"], + outs = ["consumer.out"], + cmd = "cat $(SRCS) > $@", +) diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel b/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel new file mode 100644 index 0000000..6a55baa --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel @@ -0,0 +1,16 @@ +module( + name = "wrapped_external_repo_test", + version = "0.0.0", +) + +bazel_dep(name = "inner_repo", version = "0.0.0") +local_path_override( + module_name = "inner_repo", + path = "inner_repo", +) + +bazel_dep(name = "middle_repo", version = "0.0.0") +local_path_override( + module_name = "middle_repo", + path = "middle_repo", +) diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel.lock b/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel.lock new file mode 100644 index 0000000..23f8dcf --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/MODULE.bazel.lock @@ -0,0 +1,192 @@ +{ + "lockFileVersion": 26, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.1.0/source.json": "da589573c1dee2c9ac4a568b301269a2e8191110ff0345c1a959fa7ea6c4dfd6", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": {}, + "facts": {} +} diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/WORKSPACE b/cli/src/test/resources/workspaces/wrapped_external_repo/WORKSPACE new file mode 100644 index 0000000..c16fe45 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/WORKSPACE @@ -0,0 +1 @@ +workspace(name = "wrapped_external_repo_test") diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/BUILD b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/BUILD new file mode 100644 index 0000000..10d51bd --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/BUILD @@ -0,0 +1,5 @@ +filegroup( + name = "all_files", + srcs = ["data.txt"], + visibility = ["//visibility:public"], +) diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/MODULE.bazel b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/MODULE.bazel new file mode 100644 index 0000000..cbea717 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/MODULE.bazel @@ -0,0 +1,4 @@ +module( + name = "inner_repo", + version = "0.0.0", +) diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/WORKSPACE b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/WORKSPACE new file mode 100644 index 0000000..ea8acfd --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/WORKSPACE @@ -0,0 +1 @@ +workspace(name = "inner_repo") diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/data.txt b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/data.txt new file mode 100644 index 0000000..9bc69cf --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/inner_repo/data.txt @@ -0,0 +1 @@ +version one diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/BUILD b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/BUILD new file mode 100644 index 0000000..ec27647 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/BUILD @@ -0,0 +1,5 @@ +alias( + name = "wrapped", + actual = "@inner_repo//:all_files", + visibility = ["//visibility:public"], +) diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/MODULE.bazel b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/MODULE.bazel new file mode 100644 index 0000000..b91ed16 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/MODULE.bazel @@ -0,0 +1,6 @@ +module( + name = "middle_repo", + version = "0.0.0", +) + +bazel_dep(name = "inner_repo", version = "0.0.0") diff --git a/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/WORKSPACE b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/WORKSPACE new file mode 100644 index 0000000..75c3272 --- /dev/null +++ b/cli/src/test/resources/workspaces/wrapped_external_repo/middle_repo/WORKSPACE @@ -0,0 +1 @@ +workspace(name = "middle_repo")