Skip to content

Commit

Permalink
refactor: migrate to using toml manifest instead of json manifest (#1577
Browse files Browse the repository at this point in the history
)

* update manifest structs

* update compiler

* update sozo

* add base in abis directory

* fix world address

* use utf8pathbuf instead of string for cross-platform support

* copy abi files to deployments similar to manifests

* apply clippy lints

* finally!!!!! fixed all clippy lints

* make overlay fields optional and add an example overlay contract

* more test fixes

* fix rust formatting

* fix tests

* fix sozo events

* more fixing

* update events count

* write DeployedManifest to a single file

* fix torii test

* ignore test that breaking other test

* fix rust formatting

* remove abis for world, base, and DojoModels

* add nicer error message

* update events count after recent abis change

* fix lint

* update build for torii-types

* update overlays manifest
  • Loading branch information
lambda-0x authored Mar 5, 2024
1 parent 70c32b2 commit f90a71a
Show file tree
Hide file tree
Showing 39 changed files with 2,016 additions and 762 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 29 additions & 12 deletions bin/sozo/src/commands/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ 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::Manifest;
use dojo_world::manifest::{BaseManifest, DeployedManifest};
use dojo_world::metadata::dojo_metadata_from_workspace;
use dojo_world::migration::world::WorldDiff;
use notify_debouncer_mini::notify::RecursiveMode;
use notify_debouncer_mini::{new_debouncer, DebouncedEvent, DebouncedEventKind};
Expand Down Expand Up @@ -111,28 +113,34 @@ async fn migrate<P, S>(
account: &SingleOwnerAccount<P, S>,
name: Option<String>,
ws: &Workspace<'_>,
previous_manifest: Option<Manifest>,
) -> Result<(Manifest, Option<FieldElement>)>
previous_manifest: Option<DeployedManifest>,
) -> Result<(DeployedManifest, Option<FieldElement>)>
where
P: Provider + Sync + Send + 'static,
S: Signer + Sync + Send + 'static,
{
let target_dir = ws.target_dir().path_existent().unwrap();
let target_dir = target_dir.join(ws.config().profile().as_str());
let manifest_path = target_dir.join("manifest.json");
if !manifest_path.exists() {
return Err(anyhow!("manifest.json not found"));

// `parent` returns `None` only when its root path, so its safe to unwrap
let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf();

if !manifest_dir.join(MANIFESTS_DIR).exists() {
return Err(anyhow!("Build project using `sozo build` first"));
}
let new_manifest = Manifest::load_from_path(manifest_path)?;

let new_manifest =
BaseManifest::load_from_path(&manifest_dir.join(MANIFESTS_DIR).join(BASE_DIR))?;

let diff = WorldDiff::compute(new_manifest.clone(), previous_manifest);
let total_diffs = diff.count_diffs();
let config = ws.config();
config.ui().print(format!("Total diffs found: {total_diffs}"));
if total_diffs == 0 {
return Ok((new_manifest, world_address));
return Ok((new_manifest.into(), world_address));
}

match migration::apply_diff(ws, target_dir, diff, name.clone(), world_address, account, None)
match migration::apply_diff(ws, &target_dir, diff, name.clone(), world_address, account, None)
.await
{
Ok(address) => {
Expand All @@ -147,7 +155,7 @@ where
}
}

Ok((new_manifest, world_address))
Ok((new_manifest.into(), world_address))
}

fn process_event(event: &DebouncedEvent, context: &mut DevContext<'_>) -> DevAction {
Expand Down Expand Up @@ -183,6 +191,14 @@ fn handle_reload_action(context: &mut DevContext<'_>) {

impl DevArgs {
pub fn run(self, config: &Config) -> Result<()> {
let env_metadata = if config.manifest_path().exists() {
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;

dojo_metadata_from_workspace(&ws).and_then(|inner| inner.env().cloned())
} else {
None
};

let mut context = load_context(config)?;
let (tx, rx) = channel();
let mut debouncer = new_debouncer(Duration::from_secs(1), None, tx)?;
Expand All @@ -192,10 +208,10 @@ impl DevArgs {
RecursiveMode::Recursive,
)?;
let name = self.name.clone();
let mut previous_manifest: Option<Manifest> = Option::None;
let mut previous_manifest: Option<DeployedManifest> = Option::None;
let result = build(&mut context);

let Some((mut world_address, account)) = context
let Some((mut world_address, account, _)) = context
.ws
.config()
.tokio_handle()
Expand All @@ -205,6 +221,7 @@ impl DevArgs {
self.starknet,
self.world,
name.as_ref(),
env_metadata.as_ref(),
))
.ok()
else {
Expand Down
90 changes: 4 additions & 86 deletions bin/sozo/src/commands/events.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
use std::collections::HashMap;

use anyhow::{anyhow, Result};
use cairo_lang_starknet::abi::{self, Event, Item};
use anyhow::Result;
use clap::Parser;
use dojo_world::manifest::Manifest;
use dojo_world::metadata::dojo_metadata_from_workspace;
use scarb::core::Config;
use starknet::core::utils::starknet_keccak;

use super::options::starknet::StarknetOptions;
use super::options::world::WorldOptions;
Expand Down Expand Up @@ -47,93 +42,16 @@ pub struct EventsArgs {

impl EventsArgs {
pub fn run(self, config: &Config) -> Result<()> {
let event_map = if !self.json {
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;
let target_dir = ws.target_dir().path_existent()?;
let manifest_path = target_dir.join(config.profile().as_str()).join("manifest.json");

if !manifest_path.exists() {
return Err(anyhow!("Run scarb migrate before running this command"));
}

Some(extract_events(&Manifest::load_from_path(manifest_path)?))
} else {
None
};
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;

let env_metadata = if config.manifest_path().exists() {
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;

dojo_metadata_from_workspace(&ws).and_then(|inner| inner.env().cloned())
} else {
None
};

config.tokio_handle().block_on(events::execute(self, env_metadata, event_map))
}
}

fn extract_events(manifest: &Manifest) -> HashMap<String, Vec<Event>> {
fn inner_helper(events: &mut HashMap<String, Vec<Event>>, abi: abi::Contract) {
for item in abi.into_iter() {
if let Item::Event(e) = item {
match e.kind {
abi::EventKind::Struct { .. } => {
let event_name = starknet_keccak(
e.name
.split("::")
.last()
.expect("valid fully qualified name")
.as_bytes(),
);
let vec = events.entry(event_name.to_string()).or_default();
vec.push(e.clone());
}
abi::EventKind::Enum { .. } => (),
}
}
}
}

let mut events_map = HashMap::new();

if let Some(abi) = manifest.world.abi.clone() {
inner_helper(&mut events_map, abi);
}

for contract in &manifest.contracts {
if let Some(abi) = contract.abi.clone() {
inner_helper(&mut events_map, abi);
}
}

for model in &manifest.contracts {
if let Some(abi) = model.abi.clone() {
inner_helper(&mut events_map, abi);
}
}

events_map
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn events_are_parsed_correctly() {
let arg = EventsArgs::parse_from(["event", "Event1,Event2", "--chunk-size", "1"]);
assert!(arg.events.unwrap().len() == 2);
assert!(arg.from_block.is_none());
assert!(arg.to_block.is_none());
assert!(arg.chunk_size == 1);
}

#[test]
fn extract_events_work_as_expected() {
let manifest = Manifest::load_from_path("./tests/test_data/manifest.json").unwrap();
let result = extract_events(&manifest);
let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf();

// we are just collection all events from manifest file so just verifying count should work
assert!(result.len() == 13);
config.tokio_handle().block_on(events::execute(self, env_metadata, &manifest_dir))
}
}
25 changes: 13 additions & 12 deletions bin/sozo/src/commands/migrate.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use anyhow::Result;
use anyhow::{anyhow, Result};
use clap::Args;
use dojo_lang::scarb_internal::compile_workspace;
use scarb::core::{Config, TargetKind};
use scarb::ops::CompileOpts;
use dojo_lang::compiler::MANIFESTS_DIR;
use dojo_world::metadata::dojo_metadata_from_workspace;
use scarb::core::Config;

use super::options::account::AccountOptions;
use super::options::starknet::StarknetOptions;
Expand Down Expand Up @@ -46,17 +46,18 @@ impl MigrateArgs {
}
}

let target_dir = ws.target_dir().path_existent().unwrap();
let target_dir = target_dir.join(ws.config().profile().as_str());
let env_metadata = if config.manifest_path().exists() {
dojo_metadata_from_workspace(&ws).and_then(|inner| inner.env().cloned())
} else {
None
};

if !target_dir.join("manifest.json").exists() {
compile_workspace(
config,
CompileOpts { include_targets: vec![], exclude_targets: vec![TargetKind::TEST] },
)?;
let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf();
if !manifest_dir.join(MANIFESTS_DIR).exists() {
return Err(anyhow!("Build project using `sozo build` first"));
}

ws.config().tokio_handle().block_on(migration::execute(&ws, self, target_dir))?;
ws.config().tokio_handle().block_on(migration::execute(&ws, self, env_metadata))?;

Ok(())
}
Expand Down
Loading

0 comments on commit f90a71a

Please sign in to comment.