Repository navigation
Fix #603: a label-only extension's owner no longer stands in for its repositories - #608
Merged
tinder-maxwellelliott merged 3 commits intoNov 3, 2026
Conversation
…ing on the owner Adds the extension_owner_dependent_module fixture: module `ext` owns an extension generating a hub and spokes, and module `dependent` only has a bazel_dep on `ext`. With the extension listed in --labelOnlyModuleExtensions, bumping one spoke still impacts //:uses_dependent, a target that uses a rule of `dependent` and names nothing the extension generates, because //external:dependent depends on the full //external:ext node. The test also pins that a change to `ext` itself must keep reaching `dependent`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fine-graining Per the reporter's feedback on #603, the fixture now also covers the npm half of the issue: - //:uses_ext uses `ext`'s own rule directly (like a js_binary using rules_js), with no dependent module on the path. - Spokes are named after their version (like npm__user-agents__2.1.229), so a bump replaces a spoke instead of changing it in place. - `dependent` reaches `ext` through `middle`, two module hops. - The main check runs without --fineGrainedHashExternalRepos, the reporter's configuration; a second run fine-grains only the @crates hub (a versioned spoke can't be named in a flag shared by both revisions, since Bazel rejects an undefined repository in the query). Today, with the extension listed in --labelOnlyModuleExtensions, the bump impacts //:uses_ext and //:uses_dependent in both configurations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…repositories In query mode the module that owns an extension depends on every repository the extension generates. #559 gave targets inside a listed extension's repositories a view of the owner without them, but every other reader still reached the full owner node: a target using the owner's own rule (a js_binary on rules_js) and every module with a bazel_dep path to the owner (rules_jest -> ... -> gazelle). One go.mod or pnpm-lock.yaml bump then impacted most of the workspace. For an extension listed in --labelOnlyModuleExtensions the owner now gets no stand-in edges at all, the same way --isolatedDependencyRoot members already don't. The flag's assertion becomes "used only through labels, never by resolving a toolchain from one of them", which go_deps/npm/crate repositories satisfy. With the owner node itself reduced, the per-extension %view nodes and their per-rule lookup in hash.rs are redundant and are removed. Hub-to-spoke edges stay. Users of the flag see a one-time hash shift on the owner's node and its dependents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tinder-maxwellelliott
deleted the
maxwelle/bazel-diff-603-reproducer-ce8875
branch
November 3, 2026 15:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #603
Reproducer and fix for #603: with an extension listed in
--labelOnlyModuleExtensions, a single lockfile bump (go.modvia gazelle'sgo_deps,pnpm-lock.yamlvia rules_js'snpm) still impacted every target that uses the owning module's rules and every target of every module with abazel_deppath to the owner.Fix
In query mode
lower_repositories(src/bazel.rs) makes the module that owns an extension depend on every repository the extension generates, because a toolchain resolved from one of them isn't a query input. #559 added a%-view of the owner without a listed extension's repositories, but only targets inside those repositories used it; a root target naming@ext//and//external:dependentstill reached the full owner node.Now, for a listed extension, the owner gets no stand-in edges at all, the same way
--isolatedDependencyRootmembers (owner_exemptions) already don't. With the owner node itself reduced, the per-extension view nodes and their per-rule repository lookup inhash.rsare redundant, so they're removed (net −43 lines). The hub-to-spoke edges stay.Contract change: the flag used to assert "the repositories use each other only through labels". It now asserts they are used only through labels, never by resolving a toolchain from one of them.
go_deps,npmandcraterepositories satisfy that; a toolchain-generating extension likerules_go'sgo_sdkmust not be listed. The README (template + regenerated) and the--helptext are updated accordingly.Hash shift: for users of the flag, the owner's node and everything depending on it hash differently once. No change without the flag, and no change in cquery mode (which never had the stand-in edges).
Reproducer
Extended after the reporter's feedback (comment). Fixture
tests/resources/workspaces/extension_owner_dependent_module/:extowns an extension generating a hub@cratesand version-named spokes (crates__b__1_0→crates__b__2_0, likenpm__user-agents__2.1.229).//:uses_extusesext's own rule directly (the npm half).//:uses_dependentuses a rule ofdependent, which reachesextthroughmiddle(twobazel_dephops, the Go half).//:uses_a///:uses_bconsume the hub.external::label_only_extension_bump_does_not_reach_users_of_the_owner_or_its_dependents, bumpingb:uses_ext,uses_dependentimpacted--labelOnlyModuleExtensions(no fine-graining, reporter's setup){uses_a, uses_b}uses_dependent,uses_ext--fineGrainedHashExternalRepos=@crates{uses_b}uses_dependent,uses_extext/tool.sh, both configsuses_ext,uses_dependentimpactedThe last row keeps the owner's own tree reaching its rule users and dependent modules. The fine-grained run names only the hub, since Bazel rejects a repository that doesn't exist at one of the revisions.
Testing
//src:rust_tests,//src:cli_tests: pass. The twolower_repositoriesunit tests are updated: the views test now pins only apparent names, and the owner-edges test checks both the default stand-in edges and the reduced owner for listed extensions.bzlmod_transitive_deps_cquery, twocquery_*_platforms,fine_grained_workspace_external_repo) fail only because this machine has no JDK (rules_javalocal_jdk/ coursier); CI covers them.cargo clippy --all-targets -D warnings: clean.regen_check: pass.🤖 Generated with Claude Code