From b70a55f30ed9d19f3884b1dc40bdb7f35abefe45 Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:45:03 +0100 Subject: [PATCH 1/6] feat(macros): add `SetOptions { profile }` command --- Cargo.toml | 1 + packages/fuels-macros/Cargo.toml | 1 + .../src/setup_program_test/code_gen.rs | 28 ++++++++++---- .../src/setup_program_test/parsing.rs | 4 +- .../setup_program_test/parsing/commands.rs | 5 +++ .../parsing/commands/set_options.rs | 37 +++++++++++++++++++ .../setup_program_test/unknown_command.stderr | 2 +- 7 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs diff --git a/Cargo.toml b/Cargo.toml index 09f4e2134d..44d624a5cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ serde = { version = "1.0.193", default-features = false } serde_json = "1.0.108" serde_with = { version = "3.4.0", default-features = false } sha2 = { version = "0.10.8", default-features = false } +strum = "0.26.2" syn = "2.0.39" tai64 = { version = "4.0.0", default-features = false } tar = { version = "0.4", default-features = false } diff --git a/packages/fuels-macros/Cargo.toml b/packages/fuels-macros/Cargo.toml index d1353e2bd3..1658f5bb51 100644 --- a/packages/fuels-macros/Cargo.toml +++ b/packages/fuels-macros/Cargo.toml @@ -17,6 +17,7 @@ fuels-code-gen = { workspace = true } itertools = { workspace = true } proc-macro2 = { workspace = true } quote = { workspace = true } +strum = { workspace = true, features = ["derive"] } syn = { workspace = true, features = ["extra-traits"] } [dev-dependencies] diff --git a/packages/fuels-macros/src/setup_program_test/code_gen.rs b/packages/fuels-macros/src/setup_program_test/code_gen.rs index fd83233e9c..b4c22c2b8c 100644 --- a/packages/fuels-macros/src/setup_program_test/code_gen.rs +++ b/packages/fuels-macros/src/setup_program_test/code_gen.rs @@ -9,21 +9,23 @@ use quote::quote; use syn::LitStr; use crate::setup_program_test::parsing::{ - AbigenCommand, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand, - TestProgramCommands, + AbigenCommand, BuildProfile, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand, + SetOptionsCommand, TestProgramCommands, }; pub(crate) fn generate_setup_program_test_code( commands: TestProgramCommands, ) -> syn::Result { let TestProgramCommands { + set_options, initialize_wallets, generate_bindings, deploy_contract, load_scripts, } = commands; - let project_lookup = generate_project_lookup(&generate_bindings)?; + let SetOptionsCommand { profile } = set_options.unwrap_or_default(); + let project_lookup = generate_project_lookup(&generate_bindings, profile)?; let abigen_code = abigen_code(&project_lookup)?; let wallet_code = wallet_initialization_code(initialize_wallets); let deploy_code = contract_deploying_code(&deploy_contract, &project_lookup); @@ -37,12 +39,15 @@ pub(crate) fn generate_setup_program_test_code( }) } -fn generate_project_lookup(commands: &AbigenCommand) -> syn::Result> { +fn generate_project_lookup( + commands: &AbigenCommand, + profile: BuildProfile, +) -> syn::Result> { let pairs = commands .targets .iter() .map(|command| -> syn::Result<_> { - let project = Project::new(command.program_type, &command.project)?; + let project = Project::new(command.program_type, &command.project, profile.clone())?; Ok((command.name.value(), project)) }) .collect::, _>>()?; @@ -189,10 +194,11 @@ struct Project { program_type: ProgramType, path: PathBuf, path_span: Span, + profile: BuildProfile, } impl Project { - fn new(program_type: ProgramType, dir: &LitStr) -> syn::Result { + fn new(program_type: ProgramType, dir: &LitStr, profile: BuildProfile) -> syn::Result { let path = Path::new(&dir.value()).canonicalize().map_err(|_| { syn::Error::new_spanned( dir.clone(), @@ -204,12 +210,20 @@ impl Project { program_type, path, path_span: dir.span(), + profile, }) } fn compile_file_path(&self, suffix: &str, description: &str) -> String { self.path - .join(["out/release/", self.project_name(), suffix].concat()) + .join( + [ + format!("out/{}/", &self.profile).as_str(), + self.project_name(), + suffix, + ] + .concat(), + ) .to_str() .unwrap_or_else(|| panic!("could not join path for {description}")) .to_string() diff --git a/packages/fuels-macros/src/setup_program_test/parsing.rs b/packages/fuels-macros/src/setup_program_test/parsing.rs index 4057e6b3d7..93cbb40f54 100644 --- a/packages/fuels-macros/src/setup_program_test/parsing.rs +++ b/packages/fuels-macros/src/setup_program_test/parsing.rs @@ -1,6 +1,6 @@ pub(crate) use commands::{ - AbigenCommand, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand, - TestProgramCommands, + AbigenCommand, BuildProfile, DeployContractCommand, InitializeWalletCommand, LoadScriptCommand, + SetOptionsCommand, TestProgramCommands, }; mod command_parser; diff --git a/packages/fuels-macros/src/setup_program_test/parsing/commands.rs b/packages/fuels-macros/src/setup_program_test/parsing/commands.rs index 7c1eae6dad..50ec4772ce 100644 --- a/packages/fuels-macros/src/setup_program_test/parsing/commands.rs +++ b/packages/fuels-macros/src/setup_program_test/parsing/commands.rs @@ -3,6 +3,7 @@ pub(crate) use deploy_contract::DeployContractCommand; pub(crate) use initialize_wallet::InitializeWalletCommand; use itertools::Itertools; pub(crate) use load_script::LoadScriptCommand; +pub(crate) use set_options::{BuildProfile, SetOptionsCommand}; use syn::{ parse::{Parse, ParseStream}, Result, @@ -20,11 +21,13 @@ mod abigen; mod deploy_contract; mod initialize_wallet; mod load_script; +mod set_options; // Contains the result of parsing the input to the `setup_program_test` macro. // Contents represent the users wishes with regards to wallet initialization, // bindings generation and contract deployment. pub(crate) struct TestProgramCommands { + pub(crate) set_options: Option, pub(crate) initialize_wallets: Option, pub(crate) generate_bindings: AbigenCommand, pub(crate) deploy_contract: Vec, @@ -32,6 +35,7 @@ pub(crate) struct TestProgramCommands { } command_parser!( + Options -> SetOptionsCommand, Wallets -> InitializeWalletCommand, Abigen -> AbigenCommand, Deploy -> DeployContractCommand, @@ -53,6 +57,7 @@ impl Parse for TestProgramCommands { validate_zero_or_one_wallet_command_present(&parsed_commands.Wallets)?; Ok(Self { + set_options: parsed_commands.Options.pop(), initialize_wallets: parsed_commands.Wallets.pop(), generate_bindings: abigen_command, deploy_contract: parsed_commands.Deploy, diff --git a/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs new file mode 100644 index 0000000000..49507234f6 --- /dev/null +++ b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs @@ -0,0 +1,37 @@ +use std::convert::TryFrom; + +use strum::{Display, EnumString}; +use syn::Error; + +use crate::parse_utils::{Command, UniqueNameValues}; + +#[derive(Debug, Clone, Default, PartialEq, Eq, EnumString, Display)] +#[strum(serialize_all = "lowercase")] +pub enum BuildProfile { + Debug, + #[default] + Release, +} + +#[derive(Debug, Clone, Default)] +pub struct SetOptionsCommand { + pub profile: BuildProfile, +} + +impl TryFrom for SetOptionsCommand { + type Error = Error; + + fn try_from(command: Command) -> Result { + let name_values = UniqueNameValues::new(command.contents)?; + name_values.validate_has_no_other_names(&["profile"])?; + + let profile = name_values.get_as_lit_str("profile")?; + let profile = profile + .value() + .as_str() + .parse() + .map_err(|msg| Error::new(profile.span(), msg))?; + + Ok(Self { profile }) + } +} diff --git a/packages/fuels-macros/tests/ui/setup_program_test/unknown_command.stderr b/packages/fuels-macros/tests/ui/setup_program_test/unknown_command.stderr index b39e2dad66..f5f9909d0c 100644 --- a/packages/fuels-macros/tests/ui/setup_program_test/unknown_command.stderr +++ b/packages/fuels-macros/tests/ui/setup_program_test/unknown_command.stderr @@ -1,4 +1,4 @@ -error: Unrecognized command. Expected one of: 'Wallets', 'Abigen', 'Deploy', 'LoadScript' +error: Unrecognized command. Expected one of: 'Options', 'Wallets', 'Abigen', 'Deploy', 'LoadScript' --> tests/ui/setup_program_test/unknown_command.rs:10:5 | 10 | UnknownCommand() From aae43d5cdbdb95fa73b8f44da37557cd27a467a0 Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:57:44 +0100 Subject: [PATCH 2/6] docs: add command to macro docs --- docs/src/testing/the-setup-program-test-macro.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/src/testing/the-setup-program-test-macro.md b/docs/src/testing/the-setup-program-test-macro.md index 72d71fbf68..1be9889953 100644 --- a/docs/src/testing/the-setup-program-test-macro.md +++ b/docs/src/testing/the-setup-program-test-macro.md @@ -24,6 +24,16 @@ of `COMMAND(ARG...)...` Available `COMMAND`s: +## Options + +Example: `Options(profile="debug")` + +Description: Sets options from `ARG`s to be used by other `COMMAND`s. +Available options: +- `profile`: sets the `cargo` build profile. Variants: `"release"` (default), `"debug"` + +Cardinality: 0 or 1. + ## Wallets Example: `Wallets("a_wallet", "another_wallet"...)` From 763af429a0d12e00e92975511b48735bc24d1a9a Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:26:03 +0100 Subject: [PATCH 3/6] fix docs --- docs/src/testing/the-setup-program-test-macro.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/testing/the-setup-program-test-macro.md b/docs/src/testing/the-setup-program-test-macro.md index 1be9889953..f4999f0a20 100644 --- a/docs/src/testing/the-setup-program-test-macro.md +++ b/docs/src/testing/the-setup-program-test-macro.md @@ -29,7 +29,9 @@ Available `COMMAND`s: Example: `Options(profile="debug")` Description: Sets options from `ARG`s to be used by other `COMMAND`s. + Available options: + - `profile`: sets the `cargo` build profile. Variants: `"release"` (default), `"debug"` Cardinality: 0 or 1. From d8ecdbbef818c56b18393d4362a10b71104032e9 Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Tue, 4 Jun 2024 02:56:08 +0100 Subject: [PATCH 4/6] deps: remove strum, impl string traits --- Cargo.toml | 1 - packages/fuels-macros/Cargo.toml | 1 - .../parsing/commands/set_options.rs | 31 ++++++++++++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 44d624a5cb..09f4e2134d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,6 @@ serde = { version = "1.0.193", default-features = false } serde_json = "1.0.108" serde_with = { version = "3.4.0", default-features = false } sha2 = { version = "0.10.8", default-features = false } -strum = "0.26.2" syn = "2.0.39" tai64 = { version = "4.0.0", default-features = false } tar = { version = "0.4", default-features = false } diff --git a/packages/fuels-macros/Cargo.toml b/packages/fuels-macros/Cargo.toml index 1658f5bb51..d1353e2bd3 100644 --- a/packages/fuels-macros/Cargo.toml +++ b/packages/fuels-macros/Cargo.toml @@ -17,7 +17,6 @@ fuels-code-gen = { workspace = true } itertools = { workspace = true } proc-macro2 = { workspace = true } quote = { workspace = true } -strum = { workspace = true, features = ["derive"] } syn = { workspace = true, features = ["extra-traits"] } [dev-dependencies] diff --git a/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs index 49507234f6..667d09a915 100644 --- a/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs +++ b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs @@ -1,18 +1,41 @@ -use std::convert::TryFrom; +use std::{convert::TryFrom, fmt, str::FromStr}; -use strum::{Display, EnumString}; use syn::Error; use crate::parse_utils::{Command, UniqueNameValues}; -#[derive(Debug, Clone, Default, PartialEq, Eq, EnumString, Display)] -#[strum(serialize_all = "lowercase")] +#[derive(Debug, Clone, Default, PartialEq, Eq)] pub enum BuildProfile { Debug, #[default] Release, } +impl FromStr for BuildProfile { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "debug" => Ok(Self::Debug), + "release" => Ok(Self::Release), + _ => Err(r#"invalid build profile option: must be "default" or "release""#), + } + } +} + +impl fmt::Display for BuildProfile { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + BuildProfile::Debug => "debug", + BuildProfile::Release => "release", + } + ) + } +} + #[derive(Debug, Clone, Default)] pub struct SetOptionsCommand { pub profile: BuildProfile, From 98dddb9500448209f4909eb45c4560cf62716644 Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:34:04 +0100 Subject: [PATCH 5/6] fix: typo --- .../src/setup_program_test/parsing/commands/set_options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs index 667d09a915..6d305f5d6b 100644 --- a/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs +++ b/packages/fuels-macros/src/setup_program_test/parsing/commands/set_options.rs @@ -18,7 +18,7 @@ impl FromStr for BuildProfile { match s { "debug" => Ok(Self::Debug), "release" => Ok(Self::Release), - _ => Err(r#"invalid build profile option: must be "default" or "release""#), + _ => Err(r#"invalid build profile option: must be "debug" or "release""#), } } } From 8488643520cbf389b5ebeed10cc487de96d14d5e Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko <12615679+Br1ght0ne@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:30:12 +0100 Subject: [PATCH 6/6] test(macros): add ui tests for Options command --- .../tests/ui/setup_program_test/unknown_options_key.rs | 5 +++++ .../tests/ui/setup_program_test/unknown_options_key.stderr | 5 +++++ .../tests/ui/setup_program_test/unknown_options_value.rs | 5 +++++ .../tests/ui/setup_program_test/unknown_options_value.stderr | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.rs create mode 100644 packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.stderr create mode 100644 packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.rs create mode 100644 packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.stderr diff --git a/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.rs b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.rs new file mode 100644 index 0000000000..d8af2cf74f --- /dev/null +++ b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.rs @@ -0,0 +1,5 @@ +use fuels_macros::setup_program_test; + +setup_program_test!(Options(unknown = "debug")); + +fn main() {} diff --git a/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.stderr b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.stderr new file mode 100644 index 0000000000..1adc974c9b --- /dev/null +++ b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_key.stderr @@ -0,0 +1,5 @@ +error: attribute 'unknown' not recognized. Expected one of: 'profile' + --> tests/ui/setup_program_test/unknown_options_key.rs:3:29 + | +3 | setup_program_test!(Options(unknown = "debug")); + | ^^^^^^^ diff --git a/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.rs b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.rs new file mode 100644 index 0000000000..73277322d5 --- /dev/null +++ b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.rs @@ -0,0 +1,5 @@ +use fuels_macros::setup_program_test; + +setup_program_test!(Options(profile = "not_a_profile")); + +fn main() {} diff --git a/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.stderr b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.stderr new file mode 100644 index 0000000000..9ff49d4b9a --- /dev/null +++ b/packages/fuels-macros/tests/ui/setup_program_test/unknown_options_value.stderr @@ -0,0 +1,5 @@ +error: invalid build profile option: must be "debug" or "release" + --> tests/ui/setup_program_test/unknown_options_value.rs:3:39 + | +3 | setup_program_test!(Options(profile = "not_a_profile")); + | ^^^^^^^^^^^^^^^