Move helpers to solana-cli-config (#24246)
* Add solana-cli-utils crate * Use cli-utils in cli * Move println fn to cli-output * Use cli-config instead
This commit is contained in:
parent
9ac2245970
commit
8a73badf3d
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -4598,6 +4598,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_yaml",
|
||||
"solana-clap-utils",
|
||||
"solana-sdk",
|
||||
"url 2.2.2",
|
||||
]
|
||||
|
||||
@ -4619,6 +4621,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-cli-config",
|
||||
"solana-client",
|
||||
"solana-sdk",
|
||||
"solana-transaction-status",
|
||||
|
@ -15,6 +15,8 @@ lazy_static = "1.4.0"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_yaml = "0.8.23"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.11.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.11.0" }
|
||||
url = "2.2.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
126
cli-config/src/config_input.rs
Normal file
126
cli-config/src/config_input.rs
Normal file
@ -0,0 +1,126 @@
|
||||
use {
|
||||
crate::Config, solana_clap_utils::input_validators::normalize_to_url_if_moniker,
|
||||
solana_sdk::commitment_config::CommitmentConfig, std::str::FromStr,
|
||||
};
|
||||
|
||||
pub enum SettingType {
|
||||
Explicit,
|
||||
Computed,
|
||||
SystemDefault,
|
||||
}
|
||||
|
||||
pub struct ConfigInput {
|
||||
pub json_rpc_url: String,
|
||||
pub websocket_url: String,
|
||||
pub keypair_path: String,
|
||||
pub commitment: CommitmentConfig,
|
||||
}
|
||||
|
||||
impl ConfigInput {
|
||||
fn default_keypair_path() -> String {
|
||||
Config::default().keypair_path
|
||||
}
|
||||
|
||||
fn default_json_rpc_url() -> String {
|
||||
Config::default().json_rpc_url
|
||||
}
|
||||
|
||||
fn default_websocket_url() -> String {
|
||||
Config::default().websocket_url
|
||||
}
|
||||
|
||||
fn default_commitment() -> CommitmentConfig {
|
||||
CommitmentConfig::confirmed()
|
||||
}
|
||||
|
||||
fn first_nonempty_setting(
|
||||
settings: std::vec::Vec<(SettingType, String)>,
|
||||
) -> (SettingType, String) {
|
||||
settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| !value.is_empty())
|
||||
.expect("no nonempty setting")
|
||||
}
|
||||
|
||||
fn first_setting_is_some<T>(
|
||||
settings: std::vec::Vec<(SettingType, Option<T>)>,
|
||||
) -> (SettingType, T) {
|
||||
let (setting_type, setting_option) = settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| value.is_some())
|
||||
.expect("all settings none");
|
||||
(setting_type, setting_option.unwrap())
|
||||
}
|
||||
|
||||
pub fn compute_websocket_url_setting(
|
||||
websocket_cmd_url: &str,
|
||||
websocket_cfg_url: &str,
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, websocket_cmd_url.to_string()),
|
||||
(SettingType::Explicit, websocket_cfg_url.to_string()),
|
||||
(
|
||||
SettingType::Computed,
|
||||
Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cmd_url)),
|
||||
),
|
||||
(
|
||||
SettingType::Computed,
|
||||
Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cfg_url)),
|
||||
),
|
||||
(SettingType::SystemDefault, Self::default_websocket_url()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_json_rpc_url_setting(
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, json_rpc_cmd_url.to_string()),
|
||||
(SettingType::Explicit, json_rpc_cfg_url.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_json_rpc_url()),
|
||||
]);
|
||||
(setting_type, normalize_to_url_if_moniker(&url_or_moniker))
|
||||
}
|
||||
|
||||
pub fn compute_keypair_path_setting(
|
||||
keypair_cmd_path: &str,
|
||||
keypair_cfg_path: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, keypair_cmd_path.to_string()),
|
||||
(SettingType::Explicit, keypair_cfg_path.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_keypair_path()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_commitment_config(
|
||||
commitment_cmd: &str,
|
||||
commitment_cfg: &str,
|
||||
) -> (SettingType, CommitmentConfig) {
|
||||
Self::first_setting_is_some(vec![
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cmd).ok(),
|
||||
),
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cfg).ok(),
|
||||
),
|
||||
(SettingType::SystemDefault, Some(Self::default_commitment())),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ConfigInput {
|
||||
fn default() -> ConfigInput {
|
||||
ConfigInput {
|
||||
json_rpc_url: Self::default_json_rpc_url(),
|
||||
websocket_url: Self::default_websocket_url(),
|
||||
keypair_path: Self::default_keypair_path(),
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
}
|
||||
}
|
||||
}
|
@ -55,12 +55,16 @@
|
||||
extern crate lazy_static;
|
||||
|
||||
mod config;
|
||||
pub use config::{Config, CONFIG_FILE};
|
||||
mod config_input;
|
||||
use std::{
|
||||
fs::{create_dir_all, File},
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
};
|
||||
pub use {
|
||||
config::{Config, CONFIG_FILE},
|
||||
config_input::{ConfigInput, SettingType},
|
||||
};
|
||||
|
||||
/// Load a value from a file in YAML format.
|
||||
///
|
||||
|
@ -23,6 +23,7 @@ serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.11.0" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.11.0" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.11.0" }
|
||||
solana-client = { path = "../client", version = "=1.11.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.11.0" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
|
||||
|
@ -3,6 +3,7 @@ use {
|
||||
chrono::{DateTime, Local, NaiveDateTime, SecondsFormat, TimeZone, Utc},
|
||||
console::style,
|
||||
indicatif::{ProgressBar, ProgressStyle},
|
||||
solana_cli_config::SettingType,
|
||||
solana_sdk::{
|
||||
clock::UnixTimestamp,
|
||||
hash::Hash,
|
||||
@ -104,6 +105,21 @@ pub fn writeln_name_value(f: &mut dyn fmt::Write, name: &str, value: &str) -> fm
|
||||
writeln!(f, "{} {}", style(name).bold(), styled_value)
|
||||
}
|
||||
|
||||
pub fn println_name_value_or(name: &str, value: &str, setting_type: SettingType) {
|
||||
let description = match setting_type {
|
||||
SettingType::Explicit => "",
|
||||
SettingType::Computed => "(computed)",
|
||||
SettingType::SystemDefault => "(default)",
|
||||
};
|
||||
|
||||
println!(
|
||||
"{} {} {}",
|
||||
style(name).bold(),
|
||||
style(value),
|
||||
style(description).italic(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn format_labeled_address(pubkey: &str, address_labels: &HashMap<String, String>) -> String {
|
||||
let label = address_labels.get(pubkey);
|
||||
match label {
|
||||
|
121
cli/src/cli.rs
121
cli/src/cli.rs
@ -7,7 +7,8 @@ use {
|
||||
log::*,
|
||||
num_traits::FromPrimitive,
|
||||
serde_json::{self, Value},
|
||||
solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
|
||||
solana_clap_utils::{self, input_parsers::*, keypair::*},
|
||||
solana_cli_config::ConfigInput,
|
||||
solana_cli_output::{
|
||||
display::println_name_value, CliSignature, CliValidatorsSortOrder, OutputFormat,
|
||||
},
|
||||
@ -456,129 +457,23 @@ impl From<nonce_utils::Error> for CliError {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SettingType {
|
||||
Explicit,
|
||||
Computed,
|
||||
SystemDefault,
|
||||
}
|
||||
|
||||
pub struct CliConfig<'a> {
|
||||
pub command: CliCommand,
|
||||
pub json_rpc_url: String,
|
||||
pub websocket_url: String,
|
||||
pub signers: Vec<&'a dyn Signer>,
|
||||
pub keypair_path: String,
|
||||
pub commitment: CommitmentConfig,
|
||||
pub signers: Vec<&'a dyn Signer>,
|
||||
pub rpc_client: Option<Arc<RpcClient>>,
|
||||
pub rpc_timeout: Duration,
|
||||
pub verbose: bool,
|
||||
pub output_format: OutputFormat,
|
||||
pub commitment: CommitmentConfig,
|
||||
pub send_transaction_config: RpcSendTransactionConfig,
|
||||
pub confirm_transaction_initial_timeout: Duration,
|
||||
pub address_labels: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl CliConfig<'_> {
|
||||
fn default_keypair_path() -> String {
|
||||
solana_cli_config::Config::default().keypair_path
|
||||
}
|
||||
|
||||
fn default_json_rpc_url() -> String {
|
||||
solana_cli_config::Config::default().json_rpc_url
|
||||
}
|
||||
|
||||
fn default_websocket_url() -> String {
|
||||
solana_cli_config::Config::default().websocket_url
|
||||
}
|
||||
|
||||
fn default_commitment() -> CommitmentConfig {
|
||||
CommitmentConfig::confirmed()
|
||||
}
|
||||
|
||||
fn first_nonempty_setting(
|
||||
settings: std::vec::Vec<(SettingType, String)>,
|
||||
) -> (SettingType, String) {
|
||||
settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| !value.is_empty())
|
||||
.expect("no nonempty setting")
|
||||
}
|
||||
|
||||
fn first_setting_is_some<T>(
|
||||
settings: std::vec::Vec<(SettingType, Option<T>)>,
|
||||
) -> (SettingType, T) {
|
||||
let (setting_type, setting_option) = settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| value.is_some())
|
||||
.expect("all settings none");
|
||||
(setting_type, setting_option.unwrap())
|
||||
}
|
||||
|
||||
pub fn compute_websocket_url_setting(
|
||||
websocket_cmd_url: &str,
|
||||
websocket_cfg_url: &str,
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, websocket_cmd_url.to_string()),
|
||||
(SettingType::Explicit, websocket_cfg_url.to_string()),
|
||||
(
|
||||
SettingType::Computed,
|
||||
solana_cli_config::Config::compute_websocket_url(&normalize_to_url_if_moniker(
|
||||
json_rpc_cmd_url,
|
||||
)),
|
||||
),
|
||||
(
|
||||
SettingType::Computed,
|
||||
solana_cli_config::Config::compute_websocket_url(&normalize_to_url_if_moniker(
|
||||
json_rpc_cfg_url,
|
||||
)),
|
||||
),
|
||||
(SettingType::SystemDefault, Self::default_websocket_url()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_json_rpc_url_setting(
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, json_rpc_cmd_url.to_string()),
|
||||
(SettingType::Explicit, json_rpc_cfg_url.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_json_rpc_url()),
|
||||
]);
|
||||
(setting_type, normalize_to_url_if_moniker(&url_or_moniker))
|
||||
}
|
||||
|
||||
pub fn compute_keypair_path_setting(
|
||||
keypair_cmd_path: &str,
|
||||
keypair_cfg_path: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, keypair_cmd_path.to_string()),
|
||||
(SettingType::Explicit, keypair_cfg_path.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_keypair_path()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_commitment_config(
|
||||
commitment_cmd: &str,
|
||||
commitment_cfg: &str,
|
||||
) -> (SettingType, CommitmentConfig) {
|
||||
Self::first_setting_is_some(vec![
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cmd).ok(),
|
||||
),
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cfg).ok(),
|
||||
),
|
||||
(SettingType::SystemDefault, Some(Self::default_commitment())),
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn pubkey(&self) -> Result<Pubkey, SignerError> {
|
||||
if !self.signers.is_empty() {
|
||||
self.signers[0].try_pubkey()
|
||||
@ -609,15 +504,15 @@ impl Default for CliConfig<'_> {
|
||||
pubkey: Some(Pubkey::default()),
|
||||
use_lamports_unit: false,
|
||||
},
|
||||
json_rpc_url: Self::default_json_rpc_url(),
|
||||
websocket_url: Self::default_websocket_url(),
|
||||
json_rpc_url: ConfigInput::default().json_rpc_url,
|
||||
websocket_url: ConfigInput::default().websocket_url,
|
||||
keypair_path: ConfigInput::default().keypair_path,
|
||||
commitment: ConfigInput::default().commitment,
|
||||
signers: Vec::new(),
|
||||
keypair_path: Self::default_keypair_path(),
|
||||
rpc_client: None,
|
||||
rpc_timeout: Duration::from_secs(u64::from_str(DEFAULT_RPC_TIMEOUT_SECONDS).unwrap()),
|
||||
verbose: false,
|
||||
output_format: OutputFormat::Display,
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
send_transaction_config: RpcSendTransactionConfig::default(),
|
||||
confirm_transaction_initial_timeout: Duration::from_secs(
|
||||
u64::from_str(DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS).unwrap(),
|
||||
|
@ -8,30 +8,18 @@ use {
|
||||
},
|
||||
solana_cli::{
|
||||
clap_app::get_clap_app,
|
||||
cli::{parse_command, process_command, CliCommandInfo, CliConfig, SettingType},
|
||||
cli::{parse_command, process_command, CliCommandInfo, CliConfig},
|
||||
},
|
||||
solana_cli_config::{Config, ConfigInput},
|
||||
solana_cli_output::{
|
||||
display::{println_name_value, println_name_value_or},
|
||||
OutputFormat,
|
||||
},
|
||||
solana_cli_config::Config,
|
||||
solana_cli_output::{display::println_name_value, OutputFormat},
|
||||
solana_client::rpc_config::RpcSendTransactionConfig,
|
||||
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
||||
std::{collections::HashMap, error, path::PathBuf, sync::Arc, time::Duration},
|
||||
};
|
||||
|
||||
pub fn println_name_value_or(name: &str, value: &str, setting_type: SettingType) {
|
||||
let description = match setting_type {
|
||||
SettingType::Explicit => "",
|
||||
SettingType::Computed => "(computed)",
|
||||
SettingType::SystemDefault => "(default)",
|
||||
};
|
||||
|
||||
println!(
|
||||
"{} {} {}",
|
||||
style(name).bold(),
|
||||
style(value),
|
||||
style(description).italic(),
|
||||
);
|
||||
}
|
||||
|
||||
fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error>> {
|
||||
let parse_args = match matches.subcommand() {
|
||||
("config", Some(matches)) => {
|
||||
@ -50,17 +38,18 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
|
||||
match matches.subcommand() {
|
||||
("get", Some(subcommand_matches)) => {
|
||||
let (url_setting_type, json_rpc_url) =
|
||||
CliConfig::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
ConfigInput::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) =
|
||||
ConfigInput::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let (keypair_setting_type, keypair_path) =
|
||||
CliConfig::compute_keypair_path_setting("", &config.keypair_path);
|
||||
ConfigInput::compute_keypair_path_setting("", &config.keypair_path);
|
||||
let (commitment_setting_type, commitment) =
|
||||
CliConfig::compute_commitment_config("", &config.commitment);
|
||||
ConfigInput::compute_commitment_config("", &config.commitment);
|
||||
|
||||
if let Some(field) = subcommand_matches.value_of("specific_setting") {
|
||||
let (field_name, value, setting_type) = match field {
|
||||
@ -107,17 +96,18 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
|
||||
config.save(config_file)?;
|
||||
|
||||
let (url_setting_type, json_rpc_url) =
|
||||
CliConfig::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
ConfigInput::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) =
|
||||
ConfigInput::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let (keypair_setting_type, keypair_path) =
|
||||
CliConfig::compute_keypair_path_setting("", &config.keypair_path);
|
||||
ConfigInput::compute_keypair_path_setting("", &config.keypair_path);
|
||||
let (commitment_setting_type, commitment) =
|
||||
CliConfig::compute_commitment_config("", &config.commitment);
|
||||
ConfigInput::compute_commitment_config("", &config.commitment);
|
||||
|
||||
println_name_value("Config File:", config_file);
|
||||
println_name_value_or("RPC URL:", &json_rpc_url, url_setting_type);
|
||||
@ -158,7 +148,7 @@ pub fn parse_args<'a>(
|
||||
} else {
|
||||
Config::default()
|
||||
};
|
||||
let (_, json_rpc_url) = CliConfig::compute_json_rpc_url_setting(
|
||||
let (_, json_rpc_url) = ConfigInput::compute_json_rpc_url_setting(
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
@ -171,14 +161,14 @@ pub fn parse_args<'a>(
|
||||
let confirm_transaction_initial_timeout =
|
||||
Duration::from_secs(confirm_transaction_initial_timeout);
|
||||
|
||||
let (_, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
let (_, websocket_url) = ConfigInput::compute_websocket_url_setting(
|
||||
matches.value_of("websocket_url").unwrap_or(""),
|
||||
&config.websocket_url,
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let default_signer_arg_name = "keypair".to_string();
|
||||
let (_, default_signer_path) = CliConfig::compute_keypair_path_setting(
|
||||
let (_, default_signer_path) = ConfigInput::compute_keypair_path_setting(
|
||||
matches.value_of(&default_signer_arg_name).unwrap_or(""),
|
||||
&config.keypair_path,
|
||||
);
|
||||
@ -201,7 +191,7 @@ pub fn parse_args<'a>(
|
||||
let verbose = matches.is_present("verbose");
|
||||
let output_format = OutputFormat::from_matches(matches, "output_format", verbose);
|
||||
|
||||
let (_, commitment) = CliConfig::compute_commitment_config(
|
||||
let (_, commitment) = ConfigInput::compute_commitment_config(
|
||||
matches.value_of("commitment").unwrap_or(""),
|
||||
&config.commitment,
|
||||
);
|
||||
|
3
programs/bpf/Cargo.lock
generated
3
programs/bpf/Cargo.lock
generated
@ -3312,6 +3312,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_yaml",
|
||||
"solana-clap-utils",
|
||||
"solana-sdk",
|
||||
"url",
|
||||
]
|
||||
|
||||
@ -3332,6 +3334,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-cli-config",
|
||||
"solana-client",
|
||||
"solana-sdk",
|
||||
"solana-transaction-status",
|
||||
|
Loading…
x
Reference in New Issue
Block a user