Skip to content

cargo-bazel: fix hub alias for workspace-member deps with build scripts#3974

Open
lamcw wants to merge 6 commits intobazelbuild:mainfrom
lamcw:hub-alias-for-workspace-deps
Open

cargo-bazel: fix hub alias for workspace-member deps with build scripts#3974
lamcw wants to merge 6 commits intobazelbuild:mainfrom
lamcw:hub-alias-for-workspace-deps

Conversation

@lamcw
Copy link
Copy Markdown

@lamcw lamcw commented Apr 17, 2026

Problem

When workspace member A depends on workspace member B, cargo-bazel emits hub alias() targets pointing to @{index}__B-<ver>//:B. However, extensions.bzl never creates spoke repos for workspace members (repository == null, skipped at crate_universe/extensions.bzl:722-724), so these aliases are dangling and cause "no such package" errors during analysis.

Solution

In render_hub_build_file, before calling crate_label(), check whether the dep is itself a workspace member (is_workspace_member).

  • Workspace member dep — library alias: iterate krate.targets with find_map/override_target_key() to look up override_targets[key]. If an override is present, use it as the alias actual; if absent, skip the alias entirely and emit a tracing::warn! directing the user to set override_target_lib or override_target_proc_macro in MODULE.bazel. Using override_target_key() (rather than hardcoding "lib") correctly handles both Rule::Library → "lib" and Rule::ProcMacro → "proc-macro" targets.
  • Workspace member dep — extra_aliased_targets: skip all extra aliases for workspace-member deps (they require a spoke repo) and emit a single tracing::warn! per dep.
  • External dep: behavior is unchanged — crate_label() is called as before.

Callers set override_targets via crate.annotation(override_target_lib = ...) or crate.annotation(override_target_proc_macro = ...) in MODULE.bazel.

Tests

  • hub_alias_for_workspace_member_dep_with_build_script_uses_override_target: verifies the hub alias points to the override label (not a spoke-repo label) for a workspace-member dep with a build script.
  • hub_alias_for_workspace_member_proc_macro_dep_uses_override_target: verifies the same for a Rule::ProcMacro dep, exercising the override_target_key() path.
  • hub_alias_omitted_for_workspace_member_dep_with_no_override: verifies no alias() rule is emitted when no override is set.
  • workspace_member_dep_with_alias_same_as_crate_name_and_no_override: verifies that a workspace-member dep aliased under its own crate name with no override emits no hub alias at all.
  • extra_aliased_targets_omitted_for_workspace_member_dep: verifies extra_aliased_targets aliases are suppressed for workspace-member deps.
  • extra_aliased_targets_emitted_for_external_dep: verifies extra_aliased_targets aliases are still emitted normally for external deps.
  • external_dep_with_rename_same_as_crate_name: verifies that for a non-workspace-member dep aliased under its own crate name, the rename alias is suppressed (deduplication guard) while the primary versioned and shorthand aliases are still emitted exactly once.

lamcw added 4 commits April 17, 2026 10:23
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-<ver>//: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.
Signed-off-by: Thomas Lam <thomaslam@canva.com>
Signed-off-by: Thomas Lam <thomaslam@canva.com>
- Update logic to suppress rename aliases for external dependencies that match the crate's name.
- Add tests to ensure primary and shorthand aliases are emitted correctly while preventing duplicates.

Signed-off-by: Thomas Lam <thomaslam@canva.com>
@lamcw lamcw marked this pull request as ready for review April 17, 2026 04:11
@lamcw
Copy link
Copy Markdown
Author

lamcw commented Apr 17, 2026

The failing CI check looks like a flake to me? https://buildkite.com/bazel/rules-rust-rustlang/builds/16962#019d9981-e5a4-4085-ba0e-d4051d6bd13f I cannot retry the CI job though (potentially missing permissions?) -- can you please advise how I can proceed?

lamcw added 2 commits April 17, 2026 16:16
Signed-off-by: Thomas Lam <thomaslam@canva.com>
…encies and add tests for external dependencies

Signed-off-by: Thomas Lam <thomaslam@canva.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant