From d84f367317a542da896d1607e2efa97769bcba6e Mon Sep 17 00:00:00 2001 From: Ryo Onodera Date: Tue, 12 Nov 2019 09:42:08 +0900 Subject: [PATCH] Extract duplicate clap helpers into clap-utils (#6812) --- Cargo.lock | 16 ++++++++- archiver/Cargo.toml | 1 + archiver/src/main.rs | 8 +---- clap-utils/Cargo.toml | 18 ++++++++++ {cli => clap-utils}/src/input_parsers.rs | 0 {cli => clap-utils}/src/input_validators.rs | 14 ++++++++ clap-utils/src/lib.rs | 2 ++ cli/Cargo.toml | 1 + cli/src/cli.rs | 6 ++-- cli/src/lib.rs | 2 -- cli/src/main.rs | 4 ++- cli/src/stake.rs | 12 +++---- cli/src/storage.rs | 11 +++--- cli/src/validator_info.rs | 8 +++-- cli/src/vote.rs | 12 +++---- gossip/Cargo.toml | 1 + gossip/src/main.rs | 8 +---- install/Cargo.toml | 2 +- install/src/lib.rs | 37 +-------------------- validator/Cargo.toml | 1 + validator/src/main.rs | 20 ++++------- 21 files changed, 89 insertions(+), 95 deletions(-) create mode 100644 clap-utils/Cargo.toml rename {cli => clap-utils}/src/input_parsers.rs (100%) rename {cli => clap-utils}/src/input_validators.rs (74%) create mode 100644 clap-utils/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3676a08819..8fccab963f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2993,6 +2993,7 @@ version = "0.21.0" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-clap-utils 0.21.0", "solana-core 0.21.0", "solana-logger 0.21.0", "solana-metrics 0.21.0", @@ -3174,6 +3175,16 @@ dependencies = [ "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "solana-clap-utils" +version = "0.21.0" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 0.21.0", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "solana-cli" version = "0.21.0" @@ -3197,6 +3208,7 @@ dependencies = [ "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "solana-budget-api 0.21.0", "solana-budget-program 0.21.0", + "solana-clap-utils 0.21.0", "solana-client 0.21.0", "solana-config-api 0.21.0", "solana-core 0.21.0", @@ -3471,6 +3483,7 @@ name = "solana-gossip" version = "0.21.0" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-clap-utils 0.21.0", "solana-client 0.21.0", "solana-core 0.21.0", "solana-logger 0.21.0", @@ -3496,11 +3509,11 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-clap-utils 0.21.0", "solana-client 0.21.0", "solana-config-api 0.21.0", "solana-logger 0.21.0", @@ -3966,6 +3979,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-clap-utils 0.21.0", "solana-client 0.21.0", "solana-core 0.21.0", "solana-drone 0.21.0", diff --git a/archiver/Cargo.toml b/archiver/Cargo.toml index 36eeba905a..ab337e065f 100644 --- a/archiver/Cargo.toml +++ b/archiver/Cargo.toml @@ -10,6 +10,7 @@ homepage = "https://solana.com/" [dependencies] clap = "2.33.0" console = "0.9.1" +solana-clap-utils = { path = "../clap-utils", version = "0.21.0" } solana-core = { path = "../core", version = "0.21.0" } solana-logger = { path = "../logger", version = "0.21.0" } solana-metrics = { path = "../metrics", version = "0.21.0" } diff --git a/archiver/src/main.rs b/archiver/src/main.rs index 3489aaa817..40db5b6f87 100644 --- a/archiver/src/main.rs +++ b/archiver/src/main.rs @@ -1,5 +1,6 @@ use clap::{crate_description, crate_name, crate_version, App, Arg}; use console::style; +use solana_clap_utils::input_validators::is_keypair; use solana_core::{ archiver::Archiver, cluster_info::{Node, VALIDATOR_PORT_RANGE}, @@ -11,13 +12,6 @@ use solana_sdk::{ }; use std::{net::SocketAddr, path::PathBuf, process::exit, sync::Arc}; -// Return an error if a keypair file cannot be parsed. -fn is_keypair(string: String) -> Result<(), String> { - read_keypair_file(&string) - .map(|_| ()) - .map_err(|err| format!("{:?}", err)) -} - fn main() { solana_logger::setup(); diff --git a/clap-utils/Cargo.toml b/clap-utils/Cargo.toml new file mode 100644 index 0000000000..6afcd978f0 --- /dev/null +++ b/clap-utils/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "solana-clap-utils" +version = "0.21.0" +description = "Solana utilities for the clap" +authors = ["Solana Maintainers "] +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" +homepage = "https://solana.com/" +edition = "2018" + +[dependencies] +clap = "2.33.0" +semver = "0.9.0" +solana-sdk = { path = "../sdk", version = "0.21.0" } +url = "2.1.0" + +[lib] +name = "solana_clap_utils" diff --git a/cli/src/input_parsers.rs b/clap-utils/src/input_parsers.rs similarity index 100% rename from cli/src/input_parsers.rs rename to clap-utils/src/input_parsers.rs diff --git a/cli/src/input_validators.rs b/clap-utils/src/input_validators.rs similarity index 74% rename from cli/src/input_validators.rs rename to clap-utils/src/input_validators.rs index 594a9a56dc..5b82765432 100644 --- a/cli/src/input_validators.rs +++ b/clap-utils/src/input_validators.rs @@ -34,3 +34,17 @@ pub fn is_url(string: String) -> Result<(), String> { Err(err) => Err(format!("{:?}", err)), } } + +pub fn is_semver(semver: &str) -> Result<(), String> { + match semver::Version::parse(&semver) { + Ok(_) => Ok(()), + Err(err) => Err(format!("{:?}", err)), + } +} + +pub fn is_release_channel(channel: &str) -> Result<(), String> { + match channel { + "edge" | "beta" | "stable" => Ok(()), + _ => Err(format!("Invalid release channel {}", channel)), + } +} diff --git a/clap-utils/src/lib.rs b/clap-utils/src/lib.rs new file mode 100644 index 0000000000..5fe313c4f7 --- /dev/null +++ b/clap-utils/src/lib.rs @@ -0,0 +1,2 @@ +pub mod input_parsers; +pub mod input_validators; diff --git a/cli/Cargo.toml b/cli/Cargo.toml index bb5c01356c..09c0742fc3 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,6 +27,7 @@ serde_derive = "1.0.102" serde_json = "1.0.41" serde_yaml = "0.8.11" solana-budget-api = { path = "../programs/budget_api", version = "0.21.0" } +solana-clap-utils = { path = "../clap-utils", version = "0.21.0" } solana-client = { path = "../client", version = "0.21.0" } solana-config-api = { path = "../programs/config_api", version = "0.21.0" } solana-drone = { path = "../drone", version = "0.21.0" } diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 16ff598b77..9dcf7a33a5 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -1,13 +1,14 @@ use crate::{ - cluster_query::*, display::println_name_value, input_parsers::*, input_validators::*, stake::*, - storage::*, validator_info::*, vote::*, + cluster_query::*, display::println_name_value, stake::*, storage::*, validator_info::*, vote::*, }; use chrono::prelude::*; use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; use log::*; use num_traits::FromPrimitive; use serde_json::{self, json, Value}; + use solana_budget_api::budget_instruction::{self, BudgetError}; +use solana_clap_utils::{input_parsers::*, input_validators::*}; use solana_client::{client_error::ClientError, rpc_client::RpcClient}; #[cfg(not(test))] use solana_drone::drone::request_airdrop_transaction; @@ -32,6 +33,7 @@ use solana_sdk::{ use solana_stake_api::stake_state::{Lockup, StakeAuthorize}; use solana_storage_api::storage_instruction::StorageAccountType; use solana_vote_api::vote_state::VoteAuthorize; + use std::{ fs::File, io::{Read, Write}, diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 0aa95a5b57..9555271a9d 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -5,8 +5,6 @@ pub mod cli; pub mod cluster_query; pub mod config; pub mod display; -pub mod input_parsers; -pub mod input_validators; pub mod stake; pub mod storage; pub mod validator_info; diff --git a/cli/src/main.rs b/cli/src/main.rs index bc07d2cac9..2ab5fea86c 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,12 +1,14 @@ use clap::{crate_description, crate_name, crate_version, Arg, ArgGroup, ArgMatches, SubCommand}; use console::style; + +use solana_clap_utils::input_validators::is_url; use solana_cli::{ cli::{app, parse_command, process_command, CliCommandInfo, CliConfig, CliError}, config::{self, Config}, display::{println_name_value, println_name_value_or}, - input_validators::is_url, }; use solana_sdk::signature::read_keypair_file; + use std::error; fn parse_settings(matches: &ArgMatches<'_>) -> Result> { diff --git a/cli/src/stake.rs b/cli/src/stake.rs index c04fe8c900..50d9a36c02 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -1,14 +1,10 @@ -use crate::{ - cli::{ - build_balance_message, check_account_for_fee, check_unique_pubkeys, - log_instruction_custom_error, CliCommand, CliCommandInfo, CliConfig, CliError, - ProcessResult, - }, - input_parsers::*, - input_validators::*, +use crate::cli::{ + build_balance_message, check_account_for_fee, check_unique_pubkeys, + log_instruction_custom_error, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult, }; use clap::{App, Arg, ArgMatches, SubCommand}; use console::style; +use solana_clap_utils::{input_parsers::*, input_validators::*}; use solana_client::rpc_client::RpcClient; use solana_sdk::signature::Keypair; use solana_sdk::{ diff --git a/cli/src/storage.rs b/cli/src/storage.rs index af252337f6..f944cb368a 100644 --- a/cli/src/storage.rs +++ b/cli/src/storage.rs @@ -1,12 +1,9 @@ -use crate::{ - cli::{ - check_account_for_fee, check_unique_pubkeys, log_instruction_custom_error, CliCommand, - CliCommandInfo, CliConfig, CliError, ProcessResult, - }, - input_parsers::*, - input_validators::*, +use crate::cli::{ + check_account_for_fee, check_unique_pubkeys, log_instruction_custom_error, CliCommand, + CliCommandInfo, CliConfig, CliError, ProcessResult, }; use clap::{App, Arg, ArgMatches, SubCommand}; +use solana_clap_utils::{input_parsers::*, input_validators::*}; use solana_client::rpc_client::RpcClient; use solana_sdk::signature::Keypair; use solana_sdk::{ diff --git a/cli/src/validator_info.rs b/cli/src/validator_info.rs index d9097c0de6..fe31b40dcb 100644 --- a/cli/src/validator_info.rs +++ b/cli/src/validator_info.rs @@ -1,14 +1,17 @@ use crate::{ cli::{check_account_for_fee, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult}, display::println_name_value, - input_parsers::pubkey_of, - input_validators::{is_pubkey, is_url}, }; use bincode::deserialize; use clap::{App, Arg, ArgMatches, SubCommand}; use reqwest::Client; use serde_derive::{Deserialize, Serialize}; use serde_json::{Map, Value}; + +use solana_clap_utils::{ + input_parsers::pubkey_of, + input_validators::{is_pubkey, is_url}, +}; use solana_client::rpc_client::RpcClient; use solana_config_api::{config_instruction, get_config_data, ConfigKeys, ConfigState}; use solana_sdk::{ @@ -19,6 +22,7 @@ use solana_sdk::{ signature::{Keypair, KeypairUtil}, transaction::Transaction, }; + use std::error; pub const MAX_SHORT_FIELD_LENGTH: usize = 70; diff --git a/cli/src/vote.rs b/cli/src/vote.rs index aff28047a4..fe8e94584b 100644 --- a/cli/src/vote.rs +++ b/cli/src/vote.rs @@ -1,13 +1,9 @@ -use crate::{ - cli::{ - build_balance_message, check_account_for_fee, check_unique_pubkeys, - log_instruction_custom_error, CliCommand, CliCommandInfo, CliConfig, CliError, - ProcessResult, - }, - input_parsers::*, - input_validators::*, +use crate::cli::{ + build_balance_message, check_account_for_fee, check_unique_pubkeys, + log_instruction_custom_error, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult, }; use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand}; +use solana_clap_utils::{input_parsers::*, input_validators::*}; use solana_client::rpc_client::RpcClient; use solana_sdk::signature::Keypair; use solana_sdk::{ diff --git a/gossip/Cargo.toml b/gossip/Cargo.toml index ad0ed2bb06..12e5375343 100644 --- a/gossip/Cargo.toml +++ b/gossip/Cargo.toml @@ -10,6 +10,7 @@ homepage = "https://solana.com/" [dependencies] clap = "2.33.0" +solana-clap-utils = { path = "../clap-utils", version = "0.21.0" } solana-core = { path = "../core", version = "0.21.0" } solana-client = { path = "../client", version = "0.21.0" } solana-logger = { path = "../logger", version = "0.21.0" } diff --git a/gossip/src/main.rs b/gossip/src/main.rs index b92a1c70f4..8c2c24cfbf 100644 --- a/gossip/src/main.rs +++ b/gossip/src/main.rs @@ -4,6 +4,7 @@ use clap::{ crate_description, crate_name, crate_version, value_t_or_exit, App, AppSettings, Arg, SubCommand, }; +use solana_clap_utils::input_validators::is_pubkey; use solana_client::rpc_client::RpcClient; use solana_core::{contact_info::ContactInfo, gossip_service::discover}; use solana_sdk::pubkey::Pubkey; @@ -11,13 +12,6 @@ use std::error; use std::net::SocketAddr; use std::process::exit; -fn is_pubkey(pubkey: String) -> Result<(), String> { - match pubkey.parse::() { - Ok(_) => Ok(()), - Err(err) => Err(format!("{:?}", err)), - } -} - fn main() -> Result<(), Box> { solana_logger::setup_with_filter("solana=info"); diff --git a/install/Cargo.toml b/install/Cargo.toml index eda8d9dada..343cc66ac9 100644 --- a/install/Cargo.toml +++ b/install/Cargo.toml @@ -23,11 +23,11 @@ lazy_static = "1.4.0" log = "0.4.8" nix = "0.15.0" reqwest = { version = "0.9.22", default-features = false, features = ["rustls-tls"] } -semver = "0.9.0" serde = "1.0.102" serde_derive = "1.0.102" serde_yaml = "0.8.11" sha2 = "0.8.0" +solana-clap-utils = { path = "../clap-utils", version = "0.21.0" } solana-client = { path = "../client", version = "0.21.0" } solana-config-api = { path = "../programs/config_api", version = "0.21.0" } solana-logger = { path = "../logger", version = "0.21.0" } diff --git a/install/src/lib.rs b/install/src/lib.rs index 4cf136d706..ce9cde08a2 100644 --- a/install/src/lib.rs +++ b/install/src/lib.rs @@ -2,6 +2,7 @@ extern crate lazy_static; use clap::{crate_description, crate_name, crate_version, App, AppSettings, Arg, SubCommand}; +use solana_clap_utils::input_validators::{is_pubkey, is_release_channel, is_semver, is_url}; use solana_sdk::pubkey::Pubkey; mod build_env; @@ -11,42 +12,6 @@ mod defaults; mod stop_process; mod update_manifest; -// Return an error if a url cannot be parsed. -fn is_url(string: String) -> Result<(), String> { - match url::Url::parse(&string) { - Ok(url) => { - if url.has_host() { - Ok(()) - } else { - Err("no host provided".to_string()) - } - } - Err(err) => Err(format!("{:?}", err)), - } -} - -// Return an error if a pubkey cannot be parsed. -fn is_pubkey(string: String) -> Result<(), String> { - match string.parse::() { - Ok(_) => Ok(()), - Err(err) => Err(format!("{:?}", err)), - } -} - -fn is_semver(semver: &str) -> Result<(), String> { - match semver::Version::parse(&semver) { - Ok(_) => Ok(()), - Err(err) => Err(format!("{:?}", err)), - } -} - -fn is_release_channel(channel: &str) -> Result<(), String> { - match channel { - "edge" | "beta" | "stable" => Ok(()), - _ => Err(format!("Invalid release channel {}", channel)), - } -} - pub fn main() -> Result<(), String> { solana_logger::setup(); diff --git a/validator/Cargo.toml b/validator/Cargo.toml index 1d3aae40fa..d289ad3f90 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -17,6 +17,7 @@ log = "0.4.8" indicatif = "0.13.0" reqwest = { version = "0.9.22", default-features = false } serde_json = "1.0.41" +solana-clap-utils = { path = "../clap-utils", version = "0.21.0" } solana-client = { path = "../client", version = "0.21.0" } solana-core = { path = "../core", version = "0.21.0" } solana-drone = { path = "../drone", version = "0.21.0" } diff --git a/validator/src/main.rs b/validator/src/main.rs index 56ea7aa138..c5e9cd1229 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -3,6 +3,10 @@ use clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg}; use console::{style, Emoji}; use indicatif::{ProgressBar, ProgressStyle}; use log::*; +use solana_clap_utils::{ + input_parsers::pubkey_of, + input_validators::{is_keypair, is_pubkey_or_keypair}, +}; use solana_client::rpc_client::RpcClient; use solana_core::cluster_info::{Node, VALIDATOR_PORT_RANGE}; use solana_core::contact_info::ContactInfo; @@ -229,13 +233,6 @@ fn initialize_ledger_path( Ok(genesis_hash) } -// Return an error if a keypair file cannot be parsed. -fn is_keypair(string: String) -> Result<(), String> { - read_keypair_file(&string) - .map(|_| ()) - .map_err(|err| format!("{:?}", err)) -} - #[allow(clippy::cognitive_complexity)] pub fn main() { let default_dynamic_port_range = @@ -272,7 +269,7 @@ pub fn main() { .long("vote-account") .value_name("PUBKEY") .takes_value(true) - .validator(is_keypair) + .validator(is_pubkey_or_keypair) .help("Public key of the vote account to vote with. Default is the public key of the voting keypair"), ) .arg( @@ -458,11 +455,8 @@ pub fn main() { Keypair::new() }; - let vote_account = matches - .value_of("vote_account") - .map_or(voting_keypair.pubkey(), |pubkey| { - pubkey.parse().expect("failed to parse vote_account") - }); + let vote_account = + pubkey_of(&matches, "vote_account").unwrap_or_else(|| voting_keypair.pubkey()); let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap()); let entrypoint = matches.value_of("entrypoint");