From 8532362405f7ca3a13bc925ba9e39b3dad4a0f12 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Sat, 1 Jun 2024 20:19:28 +0530 Subject: [PATCH 1/7] initial commit --- Cargo.lock | 1 + bin/sozo/src/commands/clean.rs | 2 +- bin/sozo/src/commands/dev.rs | 3 +- bin/sozo/src/commands/migrate.rs | 10 +- crates/benches/src/deployer.rs | 4 +- crates/dojo-lang/src/compiler.rs | 12 +-- crates/dojo-test-utils/src/migration.rs | 3 +- crates/dojo-world/src/contracts/world_test.rs | 3 +- .../dojo-world/src/manifest/manifest_test.rs | 6 +- crates/dojo-world/src/manifest/mod.rs | 84 +++++++++++++---- crates/sozo/ops/Cargo.toml | 1 + crates/sozo/ops/src/events.rs | 6 +- crates/sozo/ops/src/migration/migrate.rs | 4 +- crates/sozo/ops/src/migration/mod.rs | 94 ++++++++++++++++++- crates/sozo/ops/src/migration/utils.rs | 4 +- crates/sozo/ops/src/tests/migration.rs | 4 +- .../dojo_examples_actions_actions.toml | 6 +- .../dojo_examples_others_others.toml | 3 +- .../dev/overlays/dojo_base_base.toml | 1 + .../dev/overlays/dojo_world_world.toml | 1 + 20 files changed, 194 insertions(+), 58 deletions(-) create mode 100644 examples/spawn-and-move/manifests/dev/overlays/dojo_base_base.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/dojo_world_world.toml diff --git a/Cargo.lock b/Cargo.lock index 530db77742..d784dbbe5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12586,6 +12586,7 @@ dependencies = [ "starknet-crypto 0.6.2", "thiserror", "tokio", + "toml 0.8.13", "tracing", "tracing-log 0.1.4", "url", diff --git a/bin/sozo/src/commands/clean.rs b/bin/sozo/src/commands/clean.rs index 06fcd0a142..7d02a03834 100644 --- a/bin/sozo/src/commands/clean.rs +++ b/bin/sozo/src/commands/clean.rs @@ -3,7 +3,7 @@ use std::fs; use anyhow::Result; use camino::Utf8PathBuf; use clap::Args; -use dojo_lang::compiler::{ABIS_DIR, BASE_DIR, MANIFESTS_DIR}; +use dojo_world::manifest::{ABIS_DIR, BASE_DIR, MANIFESTS_DIR}; use scarb::core::Config; use tracing::trace; diff --git a/bin/sozo/src/commands/dev.rs b/bin/sozo/src/commands/dev.rs index ae6f7aa55b..2ff6eef64a 100644 --- a/bin/sozo/src/commands/dev.rs +++ b/bin/sozo/src/commands/dev.rs @@ -8,9 +8,8 @@ use cairo_lang_compiler::db::RootDatabase; use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroupEx, PrivRawFileContentQuery}; use cairo_lang_filesystem::ids::FileId; use clap::Args; -use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR}; use dojo_lang::scarb_internal::build_scarb_root_database; -use dojo_world::manifest::{BaseManifest, DeploymentManifest}; +use dojo_world::manifest::{BaseManifest, DeploymentManifest, BASE_DIR, MANIFESTS_DIR}; use dojo_world::metadata::dojo_metadata_from_workspace; use dojo_world::migration::world::WorldDiff; use dojo_world::migration::TxnConfig; diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index 9cbd421951..7823ccf8bc 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Context, Result}; use clap::{Args, Subcommand}; -use dojo_lang::compiler::MANIFESTS_DIR; +use dojo_world::manifest::MANIFESTS_DIR; use dojo_world::metadata::{dojo_metadata_from_workspace, Environment}; use dojo_world::migration::TxnConfig; use katana_rpc_api::starknet::RPC_SPEC_VERSION; @@ -50,6 +50,9 @@ pub enum MigrateCommand { #[command(flatten)] transaction: TransactionOptions, }, + + #[command(about = "Generate overlays file.")] + GenerateOverlays, } impl MigrateArgs { @@ -81,6 +84,7 @@ impl MigrateArgs { match self.command { MigrateCommand::Plan => config.tokio_handle().block_on(async { + trace!(name, "Planning migration."); migration::migrate( &ws, world_address, @@ -99,6 +103,10 @@ impl MigrateArgs { migration::migrate(&ws, world_address, rpc_url, account, &name, false, txn_config) .await }), + MigrateCommand::GenerateOverlays => { + trace!(name, "Generating Overlay files."); + migration::generate_overlays(&ws) + } } } } diff --git a/crates/benches/src/deployer.rs b/crates/benches/src/deployer.rs index abb0251c07..2a3aa0e08c 100644 --- a/crates/benches/src/deployer.rs +++ b/crates/benches/src/deployer.rs @@ -3,9 +3,9 @@ use std::path::PathBuf; use anyhow::{anyhow, bail, Context, Ok, Result}; use clap::Parser; -use dojo_lang::compiler::{DojoCompiler, DEPLOYMENTS_DIR, MANIFESTS_DIR}; +use dojo_lang::compiler::DojoCompiler; use dojo_lang::plugin::CairoPluginRepository; -use dojo_world::manifest::DeploymentManifest; +use dojo_world::manifest::{DeploymentManifest, DEPLOYMENTS_DIR, MANIFESTS_DIR}; use futures::executor::block_on; use katana_runner::KatanaRunner; use scarb::compiler::CompilerRepository; diff --git a/crates/dojo-lang/src/compiler.rs b/crates/dojo-lang/src/compiler.rs index 653aab250e..e21edfe2bb 100644 --- a/crates/dojo-lang/src/compiler.rs +++ b/crates/dojo-lang/src/compiler.rs @@ -21,7 +21,8 @@ use camino::{Utf8Path, Utf8PathBuf}; use convert_case::{Case, Casing}; use dojo_world::manifest::{ AbiFormat, Class, ComputedValueEntrypoint, DojoContract, DojoModel, Manifest, ManifestMethods, - BASE_CONTRACT_NAME, WORLD_CONTRACT_NAME, + ABIS_DIR, BASE_CONTRACT_NAME, BASE_DIR, CONTRACTS_DIR, MANIFESTS_DIR, MODELS_DIR, + WORLD_CONTRACT_NAME, }; use itertools::Itertools; use scarb::compiler::helpers::{build_compiler_config, collect_main_crate_ids}; @@ -40,15 +41,6 @@ use crate::semantics::utils::find_module_rw; const CAIRO_PATH_SEPARATOR: &str = "::"; -pub const MANIFESTS_DIR: &str = "manifests"; -pub const BASE_DIR: &str = "base"; -pub const OVERLAYS_DIR: &str = "overlays"; -pub const DEPLOYMENTS_DIR: &str = "deployments"; -pub const ABIS_DIR: &str = "abis"; - -pub const CONTRACTS_DIR: &str = "contracts"; -pub const MODELS_DIR: &str = "models"; - pub const SOURCES_DIR: &str = "src"; pub(crate) const LOG_TARGET: &str = "dojo_lang::compiler"; diff --git a/crates/dojo-test-utils/src/migration.rs b/crates/dojo-test-utils/src/migration.rs index 7ad6f25843..e8a576f341 100644 --- a/crates/dojo-test-utils/src/migration.rs +++ b/crates/dojo-test-utils/src/migration.rs @@ -1,7 +1,6 @@ use anyhow::Result; use camino::Utf8PathBuf; -use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; -use dojo_world::manifest::{BaseManifest, OverlayManifest}; +use dojo_world::manifest::{BaseManifest, OverlayManifest, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use dojo_world::migration::strategy::{prepare_for_migration, MigrationStrategy}; use dojo_world::migration::world::WorldDiff; use katana_primitives::FieldElement; diff --git a/crates/dojo-world/src/contracts/world_test.rs b/crates/dojo-world/src/contracts/world_test.rs index 3b856c1f46..c011d573fb 100644 --- a/crates/dojo-world/src/contracts/world_test.rs +++ b/crates/dojo-world/src/contracts/world_test.rs @@ -1,14 +1,13 @@ use std::time::Duration; use camino::Utf8PathBuf; -use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use dojo_test_utils::compiler; use katana_runner::KatanaRunner; use starknet::accounts::{Account, ConnectedAccount}; use starknet::core::types::{BlockId, BlockTag, FieldElement}; use super::{WorldContract, WorldContractReader}; -use crate::manifest::{BaseManifest, OverlayManifest}; +use crate::manifest::{BaseManifest, OverlayManifest, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use crate::migration::strategy::prepare_for_migration; use crate::migration::world::WorldDiff; use crate::migration::{Declarable, Deployable, TxnConfig}; diff --git a/crates/dojo-world/src/manifest/manifest_test.rs b/crates/dojo-world/src/manifest/manifest_test.rs index bc92e1a4f8..279f538d52 100644 --- a/crates/dojo-world/src/manifest/manifest_test.rs +++ b/crates/dojo-world/src/manifest/manifest_test.rs @@ -2,7 +2,6 @@ use std::io::Write; use cainome::cairo_serde::{ByteArray, CairoSerde}; use camino::Utf8PathBuf; -use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use dojo_test_utils::compiler; use dojo_test_utils::rpc::MockJsonRpcTransport; use katana_runner::KatanaRunner; @@ -17,7 +16,10 @@ use super::{ parse_contracts_events, AbiFormat, BaseManifest, DojoContract, DojoModel, OverlayManifest, }; use crate::contracts::world::test::deploy_world; -use crate::manifest::{parse_models_events, AbstractManifestError, DeploymentManifest, Manifest}; +use crate::manifest::{ + parse_models_events, AbstractManifestError, DeploymentManifest, Manifest, BASE_DIR, + MANIFESTS_DIR, OVERLAYS_DIR, +}; use crate::migration::world::WorldDiff; #[tokio::test] diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index d3aa32877a..b0ba4f8010 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -39,6 +39,15 @@ pub const BASE_CONTRACT_NAME: &str = "dojo::base::base"; pub const RESOURCE_METADATA_CONTRACT_NAME: &str = "dojo::resource_metadata::resource_metadata"; pub const RESOURCE_METADATA_MODEL_NAME: &str = "0x5265736f757263654d65746164617461"; +pub const MANIFESTS_DIR: &str = "manifests"; +pub const BASE_DIR: &str = "base"; +pub const OVERLAYS_DIR: &str = "overlays"; +pub const DEPLOYMENTS_DIR: &str = "deployments"; +pub const ABIS_DIR: &str = "abis"; + +pub const CONTRACTS_DIR: &str = "contracts"; +pub const MODELS_DIR: &str = "models"; + #[derive(Error, Debug)] pub enum AbstractManifestError { #[error("Remote World not found.")] @@ -56,7 +65,9 @@ pub enum AbstractManifestError { #[error(transparent)] Model(#[from] ModelError), #[error(transparent)] - TOML(#[from] toml::de::Error), + TomlDe(#[from] toml::de::Error), + #[error(transparent)] + TomlSer(#[from] toml::ser::Error), #[error(transparent)] IO(#[from] io::Error), #[error("Abi couldn't be loaded from path: {0}")] @@ -93,8 +104,8 @@ impl From for DeploymentManifest { impl BaseManifest { /// Load the manifest from a file at the given path. pub fn load_from_path(path: &Utf8PathBuf) -> Result { - let contract_dir = path.join("contracts"); - let model_dir = path.join("models"); + let contract_dir = path.join(CONTRACTS_DIR); + let model_dir = path.join(MODELS_DIR); let world: Manifest = toml::from_str(&fs::read_to_string( path.join(WORLD_CONTRACT_NAME.replace("::", "_")).with_extension("toml"), @@ -151,7 +162,7 @@ impl OverlayManifest { base = Some(toml::from_str(&fs::read_to_string(base_path)?)?); } - let contract_dir = path.join("contracts"); + let contract_dir = path.join(CONTRACTS_DIR); let contracts = if contract_dir.exists() { overlay_elements_from_path::(&contract_dir)? @@ -161,6 +172,44 @@ impl OverlayManifest { Ok(Self { world, base, contracts }) } + + pub fn write_to_path_nested(&self, path: &Utf8PathBuf) -> Result<(), AbstractManifestError> { + fs::create_dir_all(path.parent().unwrap())?; + + if let Some(ref world) = self.world { + let world = toml::to_string(world)?; + let file_name = + path.join(WORLD_CONTRACT_NAME.replace("::", "_")).with_extension("toml"); + fs::write(file_name, world)?; + } + + if let Some(ref base) = self.base { + let base = toml::to_string(base)?; + let file_name = path.join(BASE_CONTRACT_NAME.replace("::", "_")).with_extension("toml"); + fs::write(file_name, base)?; + } + + overlay_dojo_contracts_to_path(&path.join(CONTRACTS_DIR), self.contracts.as_slice())?; + // overlay_elements_to_path(&path.join(MODELS_DIR), self.models.as_slice())?; + Ok(()) + } + + pub fn merge(&mut self, other: OverlayManifest) { + if self.world.is_none() { + self.world = other.world; + } + + if self.base.is_none() { + self.base = other.base; + } + + for other_contract in other.contracts { + let found = self.contracts.iter().find(|c| c.name == other_contract.name); + if found.is_none() { + self.contracts.push(other_contract); + } + } + } } impl DeploymentManifest { @@ -485,20 +534,6 @@ fn parse_models_events(events: Vec) -> Vec> { .collect() } -// fn elements_to_path(item_dir: &Utf8PathBuf, items: &Vec>) -> Result<()> -// where -// T: Serialize + ManifestMethods, -// { -// fs::create_dir_all(item_dir)?; -// for item in items { -// let item_toml = toml::to_string_pretty(&item)?; -// let item_name = item.name.split("::").last().unwrap(); -// fs::write(item_dir.join(item_name).with_extension("toml"), item_toml)?; -// } - -// Ok(()) -// } - fn elements_from_path(path: &Utf8PathBuf) -> Result>, AbstractManifestError> where T: DeserializeOwned + ManifestMethods, @@ -546,6 +581,19 @@ where Ok(elements) } +fn overlay_dojo_contracts_to_path( + path: &Utf8PathBuf, + elements: &[OverlayDojoContract], +) -> Result<(), AbstractManifestError> { + fs::create_dir_all(path.parent().unwrap())?; + + for element in elements { + let path = path.join(element.name.replace("::", "_")).with_extension("toml"); + fs::write(path, toml::to_string(&element)?)?; + } + Ok(()) +} + impl ManifestMethods for DojoContract { type OverlayType = OverlayDojoContract; diff --git a/crates/sozo/ops/Cargo.toml b/crates/sozo/ops/Cargo.toml index e4eded4705..f4144ae66b 100644 --- a/crates/sozo/ops/Cargo.toml +++ b/crates/sozo/ops/Cargo.toml @@ -50,6 +50,7 @@ tokio.workspace = true tracing-log = "0.1.3" tracing.workspace = true url.workspace = true +toml.workspace = true [dev-dependencies] assert_fs.workspace = true diff --git a/crates/sozo/ops/src/events.rs b/crates/sozo/ops/src/events.rs index c524fc2e96..73ae19d7fa 100644 --- a/crates/sozo/ops/src/events.rs +++ b/crates/sozo/ops/src/events.rs @@ -5,8 +5,7 @@ use anyhow::{anyhow, Result}; use cainome::parser::tokens::{CompositeInner, CompositeInnerKind, CoreBasic, Token}; use cainome::parser::AbiParser; use camino::Utf8PathBuf; -use dojo_lang::compiler::MANIFESTS_DIR; -use dojo_world::manifest::{AbiFormat, DeploymentManifest, ManifestMethods}; +use dojo_world::manifest::{AbiFormat, DeploymentManifest, ManifestMethods, MANIFESTS_DIR}; use starknet::core::types::{BlockId, EventFilter, FieldElement}; use starknet::core::utils::{parse_cairo_short_string, starknet_keccak}; use starknet::providers::jsonrpc::HttpTransport; @@ -249,8 +248,7 @@ fn process_inners( mod tests { use cainome::parser::tokens::{Array, Composite, CompositeInner, CompositeType}; use camino::Utf8Path; - use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR}; - use dojo_world::manifest::BaseManifest; + use dojo_world::manifest::{BaseManifest, BASE_DIR}; use starknet::core::types::EmittedEvent; use super::*; diff --git a/crates/sozo/ops/src/migration/migrate.rs b/crates/sozo/ops/src/migration/migrate.rs index 044479a5d6..50c2575484 100644 --- a/crates/sozo/ops/src/migration/migrate.rs +++ b/crates/sozo/ops/src/migration/migrate.rs @@ -2,12 +2,12 @@ use std::path::Path; use anyhow::{anyhow, bail, Context, Result}; use camino::Utf8PathBuf; -use dojo_lang::compiler::{ABIS_DIR, BASE_DIR, DEPLOYMENTS_DIR, MANIFESTS_DIR}; use dojo_world::contracts::abi::world; use dojo_world::contracts::{cairo_utils, WorldContract}; use dojo_world::manifest::{ AbiFormat, BaseManifest, DeploymentManifest, DojoContract, DojoModel, Manifest, - ManifestMethods, WorldContract as ManifestWorldContract, WorldMetadata, + ManifestMethods, WorldContract as ManifestWorldContract, WorldMetadata, ABIS_DIR, BASE_DIR, + DEPLOYMENTS_DIR, MANIFESTS_DIR, }; use dojo_world::metadata::{dojo_metadata_from_workspace, ArtifactMetadata}; use dojo_world::migration::class::ClassMigration; diff --git a/crates/sozo/ops/src/migration/mod.rs b/crates/sozo/ops/src/migration/mod.rs index 85f58dfa44..89145f787b 100644 --- a/crates/sozo/ops/src/migration/mod.rs +++ b/crates/sozo/ops/src/migration/mod.rs @@ -1,8 +1,13 @@ use std::sync::Arc; +use std::{fs, io}; -use anyhow::{anyhow, Result}; -use dojo_lang::compiler::MANIFESTS_DIR; +use anyhow::{anyhow, Context, Result}; +use camino::Utf8PathBuf; use dojo_world::contracts::WorldContract; +use dojo_world::manifest::{ + DojoContract, Manifest, OverlayClass, OverlayDojoContract, OverlayManifest, BASE_CONTRACT_NAME, + BASE_DIR, CONTRACTS_DIR, MANIFESTS_DIR, OVERLAYS_DIR, WORLD_CONTRACT_NAME, +}; use dojo_world::migration::world::WorldDiff; use dojo_world::migration::{DeployOutput, TxnConfig, UpgradeOutput}; use scarb::core::Workspace; @@ -174,3 +179,88 @@ enum ContractDeploymentOutput { enum ContractUpgradeOutput { Output(UpgradeOutput), } + +pub fn generate_overlays(ws: &Workspace<'_>) -> Result<()> { + let profile_name = + ws.current_profile().expect("Scarb profile expected to be defined.").to_string(); + + // its path to a file so `parent` should never return `None` + let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf(); + let profile_dir = manifest_dir.join(MANIFESTS_DIR).join(profile_name); + + let base_manifests = profile_dir.join(BASE_DIR); + + let world = OverlayClass { name: WORLD_CONTRACT_NAME.into(), original_class_hash: None }; + let base = OverlayClass { name: BASE_CONTRACT_NAME.into(), original_class_hash: None }; + + let contracts = overlay_dojo_contracts_from_path(&base_manifests.join(CONTRACTS_DIR)) + .with_context(|| "Failed to build default DojoContract Overlays from path.")?; + // let models = overlay_model_from_path(&base_manifests.join(MODELS_DIR))?; + + let default_overlay = OverlayManifest { world: Some(world), base: Some(base), contracts }; + + let overlay_path = profile_dir.join(OVERLAYS_DIR); + let mut overlay_manifest = OverlayManifest::load_from_path(&overlay_path) + .with_context(|| "Failed to load OverlayManifest from path.")?; + overlay_manifest.merge(default_overlay); + + overlay_manifest + .write_to_path_nested(&overlay_path) + .with_context(|| "Failed to write OverlayManifest to path.")?; + Ok(()) +} + +fn overlay_dojo_contracts_from_path(path: &Utf8PathBuf) -> Result> { + let mut elements = vec![]; + + let entries = path + .read_dir()? + .map(|entry| entry.map(|e| e.path())) + .collect::, io::Error>>()?; + + for path in entries { + if path.is_file() { + let manifest: Manifest = toml::from_str(&fs::read_to_string(path)?)?; + + let overlay_manifest = OverlayDojoContract { + name: manifest.name, + original_class_hash: None, + reads: None, + writes: None, + init_calldata: None, + }; + elements.push(overlay_manifest); + } else { + continue; + } + } + + Ok(elements) +} + +// fn overlay_model_from_path(path: &Utf8PathBuf) -> Result> { +// let mut elements = vec![]; + +// let mut entries = path +// .read_dir()? +// .map(|entry| entry.map(|e| e.path())) +// .collect::, io::Error>>()?; + +// // `read_dir` doesn't guarantee any order, so we sort the entries ourself. +// // see: https://doc.rust-lang.org/std/fs/fn.read_dir.html#platform-specific-behavior +// entries.sort(); + +// for path in entries { +// if path.is_file() { +// let manifest: Manifest = toml::from_str(&fs::read_to_string(path)?)?; + +// let overlay_manifest = +// OverlayDojoModel { name: manifest.name, original_class_hash: None }; +// elements.push(overlay_manifest); +// } else { +// continue; +// } +// } + +// Ok(elements) +// } diff --git a/crates/sozo/ops/src/migration/utils.rs b/crates/sozo/ops/src/migration/utils.rs index d21e7c4c29..d85ffb6df8 100644 --- a/crates/sozo/ops/src/migration/utils.rs +++ b/crates/sozo/ops/src/migration/utils.rs @@ -1,8 +1,8 @@ use anyhow::{anyhow, Result}; use camino::Utf8PathBuf; -use dojo_lang::compiler::{BASE_DIR, OVERLAYS_DIR}; use dojo_world::manifest::{ - AbstractManifestError, BaseManifest, DeploymentManifest, OverlayManifest, + AbstractManifestError, BaseManifest, DeploymentManifest, OverlayManifest, BASE_DIR, + OVERLAYS_DIR, }; use scarb_ui::Ui; use starknet::accounts::{ConnectedAccount, SingleOwnerAccount}; diff --git a/crates/sozo/ops/src/tests/migration.rs b/crates/sozo/ops/src/tests/migration.rs index 708724a4c8..b8977423f7 100644 --- a/crates/sozo/ops/src/tests/migration.rs +++ b/crates/sozo/ops/src/tests/migration.rs @@ -2,11 +2,11 @@ use std::str; use cainome::cairo_serde::ContractAddress; use camino::Utf8Path; -use dojo_lang::compiler::{BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use dojo_test_utils::migration::prepare_migration_with_world_and_seed; use dojo_world::contracts::{WorldContract, WorldContractReader}; use dojo_world::manifest::{ - BaseManifest, DeploymentManifest, OverlayManifest, WORLD_CONTRACT_NAME, + BaseManifest, DeploymentManifest, OverlayManifest, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR, + WORLD_CONTRACT_NAME, }; use dojo_world::metadata::{ dojo_metadata_from_workspace, ArtifactMetadata, DojoMetadata, Uri, WorldMetadata, diff --git a/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_actions_actions.toml b/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_actions_actions.toml index a8e2fd4c2d..b21fc1adec 100644 --- a/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_actions_actions.toml +++ b/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_actions_actions.toml @@ -1,6 +1,4 @@ -computed = [ ] name = "dojo_examples::actions::actions" -reads = [ ] -writes = [ "Moves", "Position" ] +reads = [] +writes = ["Moves", "Position"] init_calldata = [] - diff --git a/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_others_others.toml b/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_others_others.toml index b74df0c8fe..129f942bd8 100644 --- a/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_others_others.toml +++ b/examples/spawn-and-move/manifests/dev/overlays/contracts/dojo_examples_others_others.toml @@ -1,5 +1,4 @@ +name = "dojo_examples::others::others" reads = [] writes = [] -computed = [] init_calldata = ["$contract_address:dojo_examples::actions::actions", "$class_hash:dojo_examples::actions::actions", "10"] -name = "dojo_examples::others::others" diff --git a/examples/spawn-and-move/manifests/dev/overlays/dojo_base_base.toml b/examples/spawn-and-move/manifests/dev/overlays/dojo_base_base.toml new file mode 100644 index 0000000000..f706470d45 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/dojo_base_base.toml @@ -0,0 +1 @@ +name = "dojo::base::base" diff --git a/examples/spawn-and-move/manifests/dev/overlays/dojo_world_world.toml b/examples/spawn-and-move/manifests/dev/overlays/dojo_world_world.toml new file mode 100644 index 0000000000..a3e686e3ef --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/dojo_world_world.toml @@ -0,0 +1 @@ +name = "dojo::world::world" From 0cdd60207cc8cdfdaf107ce0a8acc12635068a42 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Sun, 2 Jun 2024 12:18:07 +0530 Subject: [PATCH 2/7] add support for model overlays --- crates/dojo-world/src/manifest/mod.rs | 34 +++++++++-- crates/dojo-world/src/manifest/types.rs | 1 + crates/sozo/ops/src/migration/mod.rs | 61 +++++++++---------- .../dojo_examples_actions_actions_moved.toml | 1 + .../dojo_examples_models_emote_message.toml | 1 + .../models/dojo_examples_models_moves.toml | 1 + .../dojo_examples_models_player_config.toml | 1 + .../models/dojo_examples_models_position.toml | 1 + ...es_others_others_contract_initialized.toml | 1 + 9 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_actions_actions_moved.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_emote_message.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_moves.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_player_config.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_position.toml create mode 100644 examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_others_others_contract_initialized.toml diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index b0ba4f8010..7ab2994d97 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -163,14 +163,20 @@ impl OverlayManifest { } let contract_dir = path.join(CONTRACTS_DIR); - let contracts = if contract_dir.exists() { overlay_elements_from_path::(&contract_dir)? } else { vec![] }; - Ok(Self { world, base, contracts }) + let model_dir = path.join(MODELS_DIR); + let models = if model_dir.exists() { + overlay_elements_from_path::(&model_dir)? + } else { + vec![] + }; + + Ok(Self { world, base, contracts, models }) } pub fn write_to_path_nested(&self, path: &Utf8PathBuf) -> Result<(), AbstractManifestError> { @@ -190,7 +196,7 @@ impl OverlayManifest { } overlay_dojo_contracts_to_path(&path.join(CONTRACTS_DIR), self.contracts.as_slice())?; - // overlay_elements_to_path(&path.join(MODELS_DIR), self.models.as_slice())?; + overlay_dojo_model_to_path(&path.join(MODELS_DIR), self.models.as_slice())?; Ok(()) } @@ -209,6 +215,13 @@ impl OverlayManifest { self.contracts.push(other_contract); } } + + for other_model in other.models { + let found = self.models.iter().find(|m| m.name == other_model.name); + if found.is_none() { + self.models.push(other_model); + } + } } } @@ -585,7 +598,20 @@ fn overlay_dojo_contracts_to_path( path: &Utf8PathBuf, elements: &[OverlayDojoContract], ) -> Result<(), AbstractManifestError> { - fs::create_dir_all(path.parent().unwrap())?; + fs::create_dir_all(path)?; + + for element in elements { + let path = path.join(element.name.replace("::", "_")).with_extension("toml"); + fs::write(path, toml::to_string(&element)?)?; + } + Ok(()) +} + +fn overlay_dojo_model_to_path( + path: &Utf8PathBuf, + elements: &[OverlayDojoModel], +) -> Result<(), AbstractManifestError> { + fs::create_dir_all(path)?; for element in elements { let path = path.join(element.name.replace("::", "_")).with_extension("toml"); diff --git a/crates/dojo-world/src/manifest/types.rs b/crates/dojo-world/src/manifest/types.rs index dbbee2fd58..9147fde63e 100644 --- a/crates/dojo-world/src/manifest/types.rs +++ b/crates/dojo-world/src/manifest/types.rs @@ -42,6 +42,7 @@ pub struct OverlayManifest { pub world: Option, pub base: Option, pub contracts: Vec, + pub models: Vec, } #[derive(Clone, Serialize, Deserialize, Debug)] diff --git a/crates/sozo/ops/src/migration/mod.rs b/crates/sozo/ops/src/migration/mod.rs index 89145f787b..8919d82fae 100644 --- a/crates/sozo/ops/src/migration/mod.rs +++ b/crates/sozo/ops/src/migration/mod.rs @@ -5,8 +5,9 @@ use anyhow::{anyhow, Context, Result}; use camino::Utf8PathBuf; use dojo_world::contracts::WorldContract; use dojo_world::manifest::{ - DojoContract, Manifest, OverlayClass, OverlayDojoContract, OverlayManifest, BASE_CONTRACT_NAME, - BASE_DIR, CONTRACTS_DIR, MANIFESTS_DIR, OVERLAYS_DIR, WORLD_CONTRACT_NAME, + DojoContract, DojoModel, Manifest, OverlayClass, OverlayDojoContract, OverlayDojoModel, + OverlayManifest, BASE_CONTRACT_NAME, BASE_DIR, CONTRACTS_DIR, MANIFESTS_DIR, MODELS_DIR, + OVERLAYS_DIR, WORLD_CONTRACT_NAME, }; use dojo_world::migration::world::WorldDiff; use dojo_world::migration::{DeployOutput, TxnConfig, UpgradeOutput}; @@ -195,18 +196,22 @@ pub fn generate_overlays(ws: &Workspace<'_>) -> Result<()> { let contracts = overlay_dojo_contracts_from_path(&base_manifests.join(CONTRACTS_DIR)) .with_context(|| "Failed to build default DojoContract Overlays from path.")?; - // let models = overlay_model_from_path(&base_manifests.join(MODELS_DIR))?; + let models = overlay_model_from_path(&base_manifests.join(MODELS_DIR)) + .with_context(|| "Failed to build default DojoModel Overlays from path.")?; - let default_overlay = OverlayManifest { world: Some(world), base: Some(base), contracts }; + let default_overlay = + OverlayManifest { world: Some(world), base: Some(base), contracts, models }; let overlay_path = profile_dir.join(OVERLAYS_DIR); let mut overlay_manifest = OverlayManifest::load_from_path(&overlay_path) .with_context(|| "Failed to load OverlayManifest from path.")?; + overlay_manifest.merge(default_overlay); overlay_manifest .write_to_path_nested(&overlay_path) .with_context(|| "Failed to write OverlayManifest to path.")?; + Ok(()) } @@ -222,13 +227,8 @@ fn overlay_dojo_contracts_from_path(path: &Utf8PathBuf) -> Result = toml::from_str(&fs::read_to_string(path)?)?; - let overlay_manifest = OverlayDojoContract { - name: manifest.name, - original_class_hash: None, - reads: None, - writes: None, - init_calldata: None, - }; + let overlay_manifest = + OverlayDojoContract { name: manifest.name, ..Default::default() }; elements.push(overlay_manifest); } else { continue; @@ -238,29 +238,24 @@ fn overlay_dojo_contracts_from_path(path: &Utf8PathBuf) -> Result Result> { -// let mut elements = vec![]; - -// let mut entries = path -// .read_dir()? -// .map(|entry| entry.map(|e| e.path())) -// .collect::, io::Error>>()?; +fn overlay_model_from_path(path: &Utf8PathBuf) -> Result> { + let mut elements = vec![]; -// // `read_dir` doesn't guarantee any order, so we sort the entries ourself. -// // see: https://doc.rust-lang.org/std/fs/fn.read_dir.html#platform-specific-behavior -// entries.sort(); + let entries = path + .read_dir()? + .map(|entry| entry.map(|e| e.path())) + .collect::, io::Error>>()?; -// for path in entries { -// if path.is_file() { -// let manifest: Manifest = toml::from_str(&fs::read_to_string(path)?)?; + for path in entries { + if path.is_file() { + let manifest: Manifest = toml::from_str(&fs::read_to_string(path)?)?; -// let overlay_manifest = -// OverlayDojoModel { name: manifest.name, original_class_hash: None }; -// elements.push(overlay_manifest); -// } else { -// continue; -// } -// } + let overlay_manifest = OverlayDojoModel { name: manifest.name, ..Default::default() }; + elements.push(overlay_manifest); + } else { + continue; + } + } -// Ok(elements) -// } + Ok(elements) +} diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_actions_actions_moved.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_actions_actions_moved.toml new file mode 100644 index 0000000000..4958a7a15c --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_actions_actions_moved.toml @@ -0,0 +1 @@ +name = "dojo_examples::actions::actions::moved" diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_emote_message.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_emote_message.toml new file mode 100644 index 0000000000..d60162cc72 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_emote_message.toml @@ -0,0 +1 @@ +name = "dojo_examples::models::emote_message" diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_moves.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_moves.toml new file mode 100644 index 0000000000..dc8784e746 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_moves.toml @@ -0,0 +1 @@ +name = "dojo_examples::models::moves" diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_player_config.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_player_config.toml new file mode 100644 index 0000000000..6af8240b36 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_player_config.toml @@ -0,0 +1 @@ +name = "dojo_examples::models::player_config" diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_position.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_position.toml new file mode 100644 index 0000000000..df38e71c32 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_models_position.toml @@ -0,0 +1 @@ +name = "dojo_examples::models::position" diff --git a/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_others_others_contract_initialized.toml b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_others_others_contract_initialized.toml new file mode 100644 index 0000000000..f8f3053fe5 --- /dev/null +++ b/examples/spawn-and-move/manifests/dev/overlays/models/dojo_examples_others_others_contract_initialized.toml @@ -0,0 +1 @@ +name = "dojo_examples::others::others::contract_initialized" From a5f7231a8e7ec6cc2579ccaf1f31ad5cb78c711f Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Mon, 3 Jun 2024 16:15:10 +0530 Subject: [PATCH 3/7] clean up --- bin/sozo/src/commands/migrate.rs | 1 - crates/dojo-world/src/manifest/mod.rs | 5 +++++ crates/sozo/ops/src/migration/mod.rs | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index 7823ccf8bc..06556f1541 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -50,7 +50,6 @@ pub enum MigrateCommand { #[command(flatten)] transaction: TransactionOptions, }, - #[command(about = "Generate overlays file.")] GenerateOverlays, } diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index 7ab2994d97..d63900d6ff 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -179,6 +179,10 @@ impl OverlayManifest { Ok(Self { world, base, contracts, models }) } + /// Writes `Self` to overlay manifests folder. + /// + /// - `world` and `base` manifest are written to root of the folder. + /// - `contracts` and `models` are written to their respective directories. pub fn write_to_path_nested(&self, path: &Utf8PathBuf) -> Result<(), AbstractManifestError> { fs::create_dir_all(path.parent().unwrap())?; @@ -200,6 +204,7 @@ impl OverlayManifest { Ok(()) } + /// Add missing overlay items from `others` to `self`. pub fn merge(&mut self, other: OverlayManifest) { if self.world.is_none() { self.world = other.world; diff --git a/crates/sozo/ops/src/migration/mod.rs b/crates/sozo/ops/src/migration/mod.rs index 8919d82fae..d7d45d4c49 100644 --- a/crates/sozo/ops/src/migration/mod.rs +++ b/crates/sozo/ops/src/migration/mod.rs @@ -194,6 +194,7 @@ pub fn generate_overlays(ws: &Workspace<'_>) -> Result<()> { let world = OverlayClass { name: WORLD_CONTRACT_NAME.into(), original_class_hash: None }; let base = OverlayClass { name: BASE_CONTRACT_NAME.into(), original_class_hash: None }; + // generate default OverlayManifest from base manifests let contracts = overlay_dojo_contracts_from_path(&base_manifests.join(CONTRACTS_DIR)) .with_context(|| "Failed to build default DojoContract Overlays from path.")?; let models = overlay_model_from_path(&base_manifests.join(MODELS_DIR)) @@ -203,9 +204,13 @@ pub fn generate_overlays(ws: &Workspace<'_>) -> Result<()> { OverlayManifest { world: Some(world), base: Some(base), contracts, models }; let overlay_path = profile_dir.join(OVERLAYS_DIR); + + // read existing OverlayManifest from path let mut overlay_manifest = OverlayManifest::load_from_path(&overlay_path) .with_context(|| "Failed to load OverlayManifest from path.")?; + // merge them to get OverlayManifest which contains all the contracts and models from base + // manifests overlay_manifest.merge(default_overlay); overlay_manifest From 5a142912bc91df65fba7bd32e02eea71751025b5 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Wed, 5 Jun 2024 18:27:32 +0530 Subject: [PATCH 4/7] add test for merge --- .../dojo-world/src/manifest/manifest_test.rs | 172 +++++++++++++++++- crates/dojo-world/src/manifest/mod.rs | 1 + crates/dojo-world/src/manifest/types.rs | 2 +- 3 files changed, 171 insertions(+), 4 deletions(-) diff --git a/crates/dojo-world/src/manifest/manifest_test.rs b/crates/dojo-world/src/manifest/manifest_test.rs index 279f538d52..a003fc0e23 100644 --- a/crates/dojo-world/src/manifest/manifest_test.rs +++ b/crates/dojo-world/src/manifest/manifest_test.rs @@ -13,12 +13,13 @@ use starknet::macros::{felt, selector}; use starknet::providers::jsonrpc::{JsonRpcClient, JsonRpcMethod}; use super::{ - parse_contracts_events, AbiFormat, BaseManifest, DojoContract, DojoModel, OverlayManifest, + parse_contracts_events, AbiFormat, BaseManifest, DojoContract, DojoModel, OverlayDojoContract, + OverlayManifest, }; use crate::contracts::world::test::deploy_world; use crate::manifest::{ - parse_models_events, AbstractManifestError, DeploymentManifest, Manifest, BASE_DIR, - MANIFESTS_DIR, OVERLAYS_DIR, + parse_models_events, AbstractManifestError, DeploymentManifest, Manifest, OverlayClass, + OverlayDojoModel, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR, }; use crate::migration::world::WorldDiff; @@ -475,3 +476,168 @@ fn test_abi_format_load_abi_string() -> Result<(), Box> { Ok(()) } + +#[test] +fn overlay_merge_for_contract_and_model_work_as_expected() { + let other = OverlayManifest { + contracts: vec![ + OverlayDojoContract { name: "othercontract1".into(), ..Default::default() }, + OverlayDojoContract { name: "othercontract2".into(), ..Default::default() }, + OverlayDojoContract { name: "existingcontract".into(), ..Default::default() }, + ], + models: vec![ + OverlayDojoModel { name: "othermodel1".into(), ..Default::default() }, + OverlayDojoModel { name: "othermodel2".into(), ..Default::default() }, + OverlayDojoModel { name: "existingmodel".into(), ..Default::default() }, + ], + ..Default::default() + }; + + let mut current = OverlayManifest { + contracts: vec![ + OverlayDojoContract { name: "currentcontract1".into(), ..Default::default() }, + OverlayDojoContract { name: "currentcontract2".into(), ..Default::default() }, + OverlayDojoContract { name: "existingcontract".into(), ..Default::default() }, + ], + models: vec![ + OverlayDojoModel { name: "currentmodel1".into(), ..Default::default() }, + OverlayDojoModel { name: "currentmodel2".into(), ..Default::default() }, + OverlayDojoModel { name: "existingmodel".into(), ..Default::default() }, + ], + ..Default::default() + }; + + let expected = OverlayManifest { + contracts: vec![ + OverlayDojoContract { name: "currentcontract1".into(), ..Default::default() }, + OverlayDojoContract { name: "currentcontract2".into(), ..Default::default() }, + OverlayDojoContract { name: "existingcontract".into(), ..Default::default() }, + OverlayDojoContract { name: "othercontract1".into(), ..Default::default() }, + OverlayDojoContract { name: "othercontract2".into(), ..Default::default() }, + ], + models: vec![ + OverlayDojoModel { name: "currentmodel1".into(), ..Default::default() }, + OverlayDojoModel { name: "currentmodel2".into(), ..Default::default() }, + OverlayDojoModel { name: "existingmodel".into(), ..Default::default() }, + OverlayDojoModel { name: "othermodel1".into(), ..Default::default() }, + OverlayDojoModel { name: "othermodel2".into(), ..Default::default() }, + ], + ..Default::default() + }; + + current.merge(other); + + assert_eq!(current, expected); +} + +#[test] +fn overlay_merge_for_world_work_as_expected() { + // when other.world is none and current.world is some + let other = OverlayManifest { ..Default::default() }; + let mut current = OverlayManifest { + world: Some(OverlayClass { name: "world".into(), ..Default::default() }), + ..Default::default() + }; + let expected = OverlayManifest { + world: Some(OverlayClass { name: "world".into(), ..Default::default() }), + ..Default::default() + }; + current.merge(other); + + assert_eq!(current, expected); + + // when other.world is some and current.world is none + let other = OverlayManifest { + world: Some(OverlayClass { name: "world".into(), ..Default::default() }), + ..Default::default() + }; + let mut current = OverlayManifest { ..Default::default() }; + let expected = OverlayManifest { + world: Some(OverlayClass { name: "world".into(), ..Default::default() }), + ..Default::default() + }; + + current.merge(other); + assert_eq!(current, expected); + + // when other.world is some and current.world is some + let other = OverlayManifest { + world: Some(OverlayClass { name: "worldother".into(), ..Default::default() }), + ..Default::default() + }; + let mut current = OverlayManifest { + world: Some(OverlayClass { name: "worldcurrent".into(), ..Default::default() }), + ..Default::default() + }; + let expected = OverlayManifest { + world: Some(OverlayClass { name: "worldcurrent".into(), ..Default::default() }), + ..Default::default() + }; + + current.merge(other); + assert_eq!(current, expected); + + // when other.world is none and current.world is none + let other = OverlayManifest { ..Default::default() }; + let mut current = OverlayManifest { ..Default::default() }; + let expected = OverlayManifest { ..Default::default() }; + + current.merge(other); + assert_eq!(current, expected); +} + +#[test] +fn overlay_merge_for_base_work_as_expected() { + // when other.base is none and current.base is some + let other = OverlayManifest { ..Default::default() }; + let mut current = OverlayManifest { + base: Some(OverlayClass { name: "base".into(), ..Default::default() }), + ..Default::default() + }; + let expected = OverlayManifest { + base: Some(OverlayClass { name: "base".into(), ..Default::default() }), + ..Default::default() + }; + current.merge(other); + + assert_eq!(current, expected); + + // when other.base is some and current.base is none + let other = OverlayManifest { + base: Some(OverlayClass { name: "base".into(), ..Default::default() }), + ..Default::default() + }; + let mut current = OverlayManifest { ..Default::default() }; + let expected = OverlayManifest { + base: Some(OverlayClass { name: "base".into(), ..Default::default() }), + ..Default::default() + }; + + current.merge(other); + assert_eq!(current, expected); + + // when other.base is some and current.base is some + let other = OverlayManifest { + base: Some(OverlayClass { name: "baseother".into(), ..Default::default() }), + ..Default::default() + }; + let mut current = OverlayManifest { + base: Some(OverlayClass { name: "basecurrent".into(), ..Default::default() }), + ..Default::default() + }; + let expected = OverlayManifest { + base: Some(OverlayClass { name: "basecurrent".into(), ..Default::default() }), + ..Default::default() + }; + + current.merge(other); + assert_eq!(current, expected); + + // when other.base is none and current.base is none + let other = OverlayManifest { ..Default::default() }; + let mut current = OverlayManifest { ..Default::default() }; + let expected = OverlayManifest { ..Default::default() }; + + current.merge(other); + assert_eq!(current, expected); +} diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index d63900d6ff..1307885f70 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -205,6 +205,7 @@ impl OverlayManifest { } /// Add missing overlay items from `others` to `self`. + /// Note that this method don't override if certain item already exists in `self`. pub fn merge(&mut self, other: OverlayManifest) { if self.world.is_none() { self.world = other.world; diff --git a/crates/dojo-world/src/manifest/types.rs b/crates/dojo-world/src/manifest/types.rs index 9147fde63e..5eb3e67d0c 100644 --- a/crates/dojo-world/src/manifest/types.rs +++ b/crates/dojo-world/src/manifest/types.rs @@ -36,7 +36,7 @@ pub struct DeploymentManifest { pub models: Vec>, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Serialize, Deserialize)] #[cfg_attr(test, derive(PartialEq))] pub struct OverlayManifest { pub world: Option, From e5f25cd437ca6015cda6ed5fc4580667049d0236 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Sat, 8 Jun 2024 13:46:46 +0530 Subject: [PATCH 5/7] separate out match statement --- bin/sozo/src/commands/migrate.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index 06556f1541..f53182b9ae 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -59,6 +59,11 @@ impl MigrateArgs { trace!(args = ?self); let ws = scarb::ops::read_workspace(config.manifest_path(), config)?; + if let MigrateCommand::GenerateOverlays = self.command { + trace!("Planning migration."); + return migration::generate_overlays(&ws); + } + let env_metadata = if config.manifest_path().exists() { dojo_metadata_from_workspace(&ws).env().cloned() } else { @@ -102,10 +107,7 @@ impl MigrateArgs { migration::migrate(&ws, world_address, rpc_url, account, &name, false, txn_config) .await }), - MigrateCommand::GenerateOverlays => { - trace!(name, "Generating Overlay files."); - migration::generate_overlays(&ws) - } + _ => unreachable!("other case handled above."), } } } From d3464567d0459f103b158ed7e6e2f60df1477502 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Sat, 8 Jun 2024 15:00:11 +0530 Subject: [PATCH 6/7] fix directory creation --- crates/dojo-world/src/manifest/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index 1307885f70..5391761e49 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -147,6 +147,8 @@ impl BaseManifest { impl OverlayManifest { pub fn load_from_path(path: &Utf8PathBuf) -> Result { + fs::create_dir_all(path)?; + let mut world: Option = None; let world_path = path.join(WORLD_CONTRACT_NAME.replace("::", "_")).with_extension("toml"); @@ -184,7 +186,7 @@ impl OverlayManifest { /// - `world` and `base` manifest are written to root of the folder. /// - `contracts` and `models` are written to their respective directories. pub fn write_to_path_nested(&self, path: &Utf8PathBuf) -> Result<(), AbstractManifestError> { - fs::create_dir_all(path.parent().unwrap())?; + fs::create_dir_all(path)?; if let Some(ref world) = self.world { let world = toml::to_string(world)?; From a48a6ad1c68f2896e7438345df9352e623a0737a Mon Sep 17 00:00:00 2001 From: glihm Date: Mon, 10 Jun 2024 11:11:35 -0600 Subject: [PATCH 7/7] fix: fix test typo + add comment on isolated variant test --- bin/sozo/src/commands/migrate.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index f53182b9ae..3acb7f25cb 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -59,8 +59,10 @@ impl MigrateArgs { trace!(args = ?self); let ws = scarb::ops::read_workspace(config.manifest_path(), config)?; + // This variant is tested before the match on `self.command` to avoid + // having the need to spin up a Katana to generate the files. if let MigrateCommand::GenerateOverlays = self.command { - trace!("Planning migration."); + trace!("Generating overlays."); return migration::generate_overlays(&ws); }