diff --git a/Cargo.lock b/Cargo.lock index c067cab..40e2ab6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -743,9 +743,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180b130a4a41870edfbd36ce4169c7090bca70e195da783dea088dd973daa59c" +checksum = "367ee9093b0c2b04fd04c5c7c8b6a1082713534eab537597ae343663a518fa99" dependencies = [ "bstr", "itoa", @@ -1886,9 +1886,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.61" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", diff --git a/justfile b/justfile index 3706dc2..5ca19a7 100644 --- a/justfile +++ b/justfile @@ -10,6 +10,9 @@ install: prepare: rustup target add wasm32-unknown-unknown + rustup toolchain install nightly + rustup component add --toolchain nightly-x86_64-unknown-linux-gnu clippy + rustup component add --toolchain nightly-x86_64-unknown-linux-gnu rustfmt sudo apt install wabt wget https://github.com/WebAssembly/binaryen/releases/download/{{BINARYEN_VERSION}}/binaryen-{{BINARYEN_VERSION}}-x86_64-linux.tar.gz || { echo "Download failed"; exit 1; } sha256sum binaryen-{{BINARYEN_VERSION}}-x86_64-linux.tar.gz | grep {{BINARYEN_CHECKSUM}} || { echo "Checksum verification failed"; exit 1; } @@ -51,13 +54,13 @@ test-workspace-project: cd testproject && cargo odra clean clippy: - cargo clippy --all-targets -- -D warnings + cargo +nightly clippy --all-targets -- -D warnings check-lint: clippy - cargo fmt -- --check + cargo +nightly fmt -- --check lint: clippy - cargo fmt + cargo +nightly fmt clean: cargo clean diff --git a/src/actions/build.rs b/src/actions/build.rs index 5dc8a9a..ee31a1b 100644 --- a/src/actions/build.rs +++ b/src/actions/build.rs @@ -40,11 +40,15 @@ impl BuildAction<'_> { }); for contract in contracts { - let build_contract = format!("{}_build_contract", &contract.crate_name(self.project)); + let module_name = match self.project.is_workspace() { + true => contract.module_name(), + false => contract.crate_name(self.project), + }; + let build_contract = format!("{}_build_contract", &module_name); command::cargo_build_wasm_files( self.project.project_root(), &contract.struct_name(), - &contract.crate_name(self.project), + &module_name, ); let source = paths::wasm_path_in_target(&build_contract, self.project.project_root()); let target = @@ -56,7 +60,7 @@ impl BuildAction<'_> { let module_wasm_dir = self .project .project_root() - .join(contract.module_name()) + .join(contract.module_crate_name(self.project)) .join("wasm"); command::mkdir(module_wasm_dir.clone()); let mut module_wasm_path = module_wasm_dir.clone().join(&contract.struct_name()); @@ -80,7 +84,9 @@ impl BuildAction<'_> { if self.project.is_workspace() { command::process_wasm( &contract.struct_name(), - self.project.project_root().join(contract.module_name()), + self.project + .project_root() + .join(contract.module_crate_name(self.project)), ); } } diff --git a/src/actions/generate.rs b/src/actions/generate.rs index 57ebc79..bb3ed88 100644 --- a/src/actions/generate.rs +++ b/src/actions/generate.rs @@ -28,7 +28,7 @@ impl<'a> GenerateAction<'a> { /// Crate a new GenerateAction for a given contract. pub fn new(project: &'a Project, contract_name: String, module_name: Option) -> Self { if project.is_workspace() && module_name.is_none() { - Error::ModuleNotProvided.print_and_die(); + Error::CrateNotProvided.print_and_die(); } GenerateAction { diff --git a/src/command.rs b/src/command.rs index 74eda75..2185dd8 100644 --- a/src/command.rs +++ b/src/command.rs @@ -173,11 +173,7 @@ pub fn write_to_file(path: PathBuf, content: &str) { /// Appends a content to a file at the given path. pub fn append_file(path: PathBuf, content: &str) { - let mut file = OpenOptions::new() - .write(true) - .append(true) - .open(path) - .unwrap(); + let mut file = OpenOptions::new().append(true).open(path).unwrap(); file.write_all(content.as_bytes()).unwrap(); } diff --git a/src/errors.rs b/src/errors.rs index bd217cb..1b6141d 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -76,8 +76,11 @@ pub enum Error { #[error("Module {0} already in src/lib.rs")] ModuleAlreadyInLibRs(String), - #[error("Project is a workspace, module name is required")] - ModuleNotProvided, + #[error("Project is a workspace, crate name is required")] + CrateNotProvided, + + #[error("Crate for contract {0} not found in workspace members")] + CrateOfContractNotFound(String), } impl Error { @@ -107,7 +110,8 @@ impl Error { Error::LibRsNotFound => 22, Error::ModuleAlreadyInLibRs(_) => 23, Error::WasmoptDidNotFinish => 24, - Error::ModuleNotProvided => 25, + Error::CrateNotProvided => 25, + Error::CrateOfContractNotFound(_) => 26, } } diff --git a/src/odra_toml.rs b/src/odra_toml.rs index a88bab2..e80215f 100644 --- a/src/odra_toml.rs +++ b/src/odra_toml.rs @@ -17,18 +17,34 @@ pub struct Contract { } impl Contract { - /// Extracts first part from fqn pub fn module_name(&self) -> String { self.fqn .split_terminator("::") .next() .unwrap_or_else(|| MalformedFqn.print_and_die()) + .replace("-", "_") .to_string() } + pub fn module_crate_name(&self, project: &Project) -> String { + if project.is_workspace() { + project + .members + .iter() + .find(|m| m.name.replace("-", "_") == self.module_name()) + .unwrap_or_else(|| { + Error::CrateOfContractNotFound(self.module_name()).print_and_die() + }) + .name + .clone() + } else { + project.project_crate_name() + } + } + pub fn crate_name(&self, project: &Project) -> String { if project.is_workspace() { - self.module_name() + self.module_crate_name(project) } else { project.project_crate_name() } @@ -78,14 +94,14 @@ impl OdraToml { .any(|c| c.struct_name() == contract_name) } - /// Check if any contract in Odra.toml is a part of a module with given name - pub fn has_module(&self, module_name: &str) -> bool { + /// Check if any contract in Odra.toml is a part of a crate with given name + pub fn crate_has_contracts(&self, crate_name: &str) -> bool { self.contracts.iter().any(|c| { c.fqn .split_terminator("::") .next() .unwrap_or_else(|| Error::MalformedFqn.print_and_die()) - == module_name + == crate_name.replace("-", "_") }) } } diff --git a/src/paths.rs b/src/paths.rs index 3d5ed5d..29042bc 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -26,7 +26,6 @@ pub fn wasm_path_in_target(contract_name: &str, project_root: PathBuf) -> PathBu fn get_build_target_dir() -> PathBuf { let args: Vec = "config get build.target-dir -Z unstable-options" - .to_string() .split(' ') .map(|s| s.to_string()) .collect(); diff --git a/src/project.rs b/src/project.rs index 8682455..097d26d 100644 --- a/src/project.rs +++ b/src/project.rs @@ -128,11 +128,9 @@ impl Project { .iter() .map(|member| { let root = cargo_toml_path.parent().unwrap().join(member.clone().1); - let cargo_toml = root.join("Cargo.toml"); Member { name: member.clone().0, root, - cargo_toml, } }) .collect() @@ -156,13 +154,14 @@ impl Project { } } + /// Detects members of workspace which have Odra contracts. fn detect_members(cargo_toml_path: &PathBuf, odra_toml_path: &Path) -> Vec<(String, String)> { let odra_toml = OdraToml::load(odra_toml_path); match load_cargo_toml(cargo_toml_path).workspace { Some(workspace) => workspace .members .iter() - .filter(|member| odra_toml.has_module(member)) + .filter(|crate_name| odra_toml.crate_has_contracts(crate_name)) .map(|member| (member.clone(), member.clone())) .collect(), None => vec![], @@ -229,6 +228,4 @@ pub struct Member { pub name: String, /// Root directory of the member. pub root: PathBuf, - /// Path to the Cargo.toml file. - pub cargo_toml: PathBuf, }