From c54a500fa5b4a84c71e90911c87d187bd546791b Mon Sep 17 00:00:00 2001 From: Thomas Lam Date: Fri, 17 Apr 2026 12:21:28 +1000 Subject: [PATCH 1/7] cargo-bazel: fix hub alias for workspace-member deps with build scripts Problem: When workspace member A depends on workspace member B (where B has both a library target and a build script), cargo-bazel emits hub aliases pointing to @crate_index__B-//:B. However, extensions.bzl never creates spoke repos for workspace members (repository == null), so these aliases are dangling and cause "no such package" errors during analysis. Solution: In render_module_build_file, detect when a dep is itself a workspace member (context.workspace_members.contains_key(&dep.id)) before calling crate_label(). If it is a workspace member, look up override_targets["lib"] and use that label instead; if no override is set, skip the alias entirely rather than emitting a dangling reference. Callers set override_targets["lib"] via the crate.annotation( override_target_lib = ...) mechanism in MODULE.bazel, which records the hand-written workspace target to redirect to. Testing: - hub_alias_for_workspace_member_dep_with_build_script_uses_override_target: verifies that the hub alias points to the override label, not a spoke repo. - hub_alias_omitted_for_workspace_member_dep_with_no_override: verifies that no alias is emitted when override_targets["lib"] is absent. --- crate_universe/src/rendering.rs | 281 ++++++++++++++++++++++++++------ 1 file changed, 231 insertions(+), 50 deletions(-) diff --git a/crate_universe/src/rendering.rs b/crate_universe/src/rendering.rs index be6bcf4da0..99f698f692 100644 --- a/crate_universe/src/rendering.rs +++ b/crate_universe/src/rendering.rs @@ -210,65 +210,71 @@ impl Renderer { .unwrap_or(&self.config.default_alias_rule); if let Some(library_target_name) = &krate.library_target_name { - // Avoid adding the - alias if there are - // more than 1 dependency referencing the same crate at the - // same version, but one of them is aliased. - // - // Without this check we would add duplicate aliases in - // scenarios like the following: - // - // itertools = "0.11.24" - // itertools_other = { version = "0.11.24", package = "itertools" } - // - let add_primary_alias = dep.alias.is_none() - || !context.has_duplicate_workspace_member_dep_by_version(&dep); - - if add_primary_alias { - dependencies.push(Alias { - rule: alias_rule.rule(), - name: format!("{}-{}", krate.name, krate.version), - actual: self.crate_label( + // Workspace-member deps have no spoke repo + // (@{index}__-) — extensions.bzl skips spoke + // creation for all workspace members (repository == null). + // Use override_targets["lib"] when set; skip otherwise to + // avoid emitting dangling alias targets. + let maybe_actual: Option