diff --git a/scarb/src/core/manifest/target.rs b/scarb/src/core/manifest/target.rs index 84689b275..d09f3a18c 100644 --- a/scarb/src/core/manifest/target.rs +++ b/scarb/src/core/manifest/target.rs @@ -20,6 +20,7 @@ pub struct TargetInner { pub kind: TargetKind, pub name: SmolStr, pub source_path: Utf8PathBuf, + pub group_id: Option, pub params: toml::Value, } @@ -36,6 +37,7 @@ impl Target { kind: TargetKind, name: impl Into, source_path: impl Into, + group_id: Option, params: toml::Value, ) -> Self { assert!(params.is_table(), "params must be a TOML table"); @@ -43,6 +45,7 @@ impl Target { kind, name: name.into(), source_path: source_path.into(), + group_id, params, })) } @@ -56,6 +59,7 @@ impl Target { kind, name, source_path, + None, toml::Value::Table(toml::Table::new()), ) } @@ -64,10 +68,11 @@ impl Target { kind: TargetKind, name: impl Into, source_path: impl Into, + group_id: Option, params: impl Serialize, ) -> Result { let params = toml::Value::try_from(params)?; - Ok(Self::new(kind, name, source_path, params)) + Ok(Self::new(kind, name, source_path, group_id, params)) } pub fn is_lib(&self) -> bool { diff --git a/scarb/src/core/manifest/toml_manifest.rs b/scarb/src/core/manifest/toml_manifest.rs index 3aebea344..11e5f01e5 100644 --- a/scarb/src/core/manifest/toml_manifest.rs +++ b/scarb/src/core/manifest/toml_manifest.rs @@ -592,6 +592,7 @@ impl TomlManifest { self.lib.as_ref(), &package_name, root, + None, )?); targets.extend(Self::collect_target( @@ -599,6 +600,7 @@ impl TomlManifest { self.cairo_plugin.as_ref(), &package_name, root, + None, )?); for (kind, ext_toml) in self @@ -612,6 +614,7 @@ impl TomlManifest { Some(ext_toml), &package_name, root, + None, )?); } @@ -645,6 +648,7 @@ impl TomlManifest { Some(test_toml), &package_name, root, + None, )?); } } else if auto_detect { @@ -661,6 +665,7 @@ impl TomlManifest { Some(&target_config), &package_name, root, + None, )?); // Auto-detect test targets from `tests` directory. let tests_path = root.join(DEFAULT_TESTS_PATH); @@ -679,6 +684,7 @@ impl TomlManifest { Some(&target_config), &package_name, root, + None, )?); } else { // Tests directory does not contain `lib.cairo` file. @@ -712,6 +718,7 @@ impl TomlManifest { Some(&target_config), &package_name, root, + Some("integration_tests".into()), )?); } } @@ -725,6 +732,7 @@ impl TomlManifest { target: Option<&TomlTarget>, default_name: &SmolStr, root: &Utf8Path, + group_id: Option, ) -> Result> { let default_source_path = root.join(DEFAULT_SOURCE_PATH.as_path()); let Some(target) = target else { @@ -747,7 +755,8 @@ impl TomlManifest { .transpose()? .unwrap_or(default_source_path.to_path_buf()); - let target = Target::try_from_structured_params(kind, name, source_path, &target.params)?; + let target = + Target::try_from_structured_params(kind, name, source_path, group_id, &target.params)?; Ok(Some(target)) } diff --git a/scarb/src/core/workspace.rs b/scarb/src/core/workspace.rs index ba84eb768..9a0789da6 100644 --- a/scarb/src/core/workspace.rs +++ b/scarb/src/core/workspace.rs @@ -187,6 +187,23 @@ fn check_unique_targets(targets: &Vec<&Target>) -> Result<()> { ) } } + for (kind, group_id) in targets + .iter() + .filter_map(|target| { + target + .group_id + .clone() + .map(|group_id| (target.kind.clone(), group_id)) + }) + .unique() + { + if used.contains(&(kind.as_str(), group_id.as_str())) { + bail!( + "the group id `{group_id}` of target `{kind}` duplicates target name\n\ + help: use different group name to resolve the conflict", + ) + } + } Ok(()) } diff --git a/scarb/src/ops/metadata.rs b/scarb/src/ops/metadata.rs index d9294f29d..69089f4fe 100644 --- a/scarb/src/ops/metadata.rs +++ b/scarb/src/ops/metadata.rs @@ -194,11 +194,18 @@ fn collect_dependency_kind(kind: &DepKind) -> Option { } fn collect_target_metadata(target: &Target) -> m::TargetMetadata { + let mut params = toml_to_json(&target.params); + if let Some(group) = target.group_id.as_ref() { + params.as_object_mut().unwrap().insert( + "group-id".to_string(), + serde_json::Value::String(group.to_string()), + ); + } m::TargetMetadataBuilder::default() .kind(target.kind.to_string()) .name(target.name.to_string()) .source_path(target.source_path.clone()) - .params(toml_to_json(&target.params)) + .params(params) .build() .unwrap() }