| use std::collections::{BTreeMap, BTreeSet}; |
| |
| use serde::Deserialize; |
| |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] |
| #[serde(deny_unknown_fields)] |
| pub struct CrateSpec { |
| pub aliases: BTreeMap<String, String>, |
| pub crate_id: String, |
| pub display_name: String, |
| pub edition: String, |
| pub root_module: String, |
| pub is_workspace_member: bool, |
| pub deps: BTreeSet<String>, |
| pub proc_macro_dylib_path: Option<String>, |
| pub source: Option<CrateSpecSource>, |
| pub cfg: Vec<String>, |
| pub env: BTreeMap<String, String>, |
| pub target: String, |
| pub crate_type: CrateType, |
| pub is_test: bool, |
| pub build: Option<CrateSpecBuild>, |
| } |
| |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] |
| #[serde(deny_unknown_fields)] |
| pub struct CrateSpecBuild { |
| pub label: String, |
| pub build_file: String, |
| } |
| |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] |
| #[serde(deny_unknown_fields)] |
| pub struct CrateSpecSource { |
| pub exclude_dirs: Vec<String>, |
| pub include_dirs: Vec<String>, |
| } |
| |
| #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] |
| #[serde(rename_all = "kebab-case")] |
| pub enum CrateType { |
| Bin, |
| Rlib, |
| Lib, |
| Dylib, |
| Cdylib, |
| Staticlib, |
| ProcMacro, |
| } |
| |
| /// Read all crate specs, deduplicating crates with the same ID. This happens when |
| /// a rust_test depends on a rust_library, for example. |
| pub fn consolidate_crate_specs(crate_specs: Vec<CrateSpec>) -> anyhow::Result<BTreeSet<CrateSpec>> { |
| let mut consolidated_specs: BTreeMap<String, CrateSpec> = BTreeMap::new(); |
| for mut spec in crate_specs.into_iter() { |
| log::debug!("{:?}", spec); |
| if let Some(existing) = consolidated_specs.get_mut(&spec.crate_id) { |
| existing.deps.extend(spec.deps); |
| existing.env.extend(spec.env); |
| existing.aliases.extend(spec.aliases); |
| |
| if let Some(source) = &mut existing.source { |
| if let Some(mut new_source) = spec.source { |
| new_source |
| .exclude_dirs |
| .retain(|src| !source.exclude_dirs.contains(src)); |
| new_source |
| .include_dirs |
| .retain(|src| !source.include_dirs.contains(src)); |
| source.exclude_dirs.extend(new_source.exclude_dirs); |
| source.include_dirs.extend(new_source.include_dirs); |
| } |
| } else { |
| existing.source = spec.source; |
| } |
| |
| spec.cfg.retain(|cfg| !existing.cfg.contains(cfg)); |
| existing.cfg.extend(spec.cfg); |
| |
| // display_name should match the library's crate name because Rust Analyzer |
| // seems to use display_name for matching crate entries in rust-project.json |
| // against symbols in source files. For more details, see |
| // https://github.com/bazelbuild/rules_rust/issues/1032 |
| if spec.crate_type == CrateType::Rlib { |
| existing.display_name = spec.display_name; |
| existing.crate_type = CrateType::Rlib; |
| existing.is_test = spec.is_test; |
| } |
| |
| // We want to use the test target's build label to provide |
| // unit tests codelens actions for library crates in IDEs. |
| if spec.is_test { |
| if let Some(build) = spec.build { |
| existing.build = Some(build); |
| } |
| } |
| |
| // For proc-macro crates that exist within the workspace, there will be a |
| // generated crate-spec in both the fastbuild and opt-exec configuration. |
| // Prefer proc macro paths with an opt-exec component in the path. |
| if let Some(dylib_path) = spec.proc_macro_dylib_path.as_ref() { |
| const OPT_PATH_COMPONENT: &str = "-opt-exec-"; |
| if dylib_path.contains(OPT_PATH_COMPONENT) { |
| existing.proc_macro_dylib_path.replace(dylib_path.clone()); |
| } |
| } |
| } else { |
| consolidated_specs.insert(spec.crate_id.clone(), spec); |
| } |
| } |
| |
| Ok(consolidated_specs.into_values().collect()) |
| } |
| |
| #[cfg(test)] |
| mod test { |
| use super::*; |
| use itertools::Itertools; |
| |
| #[test] |
| fn consolidate_lib_then_test_specs() { |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-lib_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: Some(CrateSpecBuild { |
| label: "//:mylib".to_owned(), |
| build_file: "BUILD.bazel".to_owned(), |
| }), |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-extra_test_dep.rs".into(), |
| display_name: "extra_test_dep".into(), |
| edition: "2018".into(), |
| root_module: "extra_test_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-lib_dep.rs".into(), |
| display_name: "lib_dep".into(), |
| edition: "2018".into(), |
| root_module: "lib_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-extra_test_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| ]; |
| |
| assert_eq!( |
| consolidate_crate_specs(crate_specs).unwrap(), |
| BTreeSet::from([ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-lib_dep.rs".into(), "ID-extra_test_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: Some(CrateSpecBuild { |
| label: "//:mylib".to_owned(), |
| build_file: "BUILD.bazel".to_owned(), |
| }), |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-extra_test_dep.rs".into(), |
| display_name: "extra_test_dep".into(), |
| edition: "2018".into(), |
| root_module: "extra_test_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-lib_dep.rs".into(), |
| display_name: "lib_dep".into(), |
| edition: "2018".into(), |
| root_module: "lib_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| ]) |
| ); |
| } |
| |
| #[test] |
| fn consolidate_test_then_lib_specs() { |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-extra_test_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-lib_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-extra_test_dep.rs".into(), |
| display_name: "extra_test_dep".into(), |
| edition: "2018".into(), |
| root_module: "extra_test_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-lib_dep.rs".into(), |
| display_name: "lib_dep".into(), |
| edition: "2018".into(), |
| root_module: "lib_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| ]; |
| |
| assert_eq!( |
| consolidate_crate_specs(crate_specs).unwrap(), |
| BTreeSet::from([ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-lib_dep.rs".into(), "ID-extra_test_dep.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-extra_test_dep.rs".into(), |
| display_name: "extra_test_dep".into(), |
| edition: "2018".into(), |
| root_module: "extra_test_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-lib_dep.rs".into(), |
| display_name: "lib_dep".into(), |
| edition: "2018".into(), |
| root_module: "lib_dep.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| ]) |
| ); |
| } |
| |
| #[test] |
| fn consolidate_lib_test_main_specs() { |
| // mylib.rs is a library but has tests and an entry point, and mylib2.rs |
| // depends on mylib.rs. The display_name of the library target mylib.rs |
| // should be "mylib" no matter what order the crate specs is in. |
| // Otherwise Rust Analyzer will not be able to resolve references to |
| // mylib in mylib2.rs. |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_main".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib2.rs".into(), |
| display_name: "mylib2".into(), |
| edition: "2018".into(), |
| root_module: "mylib2.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-mylib.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| ]; |
| |
| for perm in crate_specs.into_iter().permutations(4) { |
| assert_eq!( |
| consolidate_crate_specs(perm).unwrap(), |
| BTreeSet::from([ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from([]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib2.rs".into(), |
| display_name: "mylib2".into(), |
| edition: "2018".into(), |
| root_module: "mylib2.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from(["ID-mylib.rs".into()]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: false, |
| build: None |
| }, |
| ]) |
| ); |
| } |
| } |
| |
| #[test] |
| fn consolidate_proc_macro_prefer_exec() { |
| // proc macro crates should prefer the -opt-exec- path which is always generated |
| // during builds where it is used, while the fastbuild version would only be built |
| // when explicitly building that target. |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-myproc_macro.rs".into(), |
| display_name: "myproc_macro".into(), |
| edition: "2018".into(), |
| root_module: "myproc_macro.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: Some( |
| "bazel-out/k8-opt-exec-F005BA11/bin/myproc_macro/libmyproc_macro-12345.so" |
| .into(), |
| ), |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::ProcMacro, |
| is_test: false, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-myproc_macro.rs".into(), |
| display_name: "myproc_macro".into(), |
| edition: "2018".into(), |
| root_module: "myproc_macro.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: Some( |
| "bazel-out/k8-fastbuild/bin/myproc_macro/libmyproc_macro-12345.so".into(), |
| ), |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::ProcMacro, |
| is_test: false, |
| build: None, |
| }, |
| ]; |
| |
| for perm in crate_specs.into_iter().permutations(2) { |
| assert_eq!( |
| consolidate_crate_specs(perm).unwrap(), |
| BTreeSet::from([CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-myproc_macro.rs".into(), |
| display_name: "myproc_macro".into(), |
| edition: "2018".into(), |
| root_module: "myproc_macro.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: Some( |
| "bazel-out/k8-opt-exec-F005BA11/bin/myproc_macro/libmyproc_macro-12345.so" |
| .into() |
| ), |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::ProcMacro, |
| is_test: false, |
| build: None, |
| },]) |
| ); |
| } |
| } |
| |
| #[test] |
| fn consolidate_spec_with_aliases() { |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::from([("ID-mylib_dep.rs".into(), "aliased_name".into())]), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| ]; |
| |
| for perm in crate_specs.into_iter().permutations(2) { |
| assert_eq!( |
| consolidate_crate_specs(perm).unwrap(), |
| BTreeSet::from([CrateSpec { |
| aliases: BTreeMap::from([("ID-mylib_dep.rs".into(), "aliased_name".into())]), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from([]), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }]) |
| ); |
| } |
| } |
| |
| #[test] |
| fn consolidate_spec_with_sources() { |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: None, |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: Some(CrateSpecSource { |
| exclude_dirs: vec!["exclude".into()], |
| include_dirs: vec!["include".into()], |
| }), |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| ]; |
| |
| for perm in crate_specs.into_iter().permutations(2) { |
| assert_eq!( |
| consolidate_crate_specs(perm).unwrap(), |
| BTreeSet::from([CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from([]), |
| proc_macro_dylib_path: None, |
| source: Some(CrateSpecSource { |
| exclude_dirs: vec!["exclude".into()], |
| include_dirs: vec!["include".into()], |
| }), |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }]) |
| ); |
| } |
| } |
| |
| #[test] |
| fn consolidate_spec_with_duplicate_sources() { |
| let crate_specs = vec![ |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: Some(CrateSpecSource { |
| exclude_dirs: vec!["exclude".into()], |
| include_dirs: vec!["include".into()], |
| }), |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }, |
| CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib_test".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::new(), |
| proc_macro_dylib_path: None, |
| source: Some(CrateSpecSource { |
| exclude_dirs: vec!["exclude".into()], |
| include_dirs: vec!["include".into()], |
| }), |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Bin, |
| is_test: true, |
| build: None, |
| }, |
| ]; |
| |
| for perm in crate_specs.into_iter().permutations(2) { |
| assert_eq!( |
| consolidate_crate_specs(perm).unwrap(), |
| BTreeSet::from([CrateSpec { |
| aliases: BTreeMap::new(), |
| crate_id: "ID-mylib.rs".into(), |
| display_name: "mylib".into(), |
| edition: "2018".into(), |
| root_module: "mylib.rs".into(), |
| is_workspace_member: true, |
| deps: BTreeSet::from([]), |
| proc_macro_dylib_path: None, |
| source: Some(CrateSpecSource { |
| exclude_dirs: vec!["exclude".into()], |
| include_dirs: vec!["include".into()], |
| }), |
| cfg: vec!["test".into(), "debug_assertions".into()], |
| env: BTreeMap::new(), |
| target: "x86_64-unknown-linux-gnu".into(), |
| crate_type: CrateType::Rlib, |
| is_test: true, |
| build: None, |
| }]) |
| ); |
| } |
| } |
| } |