diff --git a/scarb-metadata/src/lib.rs b/scarb-metadata/src/lib.rs index 2021f9023..343c4eec3 100644 --- a/scarb-metadata/src/lib.rs +++ b/scarb-metadata/src/lib.rs @@ -351,6 +351,11 @@ pub struct CompilationUnitComponentMetadata { pub name: String, /// Path to the root Cairo source file. pub source_path: Utf8PathBuf, + /// Items for the Cairo's `#[cfg(...)]` attribute to be enabled in this component. + /// + /// If not specified, the one from `CompilationUnit` will be used. + #[serde(default)] + pub cfg: Option>, /// Additional data not captured by deserializer. #[cfg_attr(feature = "builder", builder(default))] diff --git a/scarb/src/compiler/compilation_unit.rs b/scarb/src/compiler/compilation_unit.rs index 772ce8203..cf9fd55d8 100644 --- a/scarb/src/compiler/compilation_unit.rs +++ b/scarb/src/compiler/compilation_unit.rs @@ -38,6 +38,8 @@ pub struct CompilationUnit { pub compiler_config: ManifestCompilerConfig, /// Items for the Cairo's `#[cfg(...)]` attribute to be enabled in this unit. + /// + /// Each individual component can override this value. pub cfg_set: CfgSet, } @@ -49,6 +51,8 @@ pub struct CompilationUnitComponent { pub package: Package, /// Information about the specific target to build, out of the possible targets in `package`. pub target: Target, + /// Items for the Cairo's `#[cfg(...)]` attribute to be enabled in this component. + pub cfg_set: Option, } /// Information about a single package that is a compiler plugin to load for [`CompilationUnit`]. diff --git a/scarb/src/compiler/db.rs b/scarb/src/compiler/db.rs index 5c3be339c..2a61e2fe3 100644 --- a/scarb/src/compiler/db.rs +++ b/scarb/src/compiler/db.rs @@ -98,7 +98,7 @@ fn build_project_config(unit: &CompilationUnit) -> Result { component.cairo_package_name(), CrateSettings { edition: component.package.manifest.edition, - cfg_set: None, + cfg_set: component.cfg_set.clone(), // TODO (#1040): replace this with a macro experimental_features: cairo_lang_filesystem::db::ExperimentalFeaturesConfig { negative_impls: experimental_features diff --git a/scarb/src/ops/metadata.rs b/scarb/src/ops/metadata.rs index 008303e9a..3d16d0e72 100644 --- a/scarb/src/ops/metadata.rs +++ b/scarb/src/ops/metadata.rs @@ -210,6 +210,14 @@ fn collect_compilation_unit_metadata( .package(wrap_package_id(c.package.id)) .name(c.cairo_package_name()) .source_path(c.target.source_path.clone()) + .cfg(c.cfg_set.as_ref().map(|cfg_set| cfg_set + .iter() + .map(|cfg| { + serde_json::to_value(cfg) + .and_then(serde_json::from_value::) + .expect("Cairo's `Cfg` must serialize identically as Scarb Metadata's `Cfg`.") + }) + .collect::>())) .build() .unwrap() }) diff --git a/scarb/src/ops/resolve.rs b/scarb/src/ops/resolve.rs index fedfaab95..40697a654 100644 --- a/scarb/src/ops/resolve.rs +++ b/scarb/src/ops/resolve.rs @@ -220,7 +220,29 @@ fn generate_cairo_compilation_units( package }; - CompilationUnitComponent { package, target } + let cfg_set = { + if package.id == member.id { + None + } else { + let component_cfg_set = cfg_set + .iter() + .filter(|cfg| **cfg != Cfg::name("test")) + .cloned() + .collect(); + + if component_cfg_set != cfg_set { + Some(component_cfg_set) + } else { + None + } + } + }; + + CompilationUnitComponent { + package, + target, + cfg_set, + } }) .collect(); @@ -242,6 +264,7 @@ fn generate_cairo_compilation_units( // Add `lib` target for tested package, to be available as dependency. components.push(CompilationUnitComponent { package: member.clone(), + cfg_set: None, target, }); diff --git a/scarb/tests/build.rs b/scarb/tests/build.rs index 0c941ffab..bb8c9ad46 100644 --- a/scarb/tests/build.rs +++ b/scarb/tests/build.rs @@ -759,6 +759,48 @@ fn dev_dep_inside_test() { "#}); } +#[test] +fn build_test_without_compiling_tests_from_dependencies() { + let t = TempDir::new().unwrap(); + let q = t.child("q"); + ProjectBuilder::start() + .name("q") + .lib_cairo(indoc! {r#" + fn dev_dep_function() -> felt252 { 42 } + + #[cfg(test)] + mod tests { + use missing::func; + } + "#}) + .build(&q); + ProjectBuilder::start() + .name("x") + .dev_dep("q", &q) + .lib_cairo(indoc! {r#" + #[cfg(test)] + mod tests { + use q::dev_dep_function; + + fn it_works() { + dev_dep_function(); + } + } + "#}) + .build(&t); + + Scarb::quick_snapbox() + .arg("build") + .arg("--test") + .current_dir(&t) + .assert() + .success() + .stdout_matches(indoc! {r#" + [..] Compiling test(x_unittest) x v1.0.0 ([..]) + [..] Finished release target(s) in [..] + "#}); +} + #[test] fn warnings_allowed_by_default() { let t = TempDir::new().unwrap();