From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id C29341FF164 for <inbox@lore.proxmox.com>; Fri, 9 May 2025 14:11:19 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 5D8593C6BD; Fri, 9 May 2025 14:11:36 +0200 (CEST) From: Christoph Heiss <c.heiss@proxmox.com> To: pve-devel@lists.proxmox.com Date: Fri, 9 May 2025 14:09:13 +0200 Message-ID: <20250509121007.1430080-2-c.heiss@proxmox.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250509121007.1430080-1-c.heiss@proxmox.com> References: <20250509121007.1430080-1-c.heiss@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.028 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. 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. [cli.rs, lib.rs] Subject: [pve-devel] [PATCH installer 1/5] common: introduce simple cli subcommand parser based on pico-args X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> This is a very slight abstraction on top of pico-args, to reduce boilerplate code a bit for CLI subcommand handling. No functional changes. Signed-off-by: Christoph Heiss <c.heiss@proxmox.com> --- Cargo.toml | 1 + debian/control | 1 + proxmox-installer-common/Cargo.toml | 4 ++ proxmox-installer-common/src/cli.rs | 62 +++++++++++++++++++++++++++++ proxmox-installer-common/src/lib.rs | 3 ++ 5 files changed, 71 insertions(+) create mode 100644 proxmox-installer-common/src/cli.rs diff --git a/Cargo.toml b/Cargo.toml index bfec8f7..4165b96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ edition = "2024" [workspace.dependencies] anyhow = "1.0" log = "0.4.20" +pico-args = "0.5" regex = "1.7" serde = "1.0" serde_json = "1.0" diff --git a/debian/control b/debian/control index dec07ed..51c45a4 100644 --- a/debian/control +++ b/debian/control @@ -15,6 +15,7 @@ Build-Depends: cargo:native, librust-glob-0.3-dev, librust-hex-0.4-dev, librust-native-tls-dev, + librust-pico-args-0.5-dev, librust-pretty-assertions-1.4-dev, librust-regex-1+default-dev (>= 1.7~~), librust-rustls-0.21+dangerous-configuration-dev, diff --git a/proxmox-installer-common/Cargo.toml b/proxmox-installer-common/Cargo.toml index 4bdb2b0..8a6fb5c 100644 --- a/proxmox-installer-common/Cargo.toml +++ b/proxmox-installer-common/Cargo.toml @@ -22,6 +22,9 @@ rustls-native-certs = { version = "0.6", optional = true } sha2 = { version = "0.10", optional = true } ureq = { version = "2.6", features = [ "native-certs", "native-tls" ], optional = true } +# `cli` feature +pico-args = { workspace = true, optional = true } + [features] http = [ "dep:hex", @@ -31,6 +34,7 @@ http = [ "dep:sha2", "dep:ureq" ] +cli = [ "dep:pico-args" ] [dev-dependencies] pretty_assertions = "1.4" diff --git a/proxmox-installer-common/src/cli.rs b/proxmox-installer-common/src/cli.rs new file mode 100644 index 0000000..1539001 --- /dev/null +++ b/proxmox-installer-common/src/cli.rs @@ -0,0 +1,62 @@ +//! Provides a simple command line parsing interface, with special support for +//! (one-level deep) subcommands. + +use std::process; + +use anyhow::Result; + +pub use pico_args::Arguments; + +pub trait Subcommand { + /// Parses the arguments for this command from an [`pico_args::Arguments`]. + fn parse(args: &mut Arguments) -> Result<Self> + where + Self: Sized; + + /// Print command usage to stderr. + fn print_usage() + where + Self: Sized; + + /// Runs the commands action. + fn run(&self) -> Result<()>; +} + +pub struct AppInfo<'a> { + pub global_help: &'a str, + pub on_command: fn(Option<&str>, &mut Arguments) -> Result<()>, +} + +pub fn run(info: AppInfo) -> process::ExitCode { + if let Err(err) = parse_args(&info) { + eprintln!("Error: {err:#}\n\n{}", info.global_help); + process::ExitCode::FAILURE + } else { + process::ExitCode::SUCCESS + } +} + +fn parse_args(info: &AppInfo) -> Result<()> { + let mut args = pico_args::Arguments::from_env(); + let subcommand = args.subcommand()?; + + if subcommand.is_none() && args.contains(["-h", "--help"]) { + eprintln!("{}", info.global_help); + Ok(()) + } else if args.contains(["-V", "--version"]) { + eprintln!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")); + Ok(()) + } else { + (info.on_command)(subcommand.as_deref(), &mut args) + } +} + +pub fn handle_command<T: Subcommand>(args: &mut pico_args::Arguments) -> Result<()> { + if args.contains(["-h", "--help"]) { + T::print_usage(); + } else if let Err(err) = T::parse(args).and_then(|cmd| cmd.run()) { + eprint!("Error: {err:#}"); + } + + Ok(()) +} diff --git a/proxmox-installer-common/src/lib.rs b/proxmox-installer-common/src/lib.rs index 3dc3bfb..ea907a0 100644 --- a/proxmox-installer-common/src/lib.rs +++ b/proxmox-installer-common/src/lib.rs @@ -7,6 +7,9 @@ pub mod utils; #[cfg(feature = "http")] pub mod http; +#[cfg(feature = "cli")] +pub mod cli; + pub const RUNTIME_DIR: &str = "/run/proxmox-installer"; /// Default placeholder value for the administrator email address. -- 2.49.0 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel