Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
glihm committed Jul 24, 2024
1 parent 04b6e7f commit 87b754b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 57 deletions.
41 changes: 4 additions & 37 deletions bin/sozo/src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use clap::{Args, Parser};
use dojo_bindgen::{BuiltinPlugins, PluginManager};
use dojo_lang::scarb_internal::compile_workspace;
use dojo_world::manifest::MANIFESTS_DIR;
use dojo_world::metadata::{dojo_metadata_from_package, dojo_metadata_from_workspace, DojoMetadata};
use dojo_world::metadata::{dojo_metadata_from_package, dojo_metadata_from_workspace};
use prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE;
use prettytable::{format, Cell, Row, Table};
use scarb::core::{Config, Package, TargetKind};
use scarb::ops::{package, CompileOpts};
use scarb::ops::CompileOpts;
use scarb_ui::args::{FeaturesSpec, PackagesFilter};
use sozo_ops::statistics::{get_contract_statistics_for_dir, ContractStatistics};
use tracing::trace;
Expand Down Expand Up @@ -63,46 +63,13 @@ impl BuildArgs {
let package = packages.iter().next().unwrap();
dojo_metadata_from_package(&package, &ws)?
} else {
trace!("Looking for Dojo metadata among packages.");
// Here, we should iterate and remove any package that is not dojo specific?
// Or take the metadata from the first dojo package. But only one package
// that is NOT LIB and has the dojo target.
// Check all workspace members for a package with dojo target and not lib target
let dojo_packages: Vec<Package> = ws.members().into_iter()
.filter(|package| {
package.target(&TargetKind::new("dojo")).is_some()
&& !package.target(&TargetKind::new("lib")).is_some()
})
.collect();

match dojo_packages.len() {
0 => {
// If libs, we don't care about the output. Usually, only the lib compilation and testing
// is required.
tracing::warn!("No package with dojo target (and not a lib) found in workspace.");
DojoMetadata::default()
}
1 => {
let dojo_package = dojo_packages.into_iter().next().expect("Package must exist as len is 1.");
dojo_metadata_from_package(&dojo_package, &ws)?
}
_ => {
return Err(anyhow::anyhow!("Multiple packages with dojo target found in workspace. Please specify a package using --package option."));
}
}
dojo_metadata_from_workspace(&ws)?
};

// Namespaces are required to compute contracts/models data. Hence, we can't continue
// if no metadata are found.
// Once sozo will support package option, users will be able to do `-p` to select
// the package directly from the workspace instead of using `--manifest-path`.
//let dojo_metadata = dojo_metadata_from_workspace(&ws)?;

let profile_name =
ws.current_profile().expect("Scarb profile is expected at this point.").to_string();

// Manifest path is always a file, we can unwrap safely to get the
// parent folder.
// Manifest path is always a file, we can unwrap safely to get the parent folder.
let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf();

let profile_dir = manifest_dir.join(MANIFESTS_DIR).join(profile_name);
Expand Down
5 changes: 4 additions & 1 deletion bin/sozo/src/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use scarb::compiler::helpers::collect_main_crate_ids;
use scarb::compiler::{CairoCompilationUnit, CompilationUnit, CompilationUnitAttributes};
use scarb::core::{Config, TargetKind};
use scarb::ops::{self, CompileOpts};
use scarb_ui::args::FeaturesSpec;
use scarb_ui::args::{FeaturesSpec, PackagesFilter};
use tracing::trace;

pub(crate) const LOG_TARGET: &str = "sozo::cli::commands::test";
Expand Down Expand Up @@ -62,6 +62,9 @@ pub struct TestArgs {
/// Specify the features to activate.
#[command(flatten)]
features: FeaturesSpec,
/// Specify packages to test.
#[command(flatten)]
pub packages: Option<PackagesFilter>,
}

impl TestArgs {
Expand Down
10 changes: 9 additions & 1 deletion crates/dojo-lang/src/scarb_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use cairo_lang_starknet::starknet_plugin_suite;
use cairo_lang_test_plugin::test_plugin_suite;
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use camino::Utf8PathBuf;
use regex::Regex;
use scarb::compiler::{CairoCompilationUnit, CompilationUnit, CompilationUnitAttributes};
use scarb::core::{Config, PackageId};
use scarb::ops::CompileOpts;
Expand Down Expand Up @@ -90,6 +91,7 @@ pub fn compile_workspace(
) -> Result<CompileInfo> {
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;
let resolve = scarb::ops::resolve_workspace(&ws)?;
let ui = config.ui();

let compilation_units = scarb::ops::generate_compilation_units(&resolve, &opts.features, &ws)?
.into_iter()
Expand All @@ -105,9 +107,15 @@ pub fn compile_workspace(
for unit in compilation_units {
trace!(target: LOG_TARGET, unit_name = %unit.name(), target_kind = %unit.main_component().target_kind(), "Compiling unit.");
if let CompilationUnit::Cairo(unit) = unit {
let unit_name = unit.name();
let re = Regex::new(r"\s*\([^()]*\)$").unwrap();
let unit_name_no_path = re.replace(&unit_name, "");

ui.print(format!("compiling {}", unit_name_no_path));
ui.verbose(format!("target kind: {}", unit.main_component().target_kind()));

let mut db = build_scarb_root_database(&unit).unwrap();
if let Err(err) = ws.config().compilers().compile(unit.clone(), &mut (db), &ws) {
println!("err");
ws.config().ui().anyhow(&err);
compile_error_units.push(unit.name());
}
Expand Down
16 changes: 8 additions & 8 deletions crates/dojo-lang/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use cairo_lang_syntax::node::db::SyntaxGroup;
use dojo_world::metadata::NamespaceConfig;
use regex::Regex;
use toml::Table;
use tracing::debug;

/// Check if the provided name follows the format rules.
pub fn is_name_valid(name: &str) -> bool {
Expand All @@ -17,18 +16,16 @@ pub fn is_name_valid(name: &str) -> bool {
// TODO: Ask to Scarb team to expose this information with the new macro system.
pub fn get_namespace_config(db: &dyn SyntaxGroup) -> Result<NamespaceConfig> {
// Super verbose print, but useful to get the CfgSet.
// debug!(cfg_set = ?db.cfg_set(), crates = ?db.crates(), "Retrieving namespace configuration.");
// debug!(cfg_set = ?db.cfg_set(), crates = ?db.crates(), "Retrieving namespace
// configuration.");

if !db.cfg_set().contains(&cairo_lang_filesystem::cfg::Cfg {
key: "target".into(),
value: Some("dojo".into()),
}) {
// When a [lib] is compiled without the target "dojo", we shouldn't care about
// the namespace being retrieved.
return Ok(NamespaceConfig {
default: "ignored_namespace".into(),
mappings: None,
});
return Ok(NamespaceConfig { default: "ignored_namespace".into(), mappings: None });
}

let crates = db.crates();
Expand All @@ -42,7 +39,9 @@ pub fn get_namespace_config(db: &dyn SyntaxGroup) -> Result<NamespaceConfig> {
// Crates[0] is always the root crate that triggered the build origin.
// In case of a library, crates[0] refers to the lib itself if compiled directly,
// or the crate using the library otherwise.
let configuration = match db.crate_config(*crates.first().expect("No root crate found in the workspace.")) {
let configuration = match db
.crate_config(*crates.first().expect("No root crate found in the workspace."))
{
Option::Some(cfg) => cfg,
Option::None => return Err(anyhow::anyhow!("No configuration found for the root crate.")),
};
Expand All @@ -51,7 +50,8 @@ pub fn get_namespace_config(db: &dyn SyntaxGroup) -> Result<NamespaceConfig> {
let config_path = path.parent().unwrap().join("Scarb.toml");

// Very verbose.
// tracing::debug!(config_path = %config_path.to_string_lossy(), "Reading Scarb.toml file for namespace config.");
// tracing::debug!(config_path = %config_path.to_string_lossy(), "Reading Scarb.toml file
// for namespace config.");

let config_content = match fs::read_to_string(&config_path) {
Ok(x) => x,
Expand Down
54 changes: 44 additions & 10 deletions crates/dojo-world/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ use anyhow::{anyhow, Context, Result};
use camino::Utf8PathBuf;
use ipfs_api_backend_hyper::{IpfsApi, IpfsClient, TryFromUri};
use regex::Regex;
use scarb::core::{ManifestMetadata, Package, PackageId, Workspace};
use scarb::core::{ManifestMetadata, Package, TargetKind, Workspace};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::json;
use url::Url;

use crate::contracts::naming;
use crate::manifest::{BaseManifest, CONTRACTS_DIR, MODELS_DIR, WORLD_CONTRACT_TAG};

const LOG_TARGET: &str = "dojo-world::metadata";

#[cfg(test)]
#[path = "metadata_test.rs"]
mod test;
Expand Down Expand Up @@ -97,13 +99,13 @@ pub fn project_to_world_metadata(m: ProjectWorldMetadata) -> WorldMetadata {
}

pub fn dojo_metadata_from_package(package: &Package, ws: &Workspace<'_>) -> Result<DojoMetadata> {
tracing::debug!(package_id = package.id.to_string(), "Collecting Dojo metadata from package.");
tracing::debug!(target: LOG_TARGET, package_id = package.id.to_string(), "Collecting Dojo metadata from package.");

let project_metadata = package
.manifest
.metadata
.dojo()
.with_context(|| format!("Error parsing manifest file `{}`", ws.manifest_path()))?;
.manifest
.metadata
.dojo()
.with_context(|| format!("Error parsing manifest file `{}`", ws.manifest_path()))?;

let dojo_metadata = DojoMetadata {
env: project_metadata.env.clone(),
Expand All @@ -112,19 +114,51 @@ pub fn dojo_metadata_from_package(package: &Package, ws: &Workspace<'_>) -> Resu
..Default::default()
};

tracing::trace!(?dojo_metadata);
tracing::trace!(target: LOG_TARGET, ?dojo_metadata);

Ok(dojo_metadata)
}

pub fn dojo_metadata_from_workspace(ws: &Workspace<'_>) -> Result<DojoMetadata> {
let dojo_packages: Vec<Package> = ws
.members()
.into_iter()
.filter(|package| {
package.target(&TargetKind::new("dojo")).is_some()
&& !package.target(&TargetKind::new("lib")).is_some()
})
.collect();

match dojo_packages.len() {
0 => {
ws.config().ui().warn(
"No package with dojo target found in workspace. If your package is a [lib] with \
[[target.dojo]], you can ignore this warning.",
);
Ok(DojoMetadata::default())
}
1 => {
let dojo_package =
dojo_packages.into_iter().next().expect("Package must exist as len is 1.");
Ok(dojo_metadata_from_package(&dojo_package, &ws)?)
}
_ => {
return Err(anyhow::anyhow!(
"Multiple packages with dojo target found in workspace. Please specify a package \
using --package option or maybe one of them must be declared as a [lib]."
));
}
}
}

/// Collect metadata from the project configuration and from the workspace.
///
/// # Arguments
/// `ws`: the workspace.
///
/// # Returns
/// A [`DojoMetadata`] object containing all Dojo metadata.
pub fn dojo_metadata_from_workspace(ws: &Workspace<'_>) -> Result<DojoMetadata> {
pub fn dojo_metadata_from_workspace_old(ws: &Workspace<'_>) -> Result<DojoMetadata> {
let profile = ws.config().profile();

let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf();
Expand All @@ -144,8 +178,8 @@ pub fn dojo_metadata_from_workspace(ws: &Workspace<'_>) -> Result<DojoMetadata>
// (being the only package or using --package).
return Err(anyhow!(
"No current package with dojo metadata found, virtual manifest in workspace are not \
supported. Until package compilation is supported, you will have to provide the path \
to the Scarb.toml file using the --manifest-path option."
supported. Until package compilation is supported, you will have to provide the path \
to the Scarb.toml file using the --manifest-path option."
));
};

Expand Down

0 comments on commit 87b754b

Please sign in to comment.