From 0adf4df094049dec0401d4487cae609ca3e9a053 Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Thu, 22 Sep 2022 17:26:37 +0200 Subject: [PATCH] Fig and shell completions (#1638) * Fig and shell completions lib * Complete all the things --- Cargo.lock | 15 ++ Cargo.toml | 1 + clients/credential/Cargo.toml | 3 +- clients/credential/src/commands.rs | 7 + clients/credential/src/main.rs | 6 + clients/native/Cargo.toml | 3 +- clients/native/src/commands/mod.rs | 12 ++ clients/socks5/Cargo.toml | 3 +- clients/socks5/src/commands/mod.rs | 12 ++ common/completions/Cargo.toml | 11 ++ common/completions/src/lib.rs | 58 +++++++ contracts/CHANGELOG.md | 3 + explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 3 +- gateway/src/commands/mod.rs | 12 ++ mixnode/Cargo.toml | 3 +- mixnode/src/commands/mod.rs | 12 ++ nym-connect/Cargo.lock | 29 ++++ nym-wallet/nym-wallet-recovery-cli/Cargo.toml | 2 +- .../network-requester/Cargo.toml | 3 +- .../network-requester/src/main.rs | 145 ++++++++++-------- tools/nym-cli/Cargo.toml | 6 +- 22 files changed, 278 insertions(+), 73 deletions(-) create mode 100644 common/completions/Cargo.toml create mode 100644 common/completions/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 4534ee11cd..dcc1c361cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -681,6 +681,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "completions" +version = "0.1.0" +dependencies = [ + "clap 3.2.8", + "clap_complete", + "clap_complete_fig", +] + [[package]] name = "config" version = "0.1.0" @@ -919,6 +928,7 @@ dependencies = [ "cfg-if 0.1.10", "clap 3.2.8", "coconut-interface", + "completions", "config", "credential-storage", "credentials", @@ -3236,6 +3246,7 @@ dependencies = [ "clap 3.2.8", "client-core", "coconut-interface", + "completions", "config", "credential-storage", "credentials", @@ -3275,6 +3286,7 @@ dependencies = [ "clap 3.2.8", "coconut-interface", "colored", + "completions", "config", "credentials", "crypto", @@ -3317,6 +3329,7 @@ dependencies = [ "bs58", "clap 3.2.8", "colored", + "completions", "config", "crypto", "cupid", @@ -3355,6 +3368,7 @@ version = "1.0.2" dependencies = [ "async-trait", "clap 3.2.8", + "completions", "dirs", "futures", "ipnetwork", @@ -3400,6 +3414,7 @@ dependencies = [ "clap 3.2.8", "client-core", "coconut-interface", + "completions", "config", "credential-storage", "credentials", diff --git a/Cargo.toml b/Cargo.toml index b6c45da88b..fb3a7d491e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ members = [ "common/topology", "common/types", "common/wasm-utils", + "common/completions", "explorer-api", "gateway", "gateway/gateway-requests", diff --git a/clients/credential/Cargo.toml b/clients/credential/Cargo.toml index 74311917e6..078ada1f52 100644 --- a/clients/credential/Cargo.toml +++ b/clients/credential/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" async-trait = "0.1.52" bip39 = "1.0.1" cfg-if = "0.1" -clap = { version = "3.0.10", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } pickledb = "0.4.1" rand = "0.7.3" serde = { version = "1.0", features = ["derive"] } @@ -19,6 +19,7 @@ tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal", "m coconut-interface = { path = "../../common/coconut-interface" } config = { path = "../../common/config" } +completions = { path = "../../common/completions" } credentials = { path = "../../common/credentials" } credential-storage = { path = "../../common/credential-storage" } crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] } diff --git a/clients/credential/src/commands.rs b/clients/credential/src/commands.rs index c586b4a3e8..c281332810 100644 --- a/clients/credential/src/commands.rs +++ b/clients/credential/src/commands.rs @@ -3,6 +3,7 @@ use async_trait::async_trait; use clap::{Args, Subcommand}; +use completions::ArgShell; use pickledb::PickleDb; use rand::rngs::OsRng; use std::str::FromStr; @@ -28,6 +29,12 @@ pub(crate) enum Commands { ListDeposits(ListDeposits), /// Get a credential for a given deposit GetCredential(GetCredential), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, } #[async_trait] diff --git a/clients/credential/src/main.rs b/clients/credential/src/main.rs index 88e20f3da2..a3d286f09f 100644 --- a/clients/credential/src/main.rs +++ b/clients/credential/src/main.rs @@ -12,6 +12,8 @@ cfg_if::cfg_if! { use commands::{Commands, Execute}; use error::Result; use network_defaults::setup_env; + use clap::CommandFactory; + use completions::fig_generate; use clap::Parser; use pickledb::{PickleDb, PickleDbDumpPolicy, SerializationMethod}; @@ -52,10 +54,14 @@ cfg_if::cfg_if! { ), }; + let bin_name = "nym-credential-client"; + match &args.command { Commands::Deposit(m) => m.execute(&mut db, shared_storage).await?, Commands::ListDeposits(m) => m.execute(&mut db, shared_storage).await?, Commands::GetCredential(m) => m.execute(&mut db, shared_storage).await?, + Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name) } Ok(()) diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 0904d7ee01..da9cd342b3 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -20,7 +20,7 @@ futures = "0.3" # bunch of futures stuff, however, now that I think about it, it # and the single instance of abortable we have should really be refactored anyway url = "2.2" -clap = { version = "3.2.8", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } dirs = "4.0" log = "0.4" # self explanatory pretty_env_logger = "0.4" # for formatting log messages @@ -34,6 +34,7 @@ tokio-tungstenite = "0.14" # websocket client-core = { path = "../client-core" } coconut-interface = { path = "../../common/coconut-interface", optional = true } config = { path = "../../common/config" } +completions = { path = "../../common/completions" } credential-storage = { path = "../../common/credential-storage" } credentials = { path = "../../common/credentials", optional = true } crypto = { path = "../../common/crypto" } diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 9f95b7945c..fdbf7ff5bf 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::config::{Config, SocketType}; +use clap::CommandFactory; use clap::{Parser, Subcommand}; +use completions::{fig_generate, ArgShell}; pub(crate) mod init; pub(crate) mod run; @@ -62,6 +64,12 @@ pub(crate) enum Commands { Run(run::Run), /// Try to upgrade the client Upgrade(upgrade::Upgrade), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, } // Configuration that can be overridden. @@ -76,10 +84,14 @@ pub(crate) struct OverrideConfig { } pub(crate) async fn execute(args: &Cli) { + let bin_name = "nym-native-client"; + match &args.command { Commands::Init(m) => init::execute(m).await, Commands::Run(m) => run::execute(m).await, Commands::Upgrade(m) => upgrade::execute(m), + Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name), } } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index e9091ea4e8..78325d01d1 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -11,7 +11,7 @@ name = "nym_socks5" path = "src/lib.rs" [dependencies] -clap = { version = "3.2.8", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } dirs = "4.0" futures = "0.3" log = "0.4" @@ -27,6 +27,7 @@ url = "2.2" client-core = { path = "../client-core" } coconut-interface = { path = "../../common/coconut-interface", optional = true } config = { path = "../../common/config" } +completions = { path = "../../common/completions" } credential-storage = { path = "../../common/credential-storage" } credentials = { path = "../../common/credentials", optional = true } crypto = { path = "../../common/crypto" } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 651f88bab2..dbed90777f 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::config::Config; +use clap::CommandFactory; use clap::{Parser, Subcommand}; +use completions::{fig_generate, ArgShell}; use config::parse_validators; pub mod init; @@ -63,6 +65,12 @@ pub(crate) enum Commands { Run(run::Run), /// Try to upgrade the client Upgrade(upgrade::Upgrade), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, } // Configuration that can be overridden. @@ -76,10 +84,14 @@ pub(crate) struct OverrideConfig { } pub(crate) async fn execute(args: &Cli) { + let bin_name = "nym-socks5-client"; + match &args.command { Commands::Init(m) => init::execute(m).await, Commands::Run(m) => run::execute(m).await, Commands::Upgrade(m) => upgrade::execute(m), + Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name), } } diff --git a/common/completions/Cargo.toml b/common/completions/Cargo.toml new file mode 100644 index 0000000000..ace1f76e7f --- /dev/null +++ b/common/completions/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "completions" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "3.2", features = ["derive"] } +clap_complete = "3.2" +clap_complete_fig = "3.2" \ No newline at end of file diff --git a/common/completions/src/lib.rs b/common/completions/src/lib.rs new file mode 100644 index 0000000000..8526c18d4f --- /dev/null +++ b/common/completions/src/lib.rs @@ -0,0 +1,58 @@ +use clap::builder::Command; +use clap::clap_derive::ArgEnum; +use clap::Args; +use clap_complete::generator::generate; +use clap_complete::Shell as ClapShell; +use std::io; + +pub fn fig_generate(command: &mut Command, name: &str) { + clap_complete::generate( + clap_complete_fig::Fig, + command, + name, + &mut std::io::stdout(), + ) +} + +#[derive(ArgEnum, Copy, Clone)] +pub enum Shell { + Bash, + Elvish, + Fish, + PowerShell, + Zsh, +} + +#[derive(Args, Copy, Clone)] +pub struct ArgShell { + #[clap(arg_enum, value_name = "SHELL")] + shell: Shell, +} + +impl ArgShell { + pub fn generate(&self, command: &mut Command, name: &str) { + self.shell.generate(command, name) + } +} + +impl Shell { + pub fn generate(&self, command: &mut Command, name: &str) { + match &self { + Self::Bash => { + generate(ClapShell::Bash, command, name, &mut io::stdout()); + } + Self::Elvish => { + generate(ClapShell::Elvish, command, name, &mut io::stdout()); + } + Self::Fish => { + generate(ClapShell::Fish, command, name, &mut io::stdout()); + } + Self::PowerShell => { + generate(ClapShell::PowerShell, command, name, &mut io::stdout()); + } + Self::Zsh => { + generate(ClapShell::Zsh, command, name, &mut io::stdout()); + } + } + } +} diff --git a/contracts/CHANGELOG.md b/contracts/CHANGELOG.md index 38fbe32341..0050b844a1 100644 --- a/contracts/CHANGELOG.md +++ b/contracts/CHANGELOG.md @@ -3,10 +3,12 @@ ### Added - vesting-contract: added queries for delegation timestamps and paged query for all vesting delegations in the contract ([#1569]) +- all binaries: added shell completion and [Fig](fig.io) spec generation ([#1638]) ### Changed - mixnet-contract: compounding delegator rewards now happens instantaneously as opposed to having to wait for the current epoch to finish ([#1571]) +- network-requester: updated CLI to use `clap` macros ([#1638]) ### Fixed @@ -18,6 +20,7 @@ [#1569]: https://github.com/nymtech/nym/pull/1569 [#1569]: https://github.com/nymtech/nym/pull/1571 [#1613]: https://github.com/nymtech/nym/pull/1613 +[#1638]: https://github.com/nymtech/nym/pull/1638 ## [nym-contracts-v1.0.1](https://github.com/nymtech/nym/tree/nym-contracts-v1.0.1) (2022-06-22) diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index f65a46db03..2e4f4fbef4 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] chrono = { version = "0.4.19", features = ["serde"] } -clap = { version = "3.2.8", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } humantime-serde = "1.0" isocountry = "0.3.2" itertools = "0.10.3" diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index adf98f871d..f1876961bb 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -19,7 +19,7 @@ anyhow = "1.0.53" async-trait = { version = "0.1.51" } bip39 = "1.0.1" bs58 = "0.4.0" -clap = { version = "3.0.10", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } colored = "2.0" dashmap = "4.0" dirs = "4.0" @@ -55,6 +55,7 @@ coconut-interface = { path = "../common/coconut-interface", optional = true } credentials = { path = "../common/credentials" } config = { path = "../common/config" } crypto = { path = "../common/crypto" } +completions = { path = "../common/completions" } gateway-requests = { path = "gateway-requests" } mixnet-client = { path = "../common/client-libs/mixnet-client" } mixnode-common = { path = "../common/mixnode-common" } diff --git a/gateway/src/commands/mod.rs b/gateway/src/commands/mod.rs index 14c90031fd..cf3bb33273 100644 --- a/gateway/src/commands/mod.rs +++ b/gateway/src/commands/mod.rs @@ -4,8 +4,10 @@ use std::{process, str::FromStr}; use crate::{config::Config, Cli}; +use clap::CommandFactory; use clap::Subcommand; use colored::Colorize; +use completions::{fig_generate, ArgShell}; use config::parse_validators; use crypto::bech32_address_validation; use network_defaults::var_names::{ @@ -34,6 +36,12 @@ pub(crate) enum Commands { /// Try to upgrade the gateway Upgrade(upgrade::Upgrade), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, } // Configuration that can be overridden. @@ -55,12 +63,16 @@ pub(crate) struct OverrideConfig { } pub(crate) async fn execute(args: Cli) { + let bin_name = "nym-gateway"; + match &args.command { Commands::Init(m) => init::execute(m).await, Commands::NodeDetails(m) => node_details::execute(m).await, Commands::Run(m) => run::execute(m).await, Commands::Sign(m) => sign::execute(m), Commands::Upgrade(m) => upgrade::execute(m).await, + Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name), } } diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 259649ce0b..52b0999426 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.58.1" [dependencies] anyhow = "1.0.40" bs58 = "0.4.0" -clap = { version = "3.0.10", features = ["cargo", "derive"] } +clap = { version = "3.2", features = ["cargo", "derive"] } colored = "2.0" cupid = "0.6.1" dirs = "4.0" @@ -40,6 +40,7 @@ url = { version = "2.2", features = ["serde"] } ## internal config = { path="../common/config" } crypto = { path="../common/crypto" } +completions = { path="../common/completions" } mixnet-client = { path="../common/client-libs/mixnet-client" } mixnode-common = { path="../common/mixnode-common" } nonexhaustive-delayqueue = { path="../common/nonexhaustive-delayqueue" } diff --git a/mixnode/src/commands/mod.rs b/mixnode/src/commands/mod.rs index 62468ca809..f87850165a 100644 --- a/mixnode/src/commands/mod.rs +++ b/mixnode/src/commands/mod.rs @@ -4,8 +4,10 @@ use std::process; use crate::{config::Config, Cli}; +use clap::CommandFactory; use clap::Subcommand; use colored::Colorize; +use completions::{fig_generate, ArgShell}; use config::{ defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED}, parse_validators, @@ -38,6 +40,12 @@ pub(crate) enum Commands { /// Show details of this mixnode NodeDetails(node_details::NodeDetails), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, } // Configuration that can be overridden. @@ -53,6 +61,8 @@ struct OverrideConfig { } pub(crate) async fn execute(args: Cli) { + let bin_name = "nym-mixnode"; + match &args.command { Commands::Describe(m) => describe::execute(m), Commands::Init(m) => init::execute(m), @@ -60,6 +70,8 @@ pub(crate) async fn execute(args: Cli) { Commands::Sign(m) => sign::execute(m), Commands::Upgrade(m) => upgrade::execute(m), Commands::NodeDetails(m) => node_details::execute(m), + Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name), } } diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 7b443309c5..2dd92b4fd0 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -571,6 +571,25 @@ dependencies = [ "textwrap", ] +[[package]] +name = "clap_complete" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_fig" +version = "3.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9" +dependencies = [ + "clap", + "clap_complete", +] + [[package]] name = "clap_derive" version = "3.2.18" @@ -708,6 +727,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "completions" +version = "0.1.0" +dependencies = [ + "clap", + "clap_complete", + "clap_complete_fig", +] + [[package]] name = "config" version = "0.1.0" @@ -3347,6 +3375,7 @@ version = "1.0.2" dependencies = [ "clap", "client-core", + "completions", "config", "credential-storage", "crypto", diff --git a/nym-wallet/nym-wallet-recovery-cli/Cargo.toml b/nym-wallet/nym-wallet-recovery-cli/Cargo.toml index ff74de6709..e4ac1eb284 100644 --- a/nym-wallet/nym-wallet-recovery-cli/Cargo.toml +++ b/nym-wallet/nym-wallet-recovery-cli/Cargo.toml @@ -11,7 +11,7 @@ anyhow = "1.0" argon2 = "0.4" base64 = "0.13" bip39 = "1.0" -clap = { version = "3.2.20", features = ["derive"] } +clap = { version = "3.2", features = ["derive"] } log = "0.4" pretty_env_logger = "0.4" serde_json = "1.0.0" diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 1806a75ac4..e4174de920 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" [dependencies] async-trait = { version = "0.1.51" } -clap = "3.2" +clap = {version = "3.2", features = ["derive"]} dirs = "4.0" futures = "0.3.24" ipnetwork = "0.20.0" @@ -30,6 +30,7 @@ tokio-tungstenite = "0.17.2" # internal network-defaults = { path = "../../common/network-defaults" } nymsphinx = { path = "../../common/nymsphinx" } +completions = { path = "../../common/completions" } ordered-buffer = {path = "../../common/socks5/ordered-buffer"} proxy-helpers = { path = "../../common/socks5/proxy-helpers" } socks5-requests = { path = "../../common/socks5/requests" } diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 4f30fb77e8..ce1762f95b 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -1,7 +1,10 @@ // Copyright 2020 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use clap::{App, Arg, ArgMatches}; +use clap::CommandFactory; +use clap::Subcommand; +use clap::{Args, Parser}; +use completions::{fig_generate, ArgShell}; use network_defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use nymsphinx::addressing::clients::Recipient; @@ -12,75 +15,93 @@ mod core; mod statistics; mod websocket; -const OPEN_PROXY_ARG: &str = "open-proxy"; -const WS_PORT: &str = "websocket-port"; const ENABLE_STATISTICS: &str = "enable-statistics"; -const STATISTICS_RECIPIENT: &str = "statistics-recipient"; -fn parse_args() -> ArgMatches { - App::new("Nym Network Requester") - .version(env!("CARGO_PKG_VERSION")) - .author("Nymtech") - .arg( - Arg::with_name(OPEN_PROXY_ARG) - .help("specifies whether this network requester should run in 'open-proxy' mode") - .long(OPEN_PROXY_ARG) - .short('o'), - ) - .arg( - Arg::with_name(WS_PORT) - .help("websocket port to bind to") - .long(WS_PORT) - .short('p') - .takes_value(true), - ) - .arg( - Arg::with_name(ENABLE_STATISTICS) - .help("enable service anonymized statistics that get sent to a statistics aggregator server") - .long(ENABLE_STATISTICS), - ) - .arg( - Arg::with_name(STATISTICS_RECIPIENT) - .help("mixnet client address where a statistics aggregator is running. The default value is a Nym aggregator client") - .long(STATISTICS_RECIPIENT) - .requires(ENABLE_STATISTICS) - .takes_value(true), - ) - .get_matches() +#[derive(Args)] +struct Run { + /// Specifies whether this network requester should run in 'open-proxy' mode + open_proxy: bool, + + /// Websocket port to bind to + websocket_port: Option, + + /// Enable service anonymized statistics that get sent to a statistics aggregator server + enable_statistics: bool, + + /// Mixnet client address where a statistics aggregator is running. The default value is a Nym aggregator client + statistics_recipient: Option, +} + +impl Run { + async fn execute(&self) { + if self.open_proxy { + println!("\n\nYOU HAVE STARTED IN 'OPEN PROXY' MODE. ANYONE WITH YOUR CLIENT ADDRESS CAN MAKE REQUESTS FROM YOUR MACHINE. PLEASE QUIT IF YOU DON'T UNDERSTAND WHAT YOU'RE DOING.\n\n"); + } + + if self.enable_statistics { + println!("\n\nTHE NETWORK REQUESTER STATISTICS ARE ENABLED. IT WILL COLLECT AND SEND ANONYMIZED STATISTICS TO A CENTRAL SERVER. PLEASE QUIT IF YOU DON'T WANT THIS TO HAPPEN AND START WITHOUT THE {} FLAG .\n\n", ENABLE_STATISTICS); + } + + let stats_provider_addr = self + .statistics_recipient + .as_ref() + .map(Recipient::try_from_base58_string) + .transpose() + .unwrap_or(None); + + let uri = format!( + "ws://localhost:{}", + self.websocket_port + .as_ref() + .unwrap_or(&DEFAULT_WEBSOCKET_LISTENING_PORT.to_string()) + ); + + println!("Starting socks5 service provider:"); + let mut server = core::ServiceProvider::new( + uri, + self.open_proxy, + self.enable_statistics, + stats_provider_addr, + ); + server.run().await; + } +} + +#[derive(Subcommand)] +pub(crate) enum Commands { + /// Run network requester + Run(Run), + + /// Generate shell completions + Completions(ArgShell), + + /// Generate Fig specification + GenerateFigSpec, +} + +#[derive(Parser)] +#[clap(author = "Nymtech", version, about)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +pub(crate) async fn execute(args: Cli) { + let bin_name = "nym-network-requester"; + + match &args.command { + Commands::Run(r) => r.execute().await, + Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name), + Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name), + } } #[tokio::main] async fn main() { setup_logging(); - let matches = parse_args(); + let args = Cli::parse(); - let open_proxy = matches.is_present(OPEN_PROXY_ARG); - if open_proxy { - println!("\n\nYOU HAVE STARTED IN 'OPEN PROXY' MODE. ANYONE WITH YOUR CLIENT ADDRESS CAN MAKE REQUESTS FROM YOUR MACHINE. PLEASE QUIT IF YOU DON'T UNDERSTAND WHAT YOU'RE DOING.\n\n"); - } - - let enable_statistics = matches.is_present(ENABLE_STATISTICS); - if enable_statistics { - println!("\n\nTHE NETWORK REQUESTER STATISTICS ARE ENABLED. IT WILL COLLECT AND SEND ANONYMIZED STATISTICS TO A CENTRAL SERVER. PLEASE QUIT IF YOU DON'T WANT THIS TO HAPPEN AND START WITHOUT THE {} FLAG .\n\n", ENABLE_STATISTICS); - } - - let stats_provider_addr = matches - .value_of(STATISTICS_RECIPIENT) - .map(Recipient::try_from_base58_string) - .transpose() - .unwrap_or(None); - - let uri = format!( - "ws://localhost:{}", - matches - .value_of(WS_PORT) - .unwrap_or(&DEFAULT_WEBSOCKET_LISTENING_PORT.to_string()) - ); - - println!("Starting socks5 service provider:"); - let mut server = - core::ServiceProvider::new(uri, open_proxy, enable_statistics, stats_provider_addr); - server.run().await; + execute(args).await; } fn setup_logging() { diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index fe7a243f85..dcc92dfc36 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -7,9 +7,9 @@ edition = "2021" [dependencies] base64 = "0.13.0" bs58 = "0.4" -clap = { version = "3.2.8", features = ["derive"] } -clap_complete = "3.2.4" -clap_complete_fig = "3.2.4" +clap = { version = "3.2", features = ["derive"] } +clap_complete = "3.2" +clap_complete_fig = "3.2" dotenv = "0.15.0" log = "0.4" pretty_env_logger = "0.4"