From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 489A962B2E for ; Tue, 24 Nov 2020 12:48:05 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 38C30B790 for ; Tue, 24 Nov 2020 12:47:35 +0100 (CET) Received: from elsa.proxmox.com (212-186-127-178.static.upcbusiness.at [212.186.127.178]) by firstgate.proxmox.com (Proxmox) with ESMTP id A617AB788 for ; Tue, 24 Nov 2020 12:47:34 +0100 (CET) Received: by elsa.proxmox.com (Postfix, from userid 0) id 7CB95AEA312; Tue, 24 Nov 2020 12:47:34 +0100 (CET) From: Dietmar Maurer To: pbs-devel@lists.proxmox.com Date: Tue, 24 Nov 2020 12:47:23 +0100 Message-Id: <20201124114723.18414-1-dietmar@proxmox.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -1.037 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [mod.rs, command.rs] Subject: [pbs-devel] [PATCH proxmox] implement cli command alias feature X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Nov 2020 11:48:05 -0000 --- proxmox/src/api/cli/command.rs | 28 +++++++++++++++++++++++++++- proxmox/src/api/cli/mod.rs | 6 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/proxmox/src/api/cli/command.rs b/proxmox/src/api/cli/command.rs index 89dfdf1..b043175 100644 --- a/proxmox/src/api/cli/command.rs +++ b/proxmox/src/api/cli/command.rs @@ -156,6 +156,8 @@ fn parse_nested_command<'a>( // Note: Avoid async recursive function, because current rust compiler cant handle that loop { + replace_aliases(args, &map.aliases); + if args.is_empty() { let mut cmds: Vec<&String> = map.commands.keys().collect(); cmds.sort(); @@ -173,6 +175,7 @@ fn parse_nested_command<'a>( return Err(format_err!("{}", err_msg)); } + let command = args.remove(0); let (_, sub_cmd) = match map.find_command(&command) { @@ -228,7 +231,7 @@ fn help_command( _info: &ApiMethod, _rpcenv: &mut dyn RpcEnvironment, ) -> Result { - let command: Vec = param["command"] + let mut command: Vec = param["command"] .as_array() .unwrap_or(&Vec::new()) .iter() @@ -239,6 +242,9 @@ fn help_command( HELP_CONTEXT.with(|ctx| match &*ctx.borrow() { Some(def) => { + if let CommandLineInterface::Nested(map) = def.as_ref() { + replace_aliases(&mut command, &map.aliases); + } print_help(def, String::from(""), &command, verbose); } None => { @@ -259,6 +265,26 @@ pub(crate) fn help_command_def() -> CliCommand { CliCommand::new(&API_METHOD_COMMAND_HELP).arg_param(&["command"]) } +fn replace_aliases( + args: &mut Vec, + aliases: &Vec<(Vec<&'static str>, Vec<&'static str>)>, +) { + for (old, new) in aliases { + if args.len() < old.len() { continue; } + if old[..] == args[..old.len()] { + let new_args: Vec = new.iter() + .map(|s| String::from(*s)).collect(); + let rest = args.split_off(old.len()); + args.truncate(0); + args.extend(new_args); + for arg in rest.iter() { + args.push(arg.clone()); + } + return; + } + } +} + /// Handle command invocation. /// /// This command gets the command line ``args`` and tries to invoke diff --git a/proxmox/src/api/cli/mod.rs b/proxmox/src/api/cli/mod.rs index 86e1d39..71ecd46 100644 --- a/proxmox/src/api/cli/mod.rs +++ b/proxmox/src/api/cli/mod.rs @@ -101,6 +101,7 @@ pub struct CliCommandMap { /// Each command has an unique name. The map associates names with /// command definitions. pub commands: HashMap, + pub aliases: Vec<(Vec<&'static str>, Vec<&'static str>)>, } impl CliCommandMap { @@ -115,6 +116,11 @@ impl CliCommandMap { self } + pub fn alias(mut self, old: &'static[&'static str], new: &'static[&'static str]) -> Self { + self.aliases.push((Vec::from(old), Vec::from(new))); + self + } + /// Insert the help command. pub fn insert_help(mut self) -> Self { self.commands -- 2.20.1