diff --git a/framework/meta-lib/src/cargo_toml_contents.rs b/framework/meta-lib/src/cargo_toml_contents.rs index 49721f5cec..ac6f851ba3 100644 --- a/framework/meta-lib/src/cargo_toml_contents.rs +++ b/framework/meta-lib/src/cargo_toml_contents.rs @@ -10,6 +10,8 @@ use crate::contract::sc_config::ContractVariantProfile; pub const CARGO_TOML_DEPENDENCIES: &str = "dependencies"; pub const CARGO_TOML_DEV_DEPENDENCIES: &str = "dev-dependencies"; +pub const PACKAGE: &str = "package"; +pub const AUTHORS: &str = "authors"; const AUTO_GENERATED: &str = "# Code generated by the multiversx-sc build system. DO NOT EDIT. # ########################################## @@ -69,7 +71,7 @@ impl CargoTomlContents { pub fn package_name(&self) -> String { self.toml_value - .get("package") + .get(PACKAGE) .expect("missing package in Cargo.toml") .get("name") .expect("missing package name in Cargo.toml") @@ -80,7 +82,7 @@ impl CargoTomlContents { pub fn package_edition(&self) -> String { self.toml_value - .get("package") + .get(PACKAGE) .expect("missing package in Cargo.toml") .get("edition") .expect("missing package name in Cargo.toml") @@ -158,6 +160,24 @@ impl CargoTomlContents { self.toml_value.get(CARGO_TOML_DEV_DEPENDENCIES).is_some() } + pub fn change_author(&mut self, authors: String) -> bool { + let package = self + .toml_value + .get_mut(PACKAGE) + .unwrap_or_else(|| panic!("no dependencies found in crate {}", self.path.display())) + .as_table_mut() + .expect("missing package in Cargo.toml"); + + package.remove(AUTHORS); + + package.insert( + AUTHORS.to_owned(), + toml::Value::Array(vec![toml::Value::String(authors)]), + ); + + true + } + pub fn dev_dependencies_mut(&mut self) -> &mut Table { self.toml_value .get_mut(CARGO_TOML_DEV_DEPENDENCIES) diff --git a/framework/meta/src/cli/cli_args_standalone.rs b/framework/meta/src/cli/cli_args_standalone.rs index e66c83deb4..335afe41ea 100644 --- a/framework/meta/src/cli/cli_args_standalone.rs +++ b/framework/meta/src/cli/cli_args_standalone.rs @@ -265,6 +265,11 @@ pub struct TemplateArgs { /// Will be current directory if not specified. #[arg(long, verbatim_doc_comment)] pub path: Option, + + /// The author of the contract. + /// If missing, the default author will be considered. + #[arg(long, verbatim_doc_comment)] + pub author: Option, } impl CliArgsToRaw for TemplateArgs { diff --git a/framework/meta/src/cmd/template/contract_creator.rs b/framework/meta/src/cmd/template/contract_creator.rs index 65e45f4d47..8483f3c8f8 100644 --- a/framework/meta/src/cmd/template/contract_creator.rs +++ b/framework/meta/src/cmd/template/contract_creator.rs @@ -18,7 +18,13 @@ pub fn create_contract(args: &TemplateArgs) { let repo_temp_download = RepoSource::download_from_github(version, std::env::temp_dir()); let target = target_from_args(args); - let creator = ContractCreator::new(&repo_temp_download, args.template.clone(), target, false); + let creator = ContractCreator::new( + &repo_temp_download, + args.template.clone(), + target, + false, + args.author.clone(), + ); creator.create_contract(version_tag); } @@ -59,6 +65,7 @@ impl<'a> ContractCreator<'a> { template_name: String, target: ContractCreatorTarget, keep_paths: bool, + new_author: Option, ) -> Self { let template_sources = template_sources(repo_source); let template_source = template_sources @@ -75,6 +82,7 @@ impl<'a> ContractCreator<'a> { metadata, target, keep_paths, + new_author, }, } } @@ -91,7 +99,7 @@ impl<'a> ContractCreator<'a> { } pub fn update_dependencies(&self, args_tag: FrameworkVersion) { - self.adjuster.update_dependencies(args_tag); + self.adjuster.update_cargo_toml_files(args_tag); } pub fn rename_template(&self) { diff --git a/framework/meta/src/cmd/template/template_adjuster.rs b/framework/meta/src/cmd/template/template_adjuster.rs index e1ac5ad827..2e628a9266 100644 --- a/framework/meta/src/cmd/template/template_adjuster.rs +++ b/framework/meta/src/cmd/template/template_adjuster.rs @@ -15,21 +15,27 @@ const ROOT_CARGO_TOML: &str = "./Cargo.toml"; const META_CARGO_TOML: &str = "./meta/Cargo.toml"; const WASM_CARGO_TOML: &str = "./wasm/Cargo.toml"; const INTERACT_CARGO_TOML: &str = "./interact/Cargo.toml"; +const DEFAULT_AUTHOR: &str = "you"; pub struct TemplateAdjuster { pub metadata: TemplateMetadata, pub target: ContractCreatorTarget, pub keep_paths: bool, + pub new_author: Option, } impl TemplateAdjuster { - pub fn update_dependencies(&self, args_tag: FrameworkVersion) { - self.update_dependencies_root(); - self.update_dependencies_meta(); - self.update_dependencies_wasm(args_tag); - self.update_dependencies_interact(); + pub fn update_cargo_toml_files(&self, args_tag: FrameworkVersion) { + let author_as_str = self + .new_author + .clone() + .unwrap_or_else(|| DEFAULT_AUTHOR.to_string()); + self.update_cargo_toml_root(author_as_str.clone()); + self.update_cargo_toml_meta(); + self.update_cargo_toml_wasm(args_tag); + self.update_cargo_toml_interact(author_as_str); } - fn update_dependencies_root(&self) { + fn update_cargo_toml_root(&self, author: String) { let cargo_toml_path = self.target.contract_dir().join(ROOT_CARGO_TOML); let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); @@ -42,11 +48,11 @@ impl TemplateAdjuster { } else { toml.add_workspace(&[".", "meta"]); } - + toml.change_author(author); toml.save_to_file(&cargo_toml_path); } - fn update_dependencies_meta(&self) { + fn update_cargo_toml_meta(&self) { let cargo_toml_path = self.target.contract_dir().join(META_CARGO_TOML); let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); @@ -57,7 +63,7 @@ impl TemplateAdjuster { toml.save_to_file(&cargo_toml_path); } - fn update_dependencies_wasm(&self, args_tag: FrameworkVersion) { + fn update_cargo_toml_wasm(&self, args_tag: FrameworkVersion) { if is_template_with_autogenerated_wasm(args_tag) { return; } @@ -72,7 +78,7 @@ impl TemplateAdjuster { toml.save_to_file(&cargo_toml_path); } - fn update_dependencies_interact(&self) { + fn update_cargo_toml_interact(&self, author: String) { if !self.metadata.has_interactor { return; } @@ -84,6 +90,7 @@ impl TemplateAdjuster { remove_paths_from_deps(&mut toml, &[&self.metadata.name]); } + toml.change_author(author); toml.save_to_file(&cargo_toml_path); } diff --git a/framework/meta/tests/template_test.rs b/framework/meta/tests/template_test.rs index 4b0fc0bc23..764aae6f87 100644 --- a/framework/meta/tests/template_test.rs +++ b/framework/meta/tests/template_test.rs @@ -32,7 +32,12 @@ fn test_template_list() { #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_adder() { - template_test_current("adder", "examples", "new-adder"); + template_test_current( + "adder", + "examples", + "new-adder", + "Alin Cruceat ", + ); cargo_check_interactor("examples", "new-adder"); } @@ -40,19 +45,19 @@ fn template_current_adder() { #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_crypto_zombies() { - template_test_current("crypto-zombies", "examples", "new-crypto-zombies"); + template_test_current("crypto-zombies", "examples", "new-crypto-zombies", ""); } #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_empty() { - template_test_current("empty", "examples", "new-empty"); + template_test_current("empty", "examples", "new-empty", ""); } #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_ping_pong_egld() { - template_test_current("ping-pong-egld", "examples", "new-ping-pong-egld"); + template_test_current("ping-pong-egld", "examples", "new-ping-pong-egld", ""); } #[test] @@ -63,13 +68,13 @@ fn test_correct_naming() { "my-new-42-correct-empty" ); - template_test_current("empty", "examples", "my1New2_3-correct_Empty"); + template_test_current("empty", "examples", "my1New2_3-correct_Empty", ""); } /// Recreates the folder structure in `contracts`, on the same level. /// This way, the relative paths are still valid in this case, /// and we can test the templates with the framework version of the current branch. -fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { +fn template_test_current(template_name: &str, sub_path: &str, new_name: &str, new_author: &str) { let workspace_path = find_current_workspace().unwrap(); let target = ContractCreatorTarget { target_path: workspace_path.join(TEMPLATE_TEMP_DIR_NAME).join(sub_path), @@ -80,11 +85,18 @@ fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { prepare_target_dir(&target); + let author = if new_author.is_empty() { + None + } else { + Some(new_author.to_string()) + }; + ContractCreator::new( &repo_source, template_name.to_string(), target.clone(), true, + author, ) .create_contract(LAST_TEMPLATE_VERSION); @@ -97,7 +109,11 @@ fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_adder() { - template_test_released("adder", "released-adder"); + template_test_released( + "adder", + "released-adder", + "Alin Cruceat ", + ); cargo_check_interactor("", "released-adder"); } @@ -105,13 +121,13 @@ fn template_released_adder() { #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_crypto_zombies() { - template_test_released("crypto-zombies", "released-crypto-zombies"); + template_test_released("crypto-zombies", "released-crypto-zombies", ""); } #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_empty() { - template_test_released("empty", "released-empty"); + template_test_released("empty", "released-empty", ""); } /// These tests fully replicate the templating process. They @@ -119,7 +135,7 @@ fn template_released_empty() { /// - create proper contracts, /// - build the newly created contracts (to wasm) /// - run all tests (including Go scenarios) on them. -fn template_test_released(template_name: &str, new_name: &str) { +fn template_test_released(template_name: &str, new_name: &str, new_author: &str) { let workspace_path = find_current_workspace().unwrap(); let target = ContractCreatorTarget { target_path: workspace_path.join(TEMPLATE_TEMP_DIR_NAME), @@ -137,11 +153,18 @@ fn template_test_released(template_name: &str, new_name: &str) { prepare_target_dir(&target); + let author = if new_author.is_empty() { + None + } else { + Some(new_author.to_string()) + }; + ContractCreator::new( &repo_source, template_name.to_string(), target.clone(), false, + author, ) .create_contract(LAST_TEMPLATE_VERSION);