diff --git a/ant-cli/Cargo.toml b/ant-cli/Cargo.toml index 489c0c8fb0..0239975d03 100644 --- a/ant-cli/Cargo.toml +++ b/ant-cli/Cargo.toml @@ -17,6 +17,7 @@ path = "src/main.rs" default = ["metrics"] local = ["ant-bootstrap/local", "autonomi/local"] metrics = ["ant-logging/process-metrics"] +nightly = [] [[bench]] name = "files" diff --git a/ant-cli/src/commands.rs b/ant-cli/src/commands.rs index 6c6316d3cd..ff065a06c0 100644 --- a/ant-cli/src/commands.rs +++ b/ant-cli/src/commands.rs @@ -187,7 +187,7 @@ pub async fn handle_subcommand(opt: Opt) -> Result<()> { let cmd = opt.command; match cmd { - SubCmd::File { command } => match command { + Some(SubCmd::File { command }) => match command { FileCmd::Cost { file } => file::cost(&file, peers.await?).await, FileCmd::Upload { file, public } => file::upload(&file, public, peers.await?).await, FileCmd::Download { addr, dest_file } => { @@ -195,7 +195,7 @@ pub async fn handle_subcommand(opt: Opt) -> Result<()> { } FileCmd::List => file::list(), }, - SubCmd::Register { command } => match command { + Some(SubCmd::Register { command }) => match command { RegisterCmd::GenerateKey { overwrite } => register::generate_key(overwrite), RegisterCmd::Cost { name } => register::cost(&name, peers.await?).await, RegisterCmd::Create { @@ -211,13 +211,13 @@ pub async fn handle_subcommand(opt: Opt) -> Result<()> { RegisterCmd::Get { address, name } => register::get(address, name, peers.await?).await, RegisterCmd::List => register::list(), }, - SubCmd::Vault { command } => match command { + Some(SubCmd::Vault { command }) => match command { VaultCmd::Cost => vault::cost(peers.await?).await, VaultCmd::Create => vault::create(peers.await?).await, VaultCmd::Load => vault::load(peers.await?).await, VaultCmd::Sync { force } => vault::sync(peers.await?, force).await, }, - SubCmd::Wallet { command } => match command { + Some(SubCmd::Wallet { command }) => match command { WalletCmd::Create { no_password, password, @@ -230,5 +230,6 @@ pub async fn handle_subcommand(opt: Opt) -> Result<()> { WalletCmd::Export => wallet::export(), WalletCmd::Balance => wallet::balance().await, }, + None => Ok(()), } } diff --git a/ant-cli/src/main.rs b/ant-cli/src/main.rs index c0404e9f75..279a354e5d 100644 --- a/ant-cli/src/main.rs +++ b/ant-cli/src/main.rs @@ -27,6 +27,7 @@ use color_eyre::Result; #[cfg(feature = "metrics")] use ant_logging::metrics::init_metrics; use ant_logging::{LogBuilder, LogFormat, ReloadHandle, WorkerGuard}; +use ant_protocol::version; use opt::Opt; use tracing::Level; @@ -37,15 +38,47 @@ async fn main() -> Result<()> { if let Some(network_id) = opt.network_id { ant_protocol::version::set_network_id(network_id); } + + // The clone is necessary to resolve a clippy warning related to a mutex. + let identify_protocol_str = version::IDENTIFY_PROTOCOL_STR + .read() + .expect("Failed to obtain read lock for IDENTIFY_PROTOCOL_STR") + .clone(); + if opt.version { + println!( + "{}", + ant_build_info::version_string( + "Autonomi Client", + env!("CARGO_PKG_VERSION"), + Some(&identify_protocol_str) + ) + ); + return Ok(()); + } + + if opt.crate_version { + println!("Crate version: {}", env!("CARGO_PKG_VERSION")); + return Ok(()); + } + + if opt.protocol_version { + println!("Network version: {identify_protocol_str}"); + return Ok(()); + } + + #[cfg(not(feature = "nightly"))] + if opt.package_version { + println!("Package version: {}", ant_build_info::package_version()); + return Ok(()); + } + let _log_guards = init_logging_and_metrics(&opt)?; #[cfg(feature = "metrics")] tokio::spawn(init_metrics(std::process::id())); - // Log the full command that was run and the git version info!("\"{}\"", std::env::args().collect::>().join(" ")); let version = ant_build_info::git_info(); info!("autonomi client built with git version: {version}"); - println!("autonomi client built with git version: {version}"); commands::handle_subcommand(opt).await?; diff --git a/ant-cli/src/opt.rs b/ant-cli/src/opt.rs index 3ffa1eb5f6..9d7e4edd9b 100644 --- a/ant-cli/src/opt.rs +++ b/ant-cli/src/opt.rs @@ -16,8 +16,29 @@ use std::time::Duration; // Please do not remove the blank lines in these doc comments. // They are used for inserting line breaks when the help menu is rendered in the UI. #[derive(Parser)] +#[command(disable_version_flag = true)] #[command(author, version, about, long_about = None)] pub(crate) struct Opt { + /// Available sub commands. + #[clap(subcommand)] + pub command: Option, + + /// The maximum duration to wait for a connection to the network before timing out. + #[clap(long = "timeout", global = true, value_parser = |t: &str| -> Result { Ok(t.parse().map(Duration::from_secs)?) })] + pub connection_timeout: Option, + + /// Print the crate version. + #[clap(long)] + pub crate_version: bool, + + /// Specify the logging format. + /// + /// Valid values are "default" or "json". + /// + /// If the argument is not used, the default format will be applied. + #[clap(long, value_parser = LogFormat::parse_from_str, verbatim_doc_comment)] + pub log_format: Option, + /// Specify the logging output destination. /// /// Valid values are "stdout", "data-dir", or a custom path. @@ -32,25 +53,6 @@ pub(crate) struct Opt { #[clap(long, value_parser = LogOutputDest::parse_from_str, verbatim_doc_comment, default_value = "data-dir")] pub log_output_dest: LogOutputDest, - /// Specify the logging format. - /// - /// Valid values are "default" or "json". - /// - /// If the argument is not used, the default format will be applied. - #[clap(long, value_parser = LogFormat::parse_from_str, verbatim_doc_comment)] - pub log_format: Option, - - #[command(flatten)] - pub(crate) peers: PeersArgs, - - /// Available sub commands. - #[clap(subcommand)] - pub command: SubCmd, - - /// The maximum duration to wait for a connection to the network before timing out. - #[clap(long = "timeout", global = true, value_parser = |t: &str| -> Result { Ok(t.parse().map(Duration::from_secs)?) })] - pub connection_timeout: Option, - /// Specify the network ID to use. This will allow you to run the CLI on a different network. /// /// By default, the network ID is set to 1, which represents the mainnet. @@ -62,4 +64,20 @@ pub(crate) struct Opt { /// This may increase operation speed, but offers no guarantees that operations were successful. #[clap(global = true, long = "no-verify", short = 'x')] pub no_verify: bool, + + #[command(flatten)] + pub(crate) peers: PeersArgs, + + /// Print the package version. + #[cfg(not(feature = "nightly"))] + #[clap(long)] + pub package_version: bool, + + /// Print the network protocol version. + #[clap(long)] + pub protocol_version: bool, + + /// Print version information. + #[clap(long)] + pub version: bool, }