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..79bc44420 100644 --- a/scarb/src/core/manifest/toml_manifest.rs +++ b/scarb/src/core/manifest/toml_manifest.rs @@ -280,6 +280,7 @@ pub struct DetailedTomlDependency { pub struct TomlTarget

{ pub name: Option, pub source_path: Option, + pub group_id: Option, #[serde(flatten)] pub params: P, @@ -654,6 +655,7 @@ impl TomlManifest { let target_config = TomlTarget:: { name: Some(target_name), source_path, + group_id: None, params: TestTargetProps::default().try_into()?, }; targets.extend(Self::collect_target::( @@ -672,6 +674,7 @@ impl TomlManifest { let target_config = TomlTarget:: { name: Some(target_name), source_path: Some(source_path), + group_id: None, params: TestTargetProps::new(TestTargetType::Integration).try_into()?, }; targets.extend(Self::collect_target::( @@ -705,6 +708,7 @@ impl TomlManifest { let target_config = TomlTarget:: { name: Some(target_name), source_path: Some(source_path), + group_id: Some("integration_tests".into()), params: TestTargetProps::new(TestTargetType::Integration).try_into()?, }; targets.extend(Self::collect_target( @@ -747,7 +751,13 @@ 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, + target.group_id.clone(), + &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() } diff --git a/scarb/tests/workspace.rs b/scarb/tests/workspace.rs index 8c365ea4d..e007fa30c 100644 --- a/scarb/tests/workspace.rs +++ b/scarb/tests/workspace.rs @@ -126,3 +126,25 @@ fn target_name_duplicate() { help: use different target names to resolve the conflict "#}); } + +#[test] +fn target_group_id_duplicates_target_name() { + let t = TempDir::new().unwrap(); + ProjectBuilder::start() + .name("first") + .manifest_extra(indoc! {r#" + [[target.starknet-contract]] + name = "hello" + group-id = "hello" + "#}) + .build(&t); + Scarb::quick_snapbox() + .arg("fetch") + .current_dir(&t) + .assert() + .failure() + .stdout_matches(indoc! {r#" + error: the group id `hello` of target `starknet-contract` duplicates target name + help: use different group name to resolve the conflict + "#}); +}