Add support for override_target when using bzlmod (#2683)
The ability to override crate targets when using crate_universe was
added here: https://github.com/bazelbuild/rules_rust/pull/2674
However, this change did not expose that functionality when using
bzlmod.
This change adds that functionality in. Because of the limited set of
options we have for dictionaries in tag classes, I had to split out
"override_targets" into four different options, each taking a Label.
I have added in an example based on the example given in #2674 , but
using bzlmod instead. I have also tested that example and found it to be
working.
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 6ade36b..7642ff7 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -717,6 +717,14 @@
working_directory: examples/bzlmod/hello_world_no_cargo
build_targets:
- "//..."
+ bzlmod_override_targets:
+ name: Override Targets bzlmod
+ platform: ubuntu2004
+ working_directory: examples/bzlmod/override_target
+ build_targets:
+ - "//..."
+ test_targets:
+ - "//..."
compile_one_dependency:
name: --compile_one_dependency flag
platform: ubuntu2004
diff --git a/crate_universe/extension.bzl b/crate_universe/extension.bzl
index d181309..509401d 100644
--- a/crate_universe/extension.bzl
+++ b/crate_universe/extension.bzl
@@ -296,6 +296,31 @@
if annotation_dict.pop("gen_all_binaries"):
annotation_dict["gen_binaries"] = True
annotation_dict["gen_build_script"] = _OPT_BOOL_VALUES[annotation_dict["gen_build_script"]]
+
+ # Process the override targets for the annotation.
+ # In the non-bzlmod approach, this is given as a dict
+ # with the possible keys "`proc_macro`, `build_script`, `lib`, `bin`".
+ # With the tag-based approach used in Bzlmod, we run into an issue
+ # where there is no dict type that takes a string as a key and a Label as the value.
+ # To work around this, we split the override option into four, and reconstruct the
+ # dictionary here during processing
+ annotation_dict["override_targets"] = dict()
+ replacement = annotation_dict.pop("override_target_lib")
+ if replacement:
+ annotation_dict["override_targets"]["lib"] = str(replacement)
+
+ replacement = annotation_dict.pop("override_target_proc_macro")
+ if replacement:
+ annotation_dict["override_targets"]["proc_macro"] = str(replacement)
+
+ replacement = annotation_dict.pop("override_target_build_script")
+ if replacement:
+ annotation_dict["override_targets"]["build_script"] = str(replacement)
+
+ replacement = annotation_dict.pop("override_target_bin")
+ if replacement:
+ annotation_dict["override_targets"]["bin"] = str(replacement)
+
annotation = _crate_universe_crate.annotation(**{
k: v
for k, v in annotation_dict.items()
@@ -483,6 +508,18 @@
shallow_since = attr.string(
doc = "An optional timestamp used for crates originating from a git repository instead of a crate registry. This flag optimizes fetching the source code.",
),
+ override_target_lib = attr.label(
+ doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.",
+ ),
+ override_target_proc_macro = attr.label(
+ doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.",
+ ),
+ override_target_build_script = attr.label(
+ doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.",
+ ),
+ override_target_bin = attr.label(
+ doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.",
+ ),
),
)
diff --git a/examples/bzlmod/override_target/.bazelrc b/examples/bzlmod/override_target/.bazelrc
new file mode 100644
index 0000000..f9d474e
--- /dev/null
+++ b/examples/bzlmod/override_target/.bazelrc
@@ -0,0 +1,12 @@
+# Required on windows
+common --enable_platform_specific_config
+startup --windows_enable_symlinks
+build:windows --enable_runfiles
+
+build --experimental_enable_bzlmod
+
+# This isn't currently the defaut in Bazel, but we enable it to test we'll be ready if/when it flips.
+build --incompatible_disallow_empty_glob
+
+# Required for cargo_build_script support before Bazel 7
+build --incompatible_merge_fixed_and_default_shell_env
diff --git a/examples/bzlmod/override_target/.gitignore b/examples/bzlmod/override_target/.gitignore
new file mode 100644
index 0000000..a6ef824
--- /dev/null
+++ b/examples/bzlmod/override_target/.gitignore
@@ -0,0 +1 @@
+/bazel-*
diff --git a/examples/bzlmod/override_target/BUILD.bazel b/examples/bzlmod/override_target/BUILD.bazel
new file mode 100644
index 0000000..c6c4df6
--- /dev/null
+++ b/examples/bzlmod/override_target/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+
+rust_library(
+ name = "override_targets_example",
+ srcs = glob(["src/*.rs"]),
+ edition = "2018",
+ deps = [
+ "@override_test//:foo",
+ ],
+)
+
+rust_library(
+ name = "foo",
+ srcs = ["foo.rs"],
+ edition = "2018",
+ visibility = ["//visibility:public"],
+)
+
+rust_test(
+ name = "unit_test",
+ crate = ":override_targets_example",
+ edition = "2018",
+)
diff --git a/examples/bzlmod/override_target/Cargo.lock b/examples/bzlmod/override_target/Cargo.lock
new file mode 100644
index 0000000..a629a08
--- /dev/null
+++ b/examples/bzlmod/override_target/Cargo.lock
@@ -0,0 +1,16 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "foo"
+version = "0.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7dbb6acfeff1d490fba693a402456f76b344fea77a5e7cae43b5970c3332b8f"
+
+[[package]]
+name = "override_targets"
+version = "0.0.0"
+dependencies = [
+ "foo",
+]
diff --git a/examples/bzlmod/override_target/Cargo.toml b/examples/bzlmod/override_target/Cargo.toml
new file mode 100644
index 0000000..997c3f2
--- /dev/null
+++ b/examples/bzlmod/override_target/Cargo.toml
@@ -0,0 +1,12 @@
+[workspace]
+[package]
+name = "override_targets"
+version = "0.0.0"
+edition = "2021"
+publish = false
+
+[lib]
+path = "/dev/null"
+
+[dependencies.foo]
+version = "0.0.0"
diff --git a/examples/bzlmod/override_target/MODULE.bazel b/examples/bzlmod/override_target/MODULE.bazel
new file mode 100644
index 0000000..06a5c69
--- /dev/null
+++ b/examples/bzlmod/override_target/MODULE.bazel
@@ -0,0 +1,44 @@
+"""bazelbuild/rules_rust - bzlmod example"""
+
+module(
+ name = "override_target_example_with_bzlmod",
+ version = "0.0.0",
+)
+
+bazel_dep(name = "platforms", version = "0.0.8")
+bazel_dep(
+ name = "bazel_skylib",
+ version = "1.5.0",
+)
+bazel_dep(
+ name = "rules_rust",
+ version = "0.0.0",
+)
+local_path_override(
+ module_name = "rules_rust",
+ path = "../../..",
+)
+
+rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
+rust.toolchain(edition = "2021")
+use_repo(
+ rust,
+ "rust_toolchains",
+)
+
+register_toolchains("@rust_toolchains//:all")
+
+crate = use_extension(
+ "@rules_rust//crate_universe:extension.bzl",
+ "crate",
+)
+crate.from_cargo(
+ name = "override_test",
+ cargo_lockfile = "//:Cargo.lock",
+ manifests = ["//:Cargo.toml"],
+)
+crate.annotation(
+ crate = "foo",
+ override_target_lib = "@//:foo",
+)
+use_repo(crate, "override_test")
diff --git a/examples/bzlmod/override_target/WORKSPACE.bazel b/examples/bzlmod/override_target/WORKSPACE.bazel
new file mode 100644
index 0000000..b543b79
--- /dev/null
+++ b/examples/bzlmod/override_target/WORKSPACE.bazel
@@ -0,0 +1 @@
+# Intentionally blank; using bzlmod
diff --git a/examples/bzlmod/override_target/WORKSPACE.bzlmod b/examples/bzlmod/override_target/WORKSPACE.bzlmod
new file mode 100644
index 0000000..8e081c0
--- /dev/null
+++ b/examples/bzlmod/override_target/WORKSPACE.bzlmod
@@ -0,0 +1 @@
+# Intentionally blank; enable strict mode for bzlmod
diff --git a/examples/bzlmod/override_target/foo.rs b/examples/bzlmod/override_target/foo.rs
new file mode 100644
index 0000000..c3e5fb0
--- /dev/null
+++ b/examples/bzlmod/override_target/foo.rs
@@ -0,0 +1 @@
+pub const THE_ANSWER: u32 = 42;
diff --git a/examples/bzlmod/override_target/src/lib.rs b/examples/bzlmod/override_target/src/lib.rs
new file mode 100644
index 0000000..3334c92
--- /dev/null
+++ b/examples/bzlmod/override_target/src/lib.rs
@@ -0,0 +1,6 @@
+mod test {
+ #[test]
+ pub fn test() {
+ assert_eq!(foo::THE_ANSWER, 42);
+ }
+}