From f2f02346d88405ee27ab66ff370d85bda5efa03e Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Tue, 29 Jun 2021 08:11:43 -0700 Subject: [PATCH 1/6] The `compile_data` attribute can now be gathered from dependencies --- proto/proto.bzl | 1 + rust/private/providers.bzl | 3 ++- rust/private/rust.bzl | 4 ++++ rust/private/rustc.bzl | 8 ++++++-- test/compile_data/BUILD.bazel | 21 +++++++++++++++++++++ test/compile_data/compile_data.rs | 9 +++++++++ test/compile_data/compile_data.txt | 1 + test/compile_data/compile_data_test.rs | 9 +++++++++ 8 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 test/compile_data/BUILD.bazel create mode 100644 test/compile_data/compile_data.rs create mode 100644 test/compile_data/compile_data.txt create mode 100644 test/compile_data/compile_data_test.rs diff --git a/proto/proto.bzl b/proto/proto.bzl index 45207cb7ea..30952f90ff 100644 --- a/proto/proto.bzl +++ b/proto/proto.bzl @@ -234,6 +234,7 @@ def _rust_proto_compile(protos, descriptor_sets, imports, crate_name, ctx, is_gr edition = proto_toolchain.edition, rustc_env = {}, is_test = False, + compile_data = depset([target.files for target in getattr(ctx.attr, "compile_data", [])]), wrapped_crate_type = None, ), output_hash = output_hash, diff --git a/rust/private/providers.bzl b/rust/private/providers.bzl index a05f3d2fc3..adb209ef10 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -18,6 +18,7 @@ CrateInfo = provider( doc = "A provider containing general Crate information.", fields = { "aliases": "Dict[Label, String]: Renamed and aliased crates", + "compile_data": "depset[File]: Compile data required by this crate.", "deps": "depset[Provider]: This crate's (rust or cc) dependencies' providers.", "edition": "str: The edition of this crate.", "is_test": "bool: If the crate is being compiled in a test context", @@ -39,7 +40,7 @@ DepInfo = provider( doc = "A provider containing information about a Crate's dependencies.", fields = { "dep_env": "File: File with environment variables direct dependencies build scripts rely upon.", - "direct_crates": "depset[CrateInfo]", + "direct_crates": "depset[AliasableDepInfo]", "transitive_build_infos": "depset[BuildInfo]", "transitive_crates": "depset[CrateInfo]", "transitive_libs": "List[File]: All transitive dependencies, not filtered by type.", diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 62ddced299..4db0473a9b 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -266,6 +266,7 @@ def _rust_library_common(ctx, crate_type): edition = get_edition(ctx.attr, toolchain), rustc_env = ctx.attr.rustc_env, is_test = False, + compile_data = depset(ctx.files.compile_data), ), output_hash = output_hash, ) @@ -301,6 +302,7 @@ def _rust_binary_impl(ctx): edition = get_edition(ctx.attr, toolchain), rustc_env = ctx.attr.rustc_env, is_test = False, + compile_data = depset(ctx.files.compile_data), ), ) @@ -418,6 +420,7 @@ def _rust_test_common(ctx, toolchain, output): edition = crate.edition, rustc_env = ctx.attr.rustc_env, is_test = True, + compile_data = depset(crate.compile_data), wrapped_crate_type = crate.type, ) else: @@ -434,6 +437,7 @@ def _rust_test_common(ctx, toolchain, output): edition = get_edition(ctx.attr, toolchain), rustc_env = ctx.attr.rustc_env, is_test = True, + compile_data = depset(ctx.files.compile_data), ) providers = rustc_compile_action( diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index ea5ba025b0..bbbf901869 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -267,7 +267,7 @@ def collect_inputs( Args: ctx (ctx): The rule's context object. file (struct): A struct containing files defined in label type attributes marked as `allow_single_file`. - files (list): A list of all inputs. + files (list): A list of all inputs (`ctx.files`). toolchain (rust_toolchain): The current `rust_toolchain`. cc_toolchain (CcToolchainInfo): The current `cc_toolchain`. crate_info (CrateInfo): The Crate information of the crate to process build scripts for. @@ -281,9 +281,11 @@ def collect_inputs( linker_depset = cc_toolchain.all_files + # Collect compile data from the crate's dependencies + transitive_compile_data = depset(transitive = [info.compile_data for info in dep_info.transitive_crates.to_list()]) + compile_inputs = depset( getattr(files, "data", []) + - getattr(files, "compile_data", []) + [toolchain.rustc] + toolchain.crosstool_files + ([build_info.rustc_env, build_info.flags] if build_info else []) + @@ -294,6 +296,8 @@ def collect_inputs( linker_depset, crate_info.srcs, dep_info.transitive_libs, + transitive_compile_data, + crate_info.compile_data, ], ) build_env_files = getattr(files, "rustc_env_files", []) diff --git a/test/compile_data/BUILD.bazel b/test/compile_data/BUILD.bazel new file mode 100644 index 0000000000..274c8a3467 --- /dev/null +++ b/test/compile_data/BUILD.bazel @@ -0,0 +1,21 @@ +load("//rust:defs.bzl", "rust_library", "rust_test") + +# Note that this is the only target which assigns the `compile_data` attribute +rust_library( + name = "compile_data", + srcs = ["compile_data.rs"], + compile_data = ["compile_data.txt"], + edition = "2018", +) + +rust_test( + name = "compile_data_unit_test", + crate = ":compile_data", +) + +rust_test( + name = "compile_data_integration_test", + srcs = ["compile_data_test.rs"], + edition = "2018", + deps = [":compile_data"], +) diff --git a/test/compile_data/compile_data.rs b/test/compile_data/compile_data.rs new file mode 100644 index 0000000000..ccd7e64f63 --- /dev/null +++ b/test/compile_data/compile_data.rs @@ -0,0 +1,9 @@ +/// Data loaded from compile data +pub const COMPILE_DATA: &'static str = include_str!("compile_data.txt"); + +/// A test that is expected to be compiled from a target that does not +/// directly populate the `compile_data` attribute +#[test] +fn test_compile_data_contents() { + assert_eq!(COMPILE_DATA, "compile data contents\n"); +} diff --git a/test/compile_data/compile_data.txt b/test/compile_data/compile_data.txt new file mode 100644 index 0000000000..6d8daa7138 --- /dev/null +++ b/test/compile_data/compile_data.txt @@ -0,0 +1 @@ +compile data contents diff --git a/test/compile_data/compile_data_test.rs b/test/compile_data/compile_data_test.rs new file mode 100644 index 0000000000..ac640633b3 --- /dev/null +++ b/test/compile_data/compile_data_test.rs @@ -0,0 +1,9 @@ +use compile_data::COMPILE_DATA; + +#[test] +fn test_compile_data_contents() { + // This would confirm that the constant that's compiled into the `compile_data` + // crate matches the data loaded at compile time here. Where `compile_data.txt` + // would have only been provided by the `compile_data` crate itself. + assert_eq!(COMPILE_DATA, include_str!("compile_data.txt")); +} From 420ee0a19c4530090426c4177afc65741bbdb5b5 Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Wed, 30 Jun 2021 13:51:56 -0700 Subject: [PATCH 2/6] Don't transitively include compile_data from other targets --- rust/private/rustc.bzl | 4 ---- test/compile_data/BUILD.bazel | 7 ------- test/compile_data/compile_data_test.rs | 9 --------- 3 files changed, 20 deletions(-) delete mode 100644 test/compile_data/compile_data_test.rs diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index bbbf901869..87d329677f 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -281,9 +281,6 @@ def collect_inputs( linker_depset = cc_toolchain.all_files - # Collect compile data from the crate's dependencies - transitive_compile_data = depset(transitive = [info.compile_data for info in dep_info.transitive_crates.to_list()]) - compile_inputs = depset( getattr(files, "data", []) + [toolchain.rustc] + @@ -296,7 +293,6 @@ def collect_inputs( linker_depset, crate_info.srcs, dep_info.transitive_libs, - transitive_compile_data, crate_info.compile_data, ], ) diff --git a/test/compile_data/BUILD.bazel b/test/compile_data/BUILD.bazel index 274c8a3467..4a72d0af3f 100644 --- a/test/compile_data/BUILD.bazel +++ b/test/compile_data/BUILD.bazel @@ -12,10 +12,3 @@ rust_test( name = "compile_data_unit_test", crate = ":compile_data", ) - -rust_test( - name = "compile_data_integration_test", - srcs = ["compile_data_test.rs"], - edition = "2018", - deps = [":compile_data"], -) diff --git a/test/compile_data/compile_data_test.rs b/test/compile_data/compile_data_test.rs deleted file mode 100644 index ac640633b3..0000000000 --- a/test/compile_data/compile_data_test.rs +++ /dev/null @@ -1,9 +0,0 @@ -use compile_data::COMPILE_DATA; - -#[test] -fn test_compile_data_contents() { - // This would confirm that the constant that's compiled into the `compile_data` - // crate matches the data loaded at compile time here. Where `compile_data.txt` - // would have only been provided by the `compile_data` crate itself. - assert_eq!(COMPILE_DATA, include_str!("compile_data.txt")); -} From 672f3cef2ea2460ad9b56789775b4ed7184d06b8 Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Sat, 10 Jul 2021 10:25:45 -0700 Subject: [PATCH 3/6] Fixed clippy defect --- test/compile_data/compile_data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compile_data/compile_data.rs b/test/compile_data/compile_data.rs index ccd7e64f63..362f96a29e 100644 --- a/test/compile_data/compile_data.rs +++ b/test/compile_data/compile_data.rs @@ -1,5 +1,5 @@ /// Data loaded from compile data -pub const COMPILE_DATA: &'static str = include_str!("compile_data.txt"); +pub const COMPILE_DATA: &str = include_str!("compile_data.txt"); /// A test that is expected to be compiled from a target that does not /// directly populate the `compile_data` attribute From 4cd549899ffa9ad867cd3fbdc977861d94a817cf Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Thu, 15 Jul 2021 05:15:43 -0700 Subject: [PATCH 4/6] Added a wrapper test module --- test/compile_data/compile_data.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/compile_data/compile_data.rs b/test/compile_data/compile_data.rs index 362f96a29e..302892d540 100644 --- a/test/compile_data/compile_data.rs +++ b/test/compile_data/compile_data.rs @@ -1,9 +1,14 @@ /// Data loaded from compile data pub const COMPILE_DATA: &str = include_str!("compile_data.txt"); -/// A test that is expected to be compiled from a target that does not -/// directly populate the `compile_data` attribute -#[test] -fn test_compile_data_contents() { - assert_eq!(COMPILE_DATA, "compile data contents\n"); +#[cfg(test)] +mod test { + use super::*; + + /// A test that is expected to be compiled from a target that does not + /// directly populate the `compile_data` attribute + #[test] + fn test_compile_data_contents() { + assert_eq!(COMPILE_DATA, "compile data contents\n"); + } } From 850dc91ac151dd0670d986bdd6a26fb4cffaa5ae Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Thu, 15 Jul 2021 06:33:29 -0700 Subject: [PATCH 5/6] Added unittests --- rust/private/rust.bzl | 11 +- test/compile_data/BUILD.bazel | 14 --- test/compile_data/compile_data.rs | 14 --- test/unit/compile_data/BUILD.bazel | 5 + test/unit/compile_data/compile_data.rs | 26 +++++ test/{ => unit}/compile_data/compile_data.txt | 0 test/unit/compile_data/compile_data_test.bzl | 100 ++++++++++++++++++ test/unit/compile_data/test_compile_data.txt | 1 + 8 files changed, 141 insertions(+), 30 deletions(-) delete mode 100644 test/compile_data/BUILD.bazel delete mode 100644 test/compile_data/compile_data.rs create mode 100644 test/unit/compile_data/BUILD.bazel create mode 100644 test/unit/compile_data/compile_data.rs rename test/{ => unit}/compile_data/compile_data.txt (100%) create mode 100644 test/unit/compile_data/compile_data_test.bzl create mode 100644 test/unit/compile_data/test_compile_data.txt diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 4db0473a9b..5dc5669713 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -406,8 +406,15 @@ def _rust_test_common(ctx, toolchain, output): crate_type = "bin" if ctx.attr.crate: # Target is building the crate in `test` config - # Build the test binary using the dependency's srcs. crate = ctx.attr.crate[rust_common.crate_info] + + # Optionally join compile data + if crate.compile_data: + compile_data = depset(ctx.files.compile_data, transitive = [crate.compile_data]) + else: + compile_data = depset(ctx.files.compile_data) + + # Build the test binary using the dependency's srcs. crate_info = rust_common.create_crate_info( name = crate_name, type = crate_type, @@ -420,7 +427,7 @@ def _rust_test_common(ctx, toolchain, output): edition = crate.edition, rustc_env = ctx.attr.rustc_env, is_test = True, - compile_data = depset(crate.compile_data), + compile_data = compile_data, wrapped_crate_type = crate.type, ) else: diff --git a/test/compile_data/BUILD.bazel b/test/compile_data/BUILD.bazel deleted file mode 100644 index 4a72d0af3f..0000000000 --- a/test/compile_data/BUILD.bazel +++ /dev/null @@ -1,14 +0,0 @@ -load("//rust:defs.bzl", "rust_library", "rust_test") - -# Note that this is the only target which assigns the `compile_data` attribute -rust_library( - name = "compile_data", - srcs = ["compile_data.rs"], - compile_data = ["compile_data.txt"], - edition = "2018", -) - -rust_test( - name = "compile_data_unit_test", - crate = ":compile_data", -) diff --git a/test/compile_data/compile_data.rs b/test/compile_data/compile_data.rs deleted file mode 100644 index 302892d540..0000000000 --- a/test/compile_data/compile_data.rs +++ /dev/null @@ -1,14 +0,0 @@ -/// Data loaded from compile data -pub const COMPILE_DATA: &str = include_str!("compile_data.txt"); - -#[cfg(test)] -mod test { - use super::*; - - /// A test that is expected to be compiled from a target that does not - /// directly populate the `compile_data` attribute - #[test] - fn test_compile_data_contents() { - assert_eq!(COMPILE_DATA, "compile data contents\n"); - } -} diff --git a/test/unit/compile_data/BUILD.bazel b/test/unit/compile_data/BUILD.bazel new file mode 100644 index 0000000000..8fce69a694 --- /dev/null +++ b/test/unit/compile_data/BUILD.bazel @@ -0,0 +1,5 @@ +load(":compile_data_test.bzl", "compile_data_test_suite") + +compile_data_test_suite( + name = "compile_data_test_suite", +) diff --git a/test/unit/compile_data/compile_data.rs b/test/unit/compile_data/compile_data.rs new file mode 100644 index 0000000000..ad3eb920a9 --- /dev/null +++ b/test/unit/compile_data/compile_data.rs @@ -0,0 +1,26 @@ +/// Data loaded from compile data +pub const COMPILE_DATA: &str = include_str!("compile_data.txt"); + +#[cfg(test)] +mod test { + use super::*; + + /// A test that is expected to be compiled from a target that does not + /// directly populate the `compile_data` attribute + #[test] + fn test_compile_data_contents() { + assert_eq!(COMPILE_DATA, "compile data contents\n"); + } + + /// An extra module that tests the `rust_test` rule wrapping the + /// `rust_library` is able to provide it's own compile data. + #[cfg(test_compile_data)] + mod test_compile_data { + const TEST_COMPILE_DATA: &str = include_str!("test_compile_data.txt"); + + #[test] + fn test_compile_data_contents() { + assert_eq!(TEST_COMPILE_DATA, "test compile data contents\n"); + } + } +} diff --git a/test/compile_data/compile_data.txt b/test/unit/compile_data/compile_data.txt similarity index 100% rename from test/compile_data/compile_data.txt rename to test/unit/compile_data/compile_data.txt diff --git a/test/unit/compile_data/compile_data_test.bzl b/test/unit/compile_data/compile_data_test.bzl new file mode 100644 index 0000000000..ee7b526b06 --- /dev/null +++ b/test/unit/compile_data/compile_data_test.bzl @@ -0,0 +1,100 @@ +"""Unittest to verify compile_data (attribute) propagation""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("//rust:defs.bzl", "rust_common", "rust_library", "rust_test") + +def _target_has_compile_data(ctx, expected): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + + # Extract compile_data from a target expected to have a `CrateInfo` provider + crate_info = target[rust_common.crate_info] + compile_data = crate_info.compile_data.to_list() + + # Ensure compile data was correctly propagated to the provider + asserts.equals( + env, + sorted([data.short_path for data in compile_data]), + expected, + ) + + return analysistest.end(env) + +def _compile_data_propagates_to_crate_info_test_impl(ctx): + return _target_has_compile_data( + ctx, + ["test/unit/compile_data/compile_data.txt"], + ) + +def _wrapper_rule_propagates_to_crate_info_test_impl(ctx): + return _target_has_compile_data( + ctx, + ["test/unit/compile_data/compile_data.txt"], + ) + +def _wrapper_rule_propagates_and_joins_compiel_data_test_impl(ctx): + return _target_has_compile_data( + ctx, + [ + "test/unit/compile_data/compile_data.txt", + "test/unit/compile_data/test_compile_data.txt", + ], + ) + +compile_data_propagates_to_crate_info_test = analysistest.make(_compile_data_propagates_to_crate_info_test_impl) +wrapper_rule_propagates_to_crate_info_test = analysistest.make(_wrapper_rule_propagates_to_crate_info_test_impl) +wrapper_rule_propagates_and_joins_compiel_data_test = analysistest.make(_wrapper_rule_propagates_and_joins_compiel_data_test_impl) + +def _define_test_targets(): + # Note that this is the only target which assigns the `compile_data` attribute + rust_library( + name = "compile_data", + srcs = ["compile_data.rs"], + compile_data = ["compile_data.txt"], + edition = "2018", + ) + + rust_test( + name = "compile_data_unit_test", + crate = ":compile_data", + ) + + rust_test( + name = "test_compile_data_unit_test", + compile_data = ["test_compile_data.txt"], + crate = ":compile_data", + rustc_flags = ["--cfg=test_compile_data"], + ) + +def compile_data_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name (str): Name of the macro. + """ + + _define_test_targets() + + compile_data_propagates_to_crate_info_test( + name = "compile_data_propagates_to_crate_info_test", + target_under_test = ":compile_data", + ) + + wrapper_rule_propagates_to_crate_info_test( + name = "wrapper_rule_propagates_to_crate_info_test", + target_under_test = ":compile_data_unit_test", + ) + + wrapper_rule_propagates_and_joins_compiel_data_test( + name = "wrapper_rule_propagates_and_joins_compiel_data_test", + target_under_test = ":test_compile_data_unit_test", + ) + + native.test_suite( + name = name, + tests = [ + ":compile_data_propagates_to_crate_info_test", + ":wrapper_rule_propagates_to_crate_info_test", + ":wrapper_rule_propagates_and_joins_compiel_data_test", + ], + ) diff --git a/test/unit/compile_data/test_compile_data.txt b/test/unit/compile_data/test_compile_data.txt new file mode 100644 index 0000000000..31ce1d31a2 --- /dev/null +++ b/test/unit/compile_data/test_compile_data.txt @@ -0,0 +1 @@ +test compile data contents From 231a4c3385a6dca6bfa90f5ed710241059747b06 Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Thu, 15 Jul 2021 08:55:08 -0700 Subject: [PATCH 6/6] Fixed typo --- test/unit/compile_data/compile_data_test.bzl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/unit/compile_data/compile_data_test.bzl b/test/unit/compile_data/compile_data_test.bzl index ee7b526b06..43782cd8a4 100644 --- a/test/unit/compile_data/compile_data_test.bzl +++ b/test/unit/compile_data/compile_data_test.bzl @@ -32,7 +32,7 @@ def _wrapper_rule_propagates_to_crate_info_test_impl(ctx): ["test/unit/compile_data/compile_data.txt"], ) -def _wrapper_rule_propagates_and_joins_compiel_data_test_impl(ctx): +def _wrapper_rule_propagates_and_joins_compile_data_test_impl(ctx): return _target_has_compile_data( ctx, [ @@ -43,10 +43,9 @@ def _wrapper_rule_propagates_and_joins_compiel_data_test_impl(ctx): compile_data_propagates_to_crate_info_test = analysistest.make(_compile_data_propagates_to_crate_info_test_impl) wrapper_rule_propagates_to_crate_info_test = analysistest.make(_wrapper_rule_propagates_to_crate_info_test_impl) -wrapper_rule_propagates_and_joins_compiel_data_test = analysistest.make(_wrapper_rule_propagates_and_joins_compiel_data_test_impl) +wrapper_rule_propagates_and_joins_compile_data_test = analysistest.make(_wrapper_rule_propagates_and_joins_compile_data_test_impl) def _define_test_targets(): - # Note that this is the only target which assigns the `compile_data` attribute rust_library( name = "compile_data", srcs = ["compile_data.rs"], @@ -85,8 +84,8 @@ def compile_data_test_suite(name): target_under_test = ":compile_data_unit_test", ) - wrapper_rule_propagates_and_joins_compiel_data_test( - name = "wrapper_rule_propagates_and_joins_compiel_data_test", + wrapper_rule_propagates_and_joins_compile_data_test( + name = "wrapper_rule_propagates_and_joins_compile_data_test", target_under_test = ":test_compile_data_unit_test", ) @@ -95,6 +94,6 @@ def compile_data_test_suite(name): tests = [ ":compile_data_propagates_to_crate_info_test", ":wrapper_rule_propagates_to_crate_info_test", - ":wrapper_rule_propagates_and_joins_compiel_data_test", + ":wrapper_rule_propagates_and_joins_compile_data_test", ], )