From 7d2225e10bd3846f3b0561151da320f7a4cded17 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 9 Sep 2025 12:28:43 -0600 Subject: [PATCH] fix(sozo): rework the detection of Dojo default package --- Cargo.lock | 1 + crates/dojo/dojo-snf-test/Scarb.lock | 14 ++--- crates/sozo/scarb_metadata_ext/Cargo.toml | 1 + .../sozo/scarb_metadata_ext/src/metadata.rs | 58 ++++++++++++++----- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6671b9bc73..ffe46c3407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6593,6 +6593,7 @@ dependencies = [ "serde_json", "smol_str", "toml 0.8.22", + "tracing", ] [[package]] diff --git a/crates/dojo/dojo-snf-test/Scarb.lock b/crates/dojo/dojo-snf-test/Scarb.lock index c427296b7f..8b0dc488af 100644 --- a/crates/dojo/dojo-snf-test/Scarb.lock +++ b/crates/dojo/dojo-snf-test/Scarb.lock @@ -3,18 +3,18 @@ version = 1 [[package]] name = "dojo" -version = "1.6.0-alpha.1" +version = "1.7.0-alpha.2" dependencies = [ "dojo_macros", ] [[package]] name = "dojo_macros" -version = "1.6.0-alpha.1" +version = "1.7.0-alpha.2" [[package]] name = "dojo_snf_test" -version = "1.6.0-alpha.1" +version = "1.7.0-alpha.2" dependencies = [ "dojo", "snforge_std", @@ -22,15 +22,15 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.43.1" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:178e1e2081003ae5e40b5a8574654bed15acbd31cce651d4e74fe2f009bc0122" +checksum = "sha256:2dd27e8215eea8785b3930e9f452e11b429ca262b1c1fbb071bfc173b9ebc125" [[package]] name = "snforge_std" -version = "0.43.1" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:17bc65b0abfb9b174784835df173f9c81c9ad39523dba760f30589ef53cf8bb5" +checksum = "sha256:89f759fa685d48ed0ba7152d2ac2eb168da08dfa8b84b2bee96e203dc5b2413e" dependencies = [ "snforge_scarb_plugin", ] diff --git a/crates/sozo/scarb_metadata_ext/Cargo.toml b/crates/sozo/scarb_metadata_ext/Cargo.toml index 2f31ffe766..69d3e455e1 100644 --- a/crates/sozo/scarb_metadata_ext/Cargo.toml +++ b/crates/sozo/scarb_metadata_ext/Cargo.toml @@ -16,3 +16,4 @@ dunce.workspace = true scarb-metadata.workspace = true smol_str.workspace = true scarb-interop.workspace = true +tracing.workspace = true diff --git a/crates/sozo/scarb_metadata_ext/src/metadata.rs b/crates/sozo/scarb_metadata_ext/src/metadata.rs index f6b9006989..f0b34468bf 100644 --- a/crates/sozo/scarb_metadata_ext/src/metadata.rs +++ b/crates/sozo/scarb_metadata_ext/src/metadata.rs @@ -10,6 +10,7 @@ use dojo_world::local::WorldLocal; use scarb_interop::fsx; use scarb_metadata::{DepKind, Metadata, MetadataCommand, MetadataCommandError, PackageMetadata}; use serde::Serialize; +use tracing::debug; #[derive(Debug, PartialEq)] pub enum TestRunner { @@ -20,7 +21,7 @@ pub enum TestRunner { const CAIRO_TEST_RUNNER_NAME: &str = "cairo_test"; const SNF_TEST_RUNNER_NAME: &str = "snforge_std"; -const DOJO_MACROS_NAME: &str = "dojo_macros"; +const DOJO_WORLD_NAME: &str = "dojo::world::world_contract::world"; impl From<&String> for TestRunner { fn from(value: &String) -> Self { @@ -297,8 +298,11 @@ enum WorldPackageResult { /// performing some tasks like binding generation and migrations. /// /// To solve the issue where a virtual workspace has no package name, this function looks for a -/// package that is *not* a `lib` target and uses `dojo_macros` as a dependency. -/// If it finds exactly one package that matches the criteria, it returns the package name. +/// package that has a starknet-contract target that has a build-external-contracts parameter that +/// contains the dojo world. We can't rely on the package being a library, since some libraries +/// might be used in the contracts to be deployed with a world. For this reason, we first look for a +/// package that is not a library and then a package that is a library. If it finds exactly one +/// package that matches the criteria, it returns the package name. /// /// Otherwise, it returns a `MultiplePackages` variant, which will be handled by the caller, which /// generally should indicate to the user that using multiple packages with contracts to be deployed @@ -306,21 +310,49 @@ enum WorldPackageResult { /// migrate the package with contracts themselves by going into the package directory and running /// the commands. fn default_dojo_package_name(packages: &[PackageMetadata]) -> WorldPackageResult { - let mut candidates = Vec::new(); + let mut not_lib_candidates = Vec::new(); + let mut lib_candidates = Vec::new(); for p in packages { - if p.targets.iter().all(|t| t.kind != "lib") { - for d in &p.dependencies { - if d.name == DOJO_MACROS_NAME { - candidates.push(p.name.clone()); + let is_lib = p.targets.iter().any(|t| t.kind == "lib"); + + debug!(%p.name, is_lib, "Verifying package type."); + + for t in &p.targets { + if t.kind == "starknet-contract" { + if let Some(build_external_contracts) = + t.params.as_object().and_then(|obj| obj.get("build-external-contracts")) + { + if let Some(build_external_contracts) = build_external_contracts.as_array() { + if build_external_contracts + .contains(&serde_json::Value::String(DOJO_WORLD_NAME.to_string())) + { + if is_lib { + lib_candidates.push(p.name.clone()); + } else { + not_lib_candidates.push(p.name.clone()); + } + } + } } } } } - match candidates.len() { - 0 => WorldPackageResult::NoPackage, - 1 => WorldPackageResult::Ok(candidates[0].clone()), - _ => WorldPackageResult::MultiplePackages(candidates), - } + debug!(?not_lib_candidates, ?lib_candidates, "Collect candidates for Sozo build."); + + // Prioritize not lib candidates, then lib candidates. + let r = match not_lib_candidates.len() { + 0 => match lib_candidates.len() { + 0 => WorldPackageResult::NoPackage, + 1 => WorldPackageResult::Ok(lib_candidates[0].clone()), + _ => WorldPackageResult::MultiplePackages(lib_candidates), + }, + 1 => WorldPackageResult::Ok(not_lib_candidates[0].clone()), + _ => WorldPackageResult::MultiplePackages(not_lib_candidates), + }; + + debug!(?r, "Extract default dojo package name from workspace."); + + r }