From 885e661f2f99c42898d9bc1edf563d347cf773a1 Mon Sep 17 00:00:00 2001 From: gagdiez Date: Sun, 14 Jul 2024 00:59:35 +0200 Subject: [PATCH 1/8] wip: js command execute --- src/js_command_match/mod.rs | 44 +++++++++------------- src/js_command_match/validators.rs | 12 ------ src/main.rs | 60 +++++++++--------------------- 3 files changed, 34 insertions(+), 82 deletions(-) delete mode 100644 src/js_command_match/validators.rs diff --git a/src/js_command_match/mod.rs b/src/js_command_match/mod.rs index 528fa00bc..6d6a92a60 100644 --- a/src/js_command_match/mod.rs +++ b/src/js_command_match/mod.rs @@ -4,7 +4,6 @@ mod account; mod contract; mod keys; mod transactions; -mod validators; #[derive(Debug, Clone, clap::Parser)] /// Legacy CLI commands are only supported at best-effort @@ -31,40 +30,31 @@ pub enum JsCmd { #[clap(alias("send-near"))] Send(self::transactions::send::SendArgs), TxStatus(self::transactions::status::TxStatusArgs), - - #[clap(alias("validator-stake"))] - Stake(self::validators::StakeArgs), - Validators(self::validators::ValidatorsArgs), } impl JsCmd { - pub fn rust_command_generation(&self) -> Result<(Vec, String), String> { + pub fn rust_command_generation(&self) -> Vec { let network = std::env::var("NEAR_NETWORK") .or_else(|_| std::env::var("NEAR_ENV")) .unwrap_or_else(|_| "testnet".to_owned()); - let message = "The command you tried to run is deprecated in the new NEAR CLI, but we tried our best to match the old command with the new syntax, try it instead:".to_string(); - let validator_extension_message = "The command you tried to run has been moved into its own CLI extension called near-validator.\nPlease, follow the installation instructions here: https://github.com/near-cli-rs/near-validator-cli-rs/blob/master/README.md".to_string(); match self { - Self::CreateAccount(args) => Ok((args.to_cli_args(network), message)), - Self::DeleteAccount(args) => Ok((args.to_cli_args(network), message)), - Self::Login(args) => Ok((args.to_cli_args(network), message)), - Self::State(args) => Ok((args.to_cli_args(network), message)), - - Self::Call(args) => Ok((args.to_cli_args(network), message)), - Self::Deploy(args) => Ok((args.to_cli_args(network), message)), - Self::ViewState(args) => Ok((args.to_cli_args(network), message)), - Self::View(args) => Ok((args.to_cli_args(network), message)), - - Self::AddKey(args) => Ok((args.to_cli_args(network), message)), - Self::DeleteKey(args) => Ok((args.to_cli_args(network), message)), - Self::ListKeys(args) => Ok((args.to_cli_args(network), message)), - - Self::Send(args) => Ok((args.to_cli_args(network), message)), - Self::TxStatus(args) => Ok((args.to_cli_args(network), message)), - - Self::Stake(_args) => Ok((vec![], validator_extension_message)), - Self::Validators(_args) => Ok((vec![], validator_extension_message)), + Self::CreateAccount(args) => args.to_cli_args(network), + Self::DeleteAccount(args) => args.to_cli_args(network), + Self::Login(args) => args.to_cli_args(network), + Self::State(args) => args.to_cli_args(network), + + Self::Call(args) => args.to_cli_args(network), + Self::Deploy(args) => args.to_cli_args(network), + Self::ViewState(args) => args.to_cli_args(network), + Self::View(args) => args.to_cli_args(network), + + Self::AddKey(args) => args.to_cli_args(network), + Self::DeleteKey(args) => args.to_cli_args(network), + Self::ListKeys(args) => args.to_cli_args(network), + + Self::Send(args) => args.to_cli_args(network), + Self::TxStatus(args) => args.to_cli_args(network), } } } diff --git a/src/js_command_match/validators.rs b/src/js_command_match/validators.rs deleted file mode 100644 index eb4c9fa8d..000000000 --- a/src/js_command_match/validators.rs +++ /dev/null @@ -1,12 +0,0 @@ -#[derive(Debug, Clone, clap::Parser)] -/// This is a legacy `validators` command. Once you run it with the specified arguments, new syntax command will be suggested. -pub struct ValidatorsArgs { - #[clap(allow_hyphen_values = true, num_args = 0..)] - _unknown_args: Vec, -} - -#[derive(Debug, Clone, clap::Parser)] -pub struct StakeArgs { - #[clap(allow_hyphen_values = true, num_args = 0..)] - _unknown_args: Vec, -} diff --git a/src/main.rs b/src/main.rs index 7fc19eee8..4949362fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,55 +103,29 @@ fn main() -> crate::common::CliResult { let cli = match Cmd::try_parse() { Ok(cli) => cli, - Err(error) => { - match error.kind() { - clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion => {} - _ => match crate::js_command_match::JsCmd::try_parse() { + Err(error) => match error.kind() { + clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion => { + error.exit() + } + clap::error::ErrorKind::InvalidSubcommand => { + match crate::js_command_match::JsCmd::try_parse() { Ok(js_cmd) => { - match js_cmd.rust_command_generation() { - Ok((vec_cmd, success_message)) => { - eprintln!("{success_message}"); - eprintln!(); - eprintln!( - " {}", - shell_words::join( - std::iter::once(near_cli_exec_path).chain(vec_cmd) - ) - .yellow() - ); - } - Err(err) => { - eprintln!("{}", err); - } - } - std::process::exit(1); + let vec_cmd = js_cmd.rust_command_generation(); + let cmd = &shell_words::join( + std::iter::once(near_cli_exec_path.to_owned()).chain(vec_cmd), + ); + Cmd::try_parse_from(cmd).unwrap() } Err(error) => { - if let clap::error::ErrorKind::DisplayHelp = error.kind() { - error.exit(); - } - if let Some(cmd) = std::env::args().nth(1) { - match cmd.as_str() { - "add-credentials" | "add-key" | "call" | "create" - | "create-account" | "delete" | "delete-account" | "delete-key" - | "deploy" | "generate-key" | "import-account" | "keys" - | "list-keys" | "login" | "send" | "send-near" | "stake" - | "state" | "storage" | "tx-status" | "validator-stake" - | "validators" | "view" | "view-storage" => error.exit(), - _ => {} - } + if let clap::error::ErrorKind::InvalidSubcommand = error.kind() { + return crate::common::try_external_subcommand_execution(error); } + error.exit(); } - }, + } } - - if let clap::error::ErrorKind::UnknownArgument - | clap::error::ErrorKind::InvalidSubcommand = error.kind() - { - return crate::common::try_external_subcommand_execution(error); - } - error.exit(); - } + _ => error.exit(), + }, }; let cli_cmd = match ::from_cli(Some(cli), (config,)) { From eed3734a117105888bbe9668f995fc90eddf0ae4 Mon Sep 17 00:00:00 2001 From: gagdiez Date: Wed, 24 Jul 2024 13:32:51 +0200 Subject: [PATCH 2/8] fix: error handling --- src/main.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4949362fc..96e0d5920 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,12 +103,12 @@ fn main() -> crate::common::CliResult { let cli = match Cmd::try_parse() { Ok(cli) => cli, - Err(error) => match error.kind() { + Err(cmd_error) => match cmd_error.kind() { clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion => { - error.exit() + cmd_error.exit() } - clap::error::ErrorKind::InvalidSubcommand => { - match crate::js_command_match::JsCmd::try_parse() { + _ => { + match crate::js_command_match::JsCmd::try_parse() { Ok(js_cmd) => { let vec_cmd = js_cmd.rust_command_generation(); let cmd = &shell_words::join( @@ -116,15 +116,21 @@ fn main() -> crate::common::CliResult { ); Cmd::try_parse_from(cmd).unwrap() } - Err(error) => { - if let clap::error::ErrorKind::InvalidSubcommand = error.kind() { - return crate::common::try_external_subcommand_execution(error); + Err(js_cmd_error) => { + // js and rust both don't understand the subcommand + if cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand && js_cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand { + return crate::common::try_external_subcommand_execution(cmd_error); } - error.exit(); + + // js understand the subcommand + if js_cmd_error.kind() != clap::error::ErrorKind::InvalidSubcommand { + js_cmd_error.exit(); + } + + cmd_error.exit(); } } } - _ => error.exit(), }, }; From cab45e763df005108bf6d99a14661a01c4b0e5ff Mon Sep 17 00:00:00 2001 From: gagdiez Date: Wed, 24 Jul 2024 13:40:41 +0200 Subject: [PATCH 3/8] fix: use Parser to parse cmd --- src/main.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 96e0d5920..b32e50255 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,10 +111,8 @@ fn main() -> crate::common::CliResult { match crate::js_command_match::JsCmd::try_parse() { Ok(js_cmd) => { let vec_cmd = js_cmd.rust_command_generation(); - let cmd = &shell_words::join( - std::iter::once(near_cli_exec_path.to_owned()).chain(vec_cmd), - ); - Cmd::try_parse_from(cmd).unwrap() + let cmd = std::iter::once(near_cli_exec_path.to_owned()).chain(vec_cmd); + Parser::parse_from(cmd) } Err(js_cmd_error) => { // js and rust both don't understand the subcommand From 5d03eb8f7d96909b47aab0b716ff7c91c150389c Mon Sep 17 00:00:00 2001 From: gagdiez Date: Wed, 24 Jul 2024 13:47:22 +0200 Subject: [PATCH 4/8] chore: format code --- src/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index b32e50255..264072120 100644 --- a/src/main.rs +++ b/src/main.rs @@ -108,7 +108,7 @@ fn main() -> crate::common::CliResult { cmd_error.exit() } _ => { - match crate::js_command_match::JsCmd::try_parse() { + match crate::js_command_match::JsCmd::try_parse() { Ok(js_cmd) => { let vec_cmd = js_cmd.rust_command_generation(); let cmd = std::iter::once(near_cli_exec_path.to_owned()).chain(vec_cmd); @@ -116,7 +116,9 @@ fn main() -> crate::common::CliResult { } Err(js_cmd_error) => { // js and rust both don't understand the subcommand - if cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand && js_cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand { + if cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand + && js_cmd_error.kind() == clap::error::ErrorKind::InvalidSubcommand + { return crate::common::try_external_subcommand_execution(cmd_error); } From af2b543b17bb4657c4ecbd8f1286945aec151123 Mon Sep 17 00:00:00 2001 From: gagdiez Date: Tue, 30 Jul 2024 12:54:57 +0200 Subject: [PATCH 5/8] fix: call, view, validators, stake --- src/js_command_match/contract/call.rs | 2 +- src/js_command_match/contract/view.rs | 4 ++-- src/js_command_match/deprecated.rs | 30 +++++++++++++++++++++++++++ src/js_command_match/mod.rs | 7 +++++++ 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/js_command_match/deprecated.rs diff --git a/src/js_command_match/contract/call.rs b/src/js_command_match/contract/call.rs index 24598f972..98d1845c3 100644 --- a/src/js_command_match/contract/call.rs +++ b/src/js_command_match/contract/call.rs @@ -9,7 +9,7 @@ use crate::js_command_match::constants::{ pub struct CallArgs { contract_name: String, method_name: String, - #[clap(default_value = "")] + #[clap(default_value = "{}")] args: String, #[clap(long, aliases = USE_ACCOUNT_ALIASES)] use_account: String, diff --git a/src/js_command_match/contract/view.rs b/src/js_command_match/contract/view.rs index a9733db85..028c28d66 100644 --- a/src/js_command_match/contract/view.rs +++ b/src/js_command_match/contract/view.rs @@ -5,7 +5,7 @@ use crate::js_command_match::constants::NETWORK_ID_ALIASES; pub struct ViewArgs { contract_name: String, method_name: String, - #[clap(default_value = "")] + #[clap(default_value = "{}")] args: String, #[clap(long, aliases = NETWORK_ID_ALIASES)] network_id: Option, @@ -21,7 +21,7 @@ impl ViewArgs { "as-read-only".to_string(), self.contract_name.to_owned(), self.method_name.to_owned(), - "text-args".to_string(), + "json-args".to_string(), self.args.to_owned(), "network-config".to_string(), network_id, diff --git a/src/js_command_match/deprecated.rs b/src/js_command_match/deprecated.rs new file mode 100644 index 000000000..40c6be264 --- /dev/null +++ b/src/js_command_match/deprecated.rs @@ -0,0 +1,30 @@ +use color_eyre::owo_colors::OwoColorize; + +#[derive(Debug, Clone, clap::Parser)] +/// This is a legacy `validators` command. Once you run it with the specified arguments, new syntax command will be suggested. +pub struct ValidatorsArgs { + #[clap(allow_hyphen_values = true, num_args = 0..)] + _unknown_args: Vec, +} + +#[derive(Debug, Clone, clap::Parser)] +pub struct StakeArgs { + #[clap(allow_hyphen_values = true, num_args = 0..)] + _unknown_args: Vec, +} + +const DEPRECATED: &str = "The command you tried to run has been moved into its own CLI extension called near-validator.\nPlease, follow the installation instructions here: https://github.com/near-cli-rs/near-validator-cli-rs/blob/master/README.md"; + +impl ValidatorsArgs { + pub fn to_cli_args(&self, _network_config: String) -> Vec { + eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); + vec!["near-validator".to_string()] + } +} + +impl StakeArgs { + pub fn to_cli_args(&self, _network_config: String) -> Vec { + eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); + vec!["near-validator".to_string()] + } +} \ No newline at end of file diff --git a/src/js_command_match/mod.rs b/src/js_command_match/mod.rs index 6d6a92a60..0d58706dc 100644 --- a/src/js_command_match/mod.rs +++ b/src/js_command_match/mod.rs @@ -2,6 +2,7 @@ mod constants; mod account; mod contract; +mod deprecated; mod keys; mod transactions; @@ -30,6 +31,9 @@ pub enum JsCmd { #[clap(alias("send-near"))] Send(self::transactions::send::SendArgs), TxStatus(self::transactions::status::TxStatusArgs), + + Validators(self::deprecated::ValidatorsArgs), + Stake(self::deprecated::StakeArgs), } impl JsCmd { @@ -55,6 +59,9 @@ impl JsCmd { Self::Send(args) => args.to_cli_args(network), Self::TxStatus(args) => args.to_cli_args(network), + + Self::Validators(args) => args.to_cli_args(network), + Self::Stake(args) => args.to_cli_args(network), } } } From 01139b673f4d88533641f3f233933a173e4b6e41 Mon Sep 17 00:00:00 2001 From: gagdiez Date: Tue, 30 Jul 2024 12:56:11 +0200 Subject: [PATCH 6/8] chore: format --- src/js_command_match/deprecated.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/js_command_match/deprecated.rs b/src/js_command_match/deprecated.rs index 40c6be264..73f76b756 100644 --- a/src/js_command_match/deprecated.rs +++ b/src/js_command_match/deprecated.rs @@ -17,14 +17,14 @@ const DEPRECATED: &str = "The command you tried to run has been moved into its o impl ValidatorsArgs { pub fn to_cli_args(&self, _network_config: String) -> Vec { - eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); - vec!["near-validator".to_string()] + eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); + vec!["near-validator".to_string()] } } impl StakeArgs { pub fn to_cli_args(&self, _network_config: String) -> Vec { - eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); - vec!["near-validator".to_string()] + eprintln!("\n{}\n", DEPRECATED.to_string().yellow()); + vec!["near-validator".to_string()] } -} \ No newline at end of file +} From 2763629b6ef06288cca866adbdd002e1c5dc15d2 Mon Sep 17 00:00:00 2001 From: gagdiez Date: Tue, 30 Jul 2024 12:58:39 +0200 Subject: [PATCH 7/8] fix: tests --- src/js_command_match/contract/view.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js_command_match/contract/view.rs b/src/js_command_match/contract/view.rs index 028c28d66..045da08a8 100644 --- a/src/js_command_match/contract/view.rs +++ b/src/js_command_match/contract/view.rs @@ -45,15 +45,15 @@ mod tests { for (input, expected_output) in [ ( format!("near view counter.near-examples.testnet get '{args}'"), - format!("contract call-function as-read-only counter.near-examples.testnet get text-args '{args}' network-config testnet now") + format!("contract call-function as-read-only counter.near-examples.testnet get json-args '{args}' network-config testnet now") ), ( format!("near view counter.near-examples.testnet get '{args}' --{} testnet", NETWORK_ID_ALIASES[0]), - format!("contract call-function as-read-only counter.near-examples.testnet get text-args '{args}' network-config testnet now") + format!("contract call-function as-read-only counter.near-examples.testnet get json-args '{args}' network-config testnet now") ), ( format!("near view counter.near-examples.testnet get '{args}' --{} mainnet", NETWORK_ID_ALIASES[1]), - format!("contract call-function as-read-only counter.near-examples.testnet get text-args '{args}' network-config mainnet now") + format!("contract call-function as-read-only counter.near-examples.testnet get json-args '{args}' network-config mainnet now") ), ] { let input_cmd = shell_words::split(&input).expect("Input command must be a valid shell command"); From 51006ac1676f1dd76f6ce948a105e4b0f4e293a4 Mon Sep 17 00:00:00 2001 From: Vlad Frolov Date: Tue, 30 Jul 2024 13:55:03 +0200 Subject: [PATCH 8/8] Added `validator-stake` alias to `stake` command --- src/js_command_match/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js_command_match/mod.rs b/src/js_command_match/mod.rs index 0d58706dc..186313da1 100644 --- a/src/js_command_match/mod.rs +++ b/src/js_command_match/mod.rs @@ -33,6 +33,7 @@ pub enum JsCmd { TxStatus(self::transactions::status::TxStatusArgs), Validators(self::deprecated::ValidatorsArgs), + #[clap(alias("validator-stake"))] Stake(self::deprecated::StakeArgs), }