Allow deps to be renamed (#285) * Allow deps to be renamed * Add tests for renamed crates
diff --git a/proto/proto.bzl b/proto/proto.bzl index 15f1354..bd60a15 100644 --- a/proto/proto.bzl +++ b/proto/proto.bzl
@@ -167,6 +167,7 @@ root = lib_rs, srcs = srcs, deps = compile_deps, + aliases = {}, output = rust_lib, edition = proto_toolchain.edition, ),
diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index ac5b97a..60fb1a8 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl
@@ -120,6 +120,7 @@ root = lib_rs, srcs = ctx.files.srcs, deps = ctx.attr.deps, + aliases = ctx.attr.aliases, output = rust_lib, edition = _get_edition(ctx, toolchain), ), @@ -143,6 +144,7 @@ root = _crate_root_src(ctx, "main.rs"), srcs = ctx.files.srcs, deps = ctx.attr.deps, + aliases = ctx.attr.aliases, output = output, edition = _get_edition(ctx, toolchain), ), @@ -168,6 +170,7 @@ root = crate.root, srcs = crate.srcs + ctx.files.srcs, deps = crate.deps + ctx.attr.deps, + aliases = ctx.attr.aliases, output = test_binary, edition = crate.edition, ) @@ -186,6 +189,7 @@ root = _crate_root_src(ctx), srcs = ctx.files.srcs, deps = ctx.attr.deps, + aliases = ctx.attr.aliases, output = test_binary, edition = _get_edition(ctx, toolchain), ) @@ -275,6 +279,13 @@ linking a native library. """), ), + "aliases": attr.label_keyed_string_dict( + doc = _tidy(""" + Remap crates to a new name or moniker for linkage to this target + + These are other `rust_library` targets and will be presented as the new name given. + """), + ), "crate_features": attr.string_list( doc = _tidy(""" List of features to enable for this crate.
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 0839ae4..68fb8e3 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl
@@ -32,11 +32,19 @@ "root": "File: The source File entrypoint to this crate, eg. lib.rs", "srcs": "List[File]: All source Files that are part of the crate.", "deps": "List[Provider]: This crate's (rust or cc) dependencies' providers.", + "aliases": "Dict[Label, String]: Renamed and aliased crates", "output": "File: The output File that will be produced, depends on crate type.", "edition": "str: The edition of this crate.", }, ) +AliasableDep = provider( + fields = { + "name": "str", + "dep": "CrateInfo", + } +) + DepInfo = provider( fields = { "direct_crates": "depset[CrateInfo]", @@ -84,7 +92,7 @@ else: return libname -def collect_deps(deps, toolchain): +def collect_deps(deps, aliases, toolchain): """ Walks through dependencies and collects the transitive dependencies. @@ -101,10 +109,17 @@ transitive_crates = depset() transitive_dylibs = depset(order = "topological") # dylib link flag ordering matters. transitive_staticlibs = depset() + + aliases = {k.label: v for k,v in aliases.items()} for dep in deps: if CrateInfo in dep: # This dependency is a rust_library - direct_crates += [dep[CrateInfo]] + direct_dep = dep[CrateInfo] + aliasable_dep = AliasableDep( + name = aliases.get(dep.label, direct_dep.name), + dep = direct_dep, + ) + direct_crates += [aliasable_dep] transitive_crates = depset([dep[CrateInfo]], transitive = [transitive_crates]) transitive_crates = depset(transitive = [transitive_crates, dep[DepInfo].transitive_crates]) transitive_dylibs = depset(transitive = [transitive_dylibs, dep[DepInfo].transitive_dylibs]) @@ -197,6 +212,7 @@ dep_info = collect_deps( crate_info.deps, + crate_info.aliases, toolchain, ) @@ -389,7 +405,7 @@ ) def _crate_to_link_flag(crate_info): - return ["--extern", "{}={}".format(crate_info.name, crate_info.output.path)] + return ["--extern", "{}={}".format(crate_info.name, crate_info.dep.output.path)] def _get_crate_dirname(crate): return crate.output.dirname
diff --git a/rust/private/rustdoc_test.bzl b/rust/private/rustdoc_test.bzl index db69b67..1e90e28 100644 --- a/rust/private/rustdoc_test.bzl +++ b/rust/private/rustdoc_test.bzl
@@ -67,7 +67,7 @@ link_search_flags = [] link_flags += ["--extern=" + crate.name + "=" + crate.output.short_path] - link_flags += ["--extern=" + c.name + "=" + c.output.short_path for c in d.direct_crates.to_list()] + link_flags += ["--extern=" + c.name + "=" + c.dep.output.short_path for c in d.direct_crates.to_list()] link_search_flags += ["-Ldependency={}".format(dirname(c.output.short_path)) for c in d.transitive_crates.to_list()] link_flags += ["-ldylib=" + get_lib_name(lib) for lib in d.transitive_dylibs.to_list()]
diff --git a/test/renamed_deps/BUILD b/test/renamed_deps/BUILD new file mode 100644 index 0000000..04408be --- /dev/null +++ b/test/renamed_deps/BUILD
@@ -0,0 +1,48 @@ +load( + "//rust:rust.bzl", + "rust_library", + "rust_test", +) + +rust_library( + name = "mod1", + srcs = ["mod1.rs"], +) + +rust_library( + name = "mod2", + srcs = ["mod2.rs"], + deps = [":mod1"], +) + +rust_library( + name = "mod3", + srcs = ["mod3.rs"], + aliases = { + ":mod1": "alias_a", + ":mod2": "alias_b", + }, + deps = [ + ":mod1", + ":mod2", + ], +) + +rust_test( + name = "mod1_test", + crate = ":mod1", +) + +rust_test( + name = "mod2_test", + crate = ":mod2", +) + +rust_test( + name = "mod3_test", + crate = ":mod3", + aliases = { + ":mod1": "alias_a", + ":mod2": "alias_b", + }, +)
diff --git a/test/renamed_deps/mod1.rs b/test/renamed_deps/mod1.rs new file mode 100644 index 0000000..a66f490 --- /dev/null +++ b/test/renamed_deps/mod1.rs
@@ -0,0 +1,11 @@ +pub fn world() -> String { + "world".to_owned() +} + +#[cfg(test)] +mod test { + #[test] + fn test_world() { + assert_eq!(super::world(), "world"); + } +}
diff --git a/test/renamed_deps/mod2.rs b/test/renamed_deps/mod2.rs new file mode 100644 index 0000000..cff993b --- /dev/null +++ b/test/renamed_deps/mod2.rs
@@ -0,0 +1,22 @@ +extern crate mod1; + +pub fn greeter(name: &str) -> String { + format!("Hello, {}!", name) +} + +pub fn default_greeter() -> String { + greeter(&mod1::world()) +} + +#[cfg(test)] +mod test { + #[test] + fn test_greeter() { + assert_eq!(super::greeter("Bob"), "Hello, Bob!"); + } + + #[test] + fn test_default_greeter() { + assert_eq!(super::default_greeter(), "Hello, world!"); + } +}
diff --git a/test/renamed_deps/mod3.rs b/test/renamed_deps/mod3.rs new file mode 100644 index 0000000..4942bf2 --- /dev/null +++ b/test/renamed_deps/mod3.rs
@@ -0,0 +1,38 @@ +// This crate depends on 2 crates with one of them depending on the other one. +// If the crates are not set correctly in the dependency chain, this crate won't +// compile. The order of the `extern crate` is important to trigger that bug. +extern crate alias_a; +extern crate alias_b; + +pub fn greet(name: &str) { + println!("{}", alias_b::greeter(name)) +} + +pub fn greet_default() { + println!("{}", alias_b::default_greeter()) +} + +/// This is a documentation. +/// +/// # Examples +/// +/// ```rust +/// assert!( +/// mod3::am_i_the_world("world") == true +/// ); +/// assert!( +/// mod3::am_i_the_world("myself") == false +/// ); +/// ``` +pub fn am_i_the_world(me: &str) -> bool { + return me == alias_a::world(); +} + +#[cfg(test)] +mod test { + #[test] + fn test_am_i_the_world() { + assert!(super::am_i_the_world("world")); + assert!(!super::am_i_the_world("bob")); + } +}