From 683ea8fd34fd343535d79e99b76a34fa27cc825d Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:16:24 +0200 Subject: [PATCH 1/6] refactor(client-cli): use a flattened clap structure for shared arguments Only apply to `--json` but allow to easily add more if needed. --- .../src/commands/cardano_db/download.rs | 17 +++++++++------- .../src/commands/cardano_db/list.rs | 14 +++++++------ .../src/commands/cardano_db/show.rs | 12 +++++------ .../cardano_stake_distribution/download.rs | 19 ++++++++++++------ .../cardano_stake_distribution/list.rs | 17 +++++++++++----- .../commands/cardano_transaction/certify.rs | 19 ++++++++++++------ .../cardano_transaction/snapshot_list.rs | 14 ++++++++----- .../cardano_transaction/snapshot_show.rs | 15 +++++++++----- .../mithril_stake_distribution/download.rs | 20 +++++++++++++------ .../mithril_stake_distribution/list.rs | 17 +++++++++++----- mithril-client-cli/src/commands/mod.rs | 9 +++++++++ 11 files changed, 116 insertions(+), 57 deletions(-) diff --git a/mithril-client-cli/src/commands/cardano_db/download.rs b/mithril-client-cli/src/commands/cardano_db/download.rs index 8911d8d21ce..45348467ee9 100644 --- a/mithril-client-cli/src/commands/cardano_db/download.rs +++ b/mithril-client-cli/src/commands/cardano_db/download.rs @@ -11,7 +11,7 @@ use std::{ }; use crate::{ - commands::client_builder, + commands::{client_builder, SharedArgs}, configuration::ConfigParameters, utils::{ CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils, IndicatifFeedbackReceiver, @@ -25,9 +25,8 @@ use mithril_client::{ /// Clap command to download a Cardano db and verify its associated certificate. #[derive(Parser, Debug, Clone)] pub struct CardanoDbDownloadCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Digest of the cardano db to download. Use the `list` command to get that information. /// @@ -48,7 +47,7 @@ pub struct CardanoDbDownloadCommand { impl CardanoDbDownloadCommand { /// Is JSON output enabled pub fn is_json_output_enabled(&self) -> bool { - self.json + self.shared_args.json } /// Command execution @@ -58,7 +57,7 @@ impl CardanoDbDownloadCommand { let download_dir: &String = ¶ms.require("download_dir")?; let db_dir = Path::new(download_dir).join("db"); - let progress_output_type = if self.json { + let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter } else { ProgressOutputType::Tty @@ -128,7 +127,11 @@ impl CardanoDbDownloadCommand { ) .await?; - Self::log_download_information(&db_dir, &cardano_db_message, self.json)?; + Self::log_download_information( + &db_dir, + &cardano_db_message, + self.is_json_output_enabled(), + )?; Ok(()) } diff --git a/mithril-client-cli/src/commands/cardano_db/list.rs b/mithril-client-cli/src/commands/cardano_db/list.rs index 7b457e19f84..f6bc29c1052 100644 --- a/mithril-client-cli/src/commands/cardano_db/list.rs +++ b/mithril-client-cli/src/commands/cardano_db/list.rs @@ -3,21 +3,23 @@ use cli_table::{format::Justify, print_stdout, Cell, Table}; use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; -use crate::{commands::client_builder_with_fallback_genesis_key, configuration::ConfigParameters}; +use crate::{ + commands::{client_builder_with_fallback_genesis_key, SharedArgs}, + configuration::ConfigParameters, +}; use mithril_client::MithrilResult; /// Clap command to list existing cardano dbs #[derive(Parser, Debug, Clone)] pub struct CardanoDbListCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, } impl CardanoDbListCommand { /// Is JSON output enabled pub fn is_json_output_enabled(&self) -> bool { - self.json + self.shared_args.json } /// Main command execution @@ -27,7 +29,7 @@ impl CardanoDbListCommand { let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let items = client.snapshot().list().await?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&items)?); } else { let items = items diff --git a/mithril-client-cli/src/commands/cardano_db/show.rs b/mithril-client-cli/src/commands/cardano_db/show.rs index 69e3fdbdf64..fa7d318a895 100644 --- a/mithril-client-cli/src/commands/cardano_db/show.rs +++ b/mithril-client-cli/src/commands/cardano_db/show.rs @@ -5,7 +5,8 @@ use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; use crate::{ - commands::client_builder_with_fallback_genesis_key, configuration::ConfigParameters, + commands::{client_builder_with_fallback_genesis_key, SharedArgs}, + configuration::ConfigParameters, utils::ExpanderUtils, }; use mithril_client::MithrilResult; @@ -13,9 +14,8 @@ use mithril_client::MithrilResult; /// Clap command to show a given cardano db #[derive(Parser, Debug, Clone)] pub struct CardanoDbShowCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Cardano DB digest. /// @@ -26,7 +26,7 @@ pub struct CardanoDbShowCommand { impl CardanoDbShowCommand { /// Is JSON output enabled pub fn is_json_output_enabled(&self) -> bool { - self.json + self.shared_args.json } /// Cardano DB Show command @@ -55,7 +55,7 @@ impl CardanoDbShowCommand { .await? .ok_or_else(|| anyhow!("Cardano DB not found for digest: '{}'", &self.digest))?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&cardano_db_message)?); } else { let cardano_db_table = vec![ diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs index 467c7641bab..dab41e619a0 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs @@ -8,7 +8,10 @@ use std::{ }; use crate::utils::{ExpanderUtils, IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; -use crate::{commands::client_builder, configuration::ConfigParameters}; +use crate::{ + commands::{client_builder, SharedArgs}, + configuration::ConfigParameters, +}; use mithril_client::common::Epoch; use mithril_client::Client; use mithril_client::{CardanoStakeDistribution, MessageBuilder, MithrilResult}; @@ -16,9 +19,8 @@ use mithril_client::{CardanoStakeDistribution, MessageBuilder, MithrilResult}; /// Download and verify a Cardano stake distribution information. #[derive(Parser, Debug, Clone)] pub struct CardanoStakeDistributionDownloadCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Epoch or hash of the Cardano stake distribution artifact. /// @@ -37,6 +39,11 @@ pub struct CardanoStakeDistributionDownloadCommand { } impl CardanoStakeDistributionDownloadCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder @@ -47,7 +54,7 @@ impl CardanoStakeDistributionDownloadCommand { let download_dir = ¶ms.require("download_dir")?; let download_dir = Path::new(download_dir); - let progress_output_type = if self.json { + let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter } else { ProgressOutputType::Tty @@ -130,7 +137,7 @@ impl CardanoStakeDistributionDownloadCommand { })?, )?; - if self.json { + if self.is_json_output_enabled() { println!( r#"{{"cardano_stake_distribution_epoch": "{}", "filepath": "{}"}}"#, cardano_stake_distribution.epoch, diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs index 1aec171e643..bec5d34588c 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs @@ -3,18 +3,25 @@ use cli_table::{format::Justify, print_stdout, Cell, Table}; use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; -use crate::{commands::client_builder_with_fallback_genesis_key, configuration::ConfigParameters}; +use crate::{ + commands::{client_builder_with_fallback_genesis_key, SharedArgs}, + configuration::ConfigParameters, +}; use mithril_client::MithrilResult; /// Cardano stake distribution LIST command #[derive(Parser, Debug, Clone)] pub struct CardanoStakeDistributionListCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, } impl CardanoStakeDistributionListCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder.build()?; @@ -22,7 +29,7 @@ impl CardanoStakeDistributionListCommand { let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.cardano_stake_distribution().list().await?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&lines)?); } else { let lines = lines diff --git a/mithril-client-cli/src/commands/cardano_transaction/certify.rs b/mithril-client-cli/src/commands/cardano_transaction/certify.rs index 8e340997832..378e65277c6 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/certify.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/certify.rs @@ -11,14 +11,16 @@ use mithril_client::{ }; use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; -use crate::{commands::client_builder, configuration::ConfigParameters}; +use crate::{ + commands::{client_builder, SharedArgs}, + configuration::ConfigParameters, +}; /// Clap command to show a given Cardano transaction sets #[derive(Parser, Debug, Clone)] pub struct CardanoTransactionsCertifyCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Genesis Verification Key to check the certificate chain. #[clap(long, env = "GENESIS_VERIFICATION_KEY")] @@ -30,12 +32,17 @@ pub struct CardanoTransactionsCertifyCommand { } impl CardanoTransactionsCertifyCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Cardano transaction certify command pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder.add_source(self.clone()).build()?; let params = ConfigParameters::new(config.try_deserialize::>()?); - let progress_output_type = if self.json { + let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter } else { ProgressOutputType::Tty @@ -91,7 +98,7 @@ impl CardanoTransactionsCertifyCommand { Self::log_certify_information( &verified_transactions, &cardano_transaction_proof.non_certified_transactions, - self.json, + self.is_json_output_enabled(), ) } diff --git a/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs b/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs index d1cbc24becf..a92d97884ff 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs @@ -4,19 +4,23 @@ use cli_table::{print_stdout, Cell, Table}; use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; -use crate::commands::client_builder_with_fallback_genesis_key; +use crate::commands::{client_builder_with_fallback_genesis_key, SharedArgs}; use crate::configuration::ConfigParameters; use mithril_client::MithrilResult; /// Cardano transaction snapshot list command #[derive(Parser, Debug, Clone)] pub struct CardanoTransactionSnapshotListCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, } impl CardanoTransactionSnapshotListCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder.build()?; @@ -24,7 +28,7 @@ impl CardanoTransactionSnapshotListCommand { let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.cardano_transaction().list_snapshots().await?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&lines)?); } else { let lines = lines diff --git a/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs b/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs index ae01a548c92..723e5649884 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs @@ -5,7 +5,8 @@ use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; use crate::{ - commands::client_builder_with_fallback_genesis_key, configuration::ConfigParameters, + commands::{client_builder_with_fallback_genesis_key, SharedArgs}, + configuration::ConfigParameters, utils::ExpanderUtils, }; use mithril_client::MithrilResult; @@ -13,9 +14,8 @@ use mithril_client::MithrilResult; /// Clap command to show a given Cardano transaction snapshot #[derive(Parser, Debug, Clone)] pub struct CardanoTransactionsSnapshotShowCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Cardano transaction snapshot hash. /// @@ -25,6 +25,11 @@ pub struct CardanoTransactionsSnapshotShowCommand { } impl CardanoTransactionsSnapshotShowCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Cardano transaction snapshot Show command pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder.build()?; @@ -56,7 +61,7 @@ impl CardanoTransactionsSnapshotShowCommand { ) })?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&tx_sets)?); } else { let transaction_sets_table = vec![ diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs index dba43e7490d..ab10946249e 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs @@ -8,7 +8,11 @@ use std::{ }; use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; -use crate::{commands::client_builder, configuration::ConfigParameters, utils::ExpanderUtils}; +use crate::{ + commands::{client_builder, SharedArgs}, + configuration::ConfigParameters, + utils::ExpanderUtils, +}; use mithril_client::MessageBuilder; use mithril_client::MithrilResult; @@ -16,9 +20,8 @@ use mithril_client::MithrilResult; /// verification fails, the file is not persisted. #[derive(Parser, Debug, Clone)] pub struct MithrilStakeDistributionDownloadCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, /// Hash of the Mithril Stake Distribution artifact. /// @@ -37,6 +40,11 @@ pub struct MithrilStakeDistributionDownloadCommand { } impl MithrilStakeDistributionDownloadCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder @@ -47,7 +55,7 @@ impl MithrilStakeDistributionDownloadCommand { let download_dir = ¶ms.require("download_dir")?; let download_dir = Path::new(download_dir); - let progress_output_type = if self.json { + let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter } else { ProgressOutputType::Tty @@ -144,7 +152,7 @@ impl MithrilStakeDistributionDownloadCommand { })?, )?; - if self.json { + if self.is_json_output_enabled() { println!( r#"{{"mithril_stake_distribution_hash": "{}", "filepath": "{}"}}"#, mithril_stake_distribution.hash, diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs index 9051f9b63b4..60cf35ad34e 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs @@ -3,18 +3,25 @@ use cli_table::{format::Justify, print_stdout, Cell, Table}; use config::{builder::DefaultState, ConfigBuilder}; use std::collections::HashMap; -use crate::{commands::client_builder_with_fallback_genesis_key, configuration::ConfigParameters}; +use crate::{ + commands::{client_builder_with_fallback_genesis_key, SharedArgs}, + configuration::ConfigParameters, +}; use mithril_client::MithrilResult; /// Mithril stake distribution LIST command #[derive(Parser, Debug, Clone)] pub struct MithrilStakeDistributionListCommand { - /// Enable JSON output. - #[clap(long)] - json: bool, + #[clap(flatten)] + shared_args: SharedArgs, } impl MithrilStakeDistributionListCommand { + /// Is JSON output enabled + pub fn is_json_output_enabled(&self) -> bool { + self.shared_args.json + } + /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { let config = config_builder.build()?; @@ -22,7 +29,7 @@ impl MithrilStakeDistributionListCommand { let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.mithril_stake_distribution().list().await?; - if self.json { + if self.is_json_output_enabled() { println!("{}", serde_json::to_string(&lines)?); } else { let lines = lines diff --git a/mithril-client-cli/src/commands/mod.rs b/mithril-client-cli/src/commands/mod.rs index 17a3e23bc21..ca99d302078 100644 --- a/mithril-client-cli/src/commands/mod.rs +++ b/mithril-client-cli/src/commands/mod.rs @@ -11,11 +11,20 @@ pub mod mithril_stake_distribution; pub use deprecation::{DeprecatedCommand, Deprecation}; +use clap::Args; use mithril_client::{ClientBuilder, MithrilResult}; use slog_scope::logger; use crate::configuration::ConfigParameters; +/// Shared arguments for all commands +#[derive(Debug, Clone, Args)] +pub struct SharedArgs { + /// Enable JSON output. + #[clap(long)] + json: bool, +} + pub(crate) fn client_builder(params: &ConfigParameters) -> MithrilResult { let builder = ClientBuilder::aggregator( ¶ms.require("aggregator_endpoint")?, From 3f42a7e6a10097c26af80f344ad6e3c0bdecb7b6 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:24:02 +0200 Subject: [PATCH 2/6] feat(client-cli): add a 'source' system for ConfigParameters Similar but simpler than the one used by config, this will allow to reduce confusion in our commands by only using the locally defined ConfigParameters. --- mithril-client-cli/src/configuration.rs | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/mithril-client-cli/src/configuration.rs b/mithril-client-cli/src/configuration.rs index ac5127f6a80..e89403ebec1 100644 --- a/mithril-client-cli/src/configuration.rs +++ b/mithril-client-cli/src/configuration.rs @@ -8,6 +8,10 @@ pub enum ConfigError { /// Error raised when a required parameter is not present. #[error("Parameter '{0}' is mandatory.")] Required(String), + + /// Error raised when a parameter cannot be converted to string. + #[error("Parameter '{0}' cannot be converted to string.")] + Conversion(String), } /// Configuration parameters holder @@ -42,6 +46,14 @@ impl ConfigParameters { self } + /// Fill the holder with parameters from a source + pub fn add_source(mut self, source: &impl ConfigSource) -> Result { + let extra = source.collect()?; + self.parameters.extend(extra); + + Ok(self) + } + /// Fetch a parameter from the holder. pub fn get(&self, name: &str) -> Option { self.parameters.get(name).cloned() @@ -61,10 +73,37 @@ impl ConfigParameters { } } +/// Describes a generic source of configuration parameters +pub trait ConfigSource { + /// Collect all the configuration parameters from the source + fn collect(&self) -> Result, ConfigError>; +} + #[cfg(test)] mod tests { use super::*; + struct TestSource { + params: HashMap, + } + + impl From<[(&str, &str); N]> for TestSource { + fn from(arr: [(&str, &str); N]) -> Self { + TestSource { + params: arr + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } + } + + impl ConfigSource for TestSource { + fn collect(&self) -> Result, ConfigError> { + Ok(self.params.clone()) + } + } + #[test] fn test_config_constructor() { let config = ConfigParameters::build(&[("pika", "chu")]); @@ -119,4 +158,36 @@ mod tests { assert_eq!("chu".to_string(), config.require("pika").unwrap()); config.require("whatever").unwrap_err(); } + + #[test] + fn test_add_source_to_config() { + let config = ConfigParameters::build(&[("pika", "chu"), ("chari", "zard")]) + .add_source(&TestSource::from([("jiggly", "puff")])) + .unwrap(); + + assert_eq!( + ConfigParameters { + parameters: HashMap::from([ + ("pika".to_string(), "chu".to_string()), + ("chari".to_string(), "zard".to_string()), + ("jiggly".to_string(), "puff".to_string()) + ]) + }, + config + ); + } + + #[test] + fn test_add_source_replace_existing_value() { + let config = ConfigParameters::build(&[("pika", "pika")]) + .add_source(&TestSource::from([("pika", "not chu")])) + .unwrap(); + + assert_eq!( + ConfigParameters { + parameters: HashMap::from([("pika".to_string(), "not chu".to_string()),]) + }, + config + ); + } } From 9006dfb573f4f7b243b7051947919fe6ca0b0ac6 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:00:28 +0200 Subject: [PATCH 3/6] refactor(client-cli): supersed most config usage in commands Using crate defined `ConfigParameters`. --- .../src/commands/cardano_db/download.rs | 34 +++++++-------- .../cardano_stake_distribution/download.rs | 41 ++++++++----------- .../commands/cardano_transaction/certify.rs | 22 ++++------ .../mithril_stake_distribution/download.rs | 41 ++++++++----------- 4 files changed, 58 insertions(+), 80 deletions(-) diff --git a/mithril-client-cli/src/commands/cardano_db/download.rs b/mithril-client-cli/src/commands/cardano_db/download.rs index 45348467ee9..5c5de03c48e 100644 --- a/mithril-client-cli/src/commands/cardano_db/download.rs +++ b/mithril-client-cli/src/commands/cardano_db/download.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Context}; use chrono::Utc; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind}; +use config::{builder::DefaultState, ConfigBuilder}; use slog_scope::{debug, warn}; use std::{ collections::HashMap, @@ -12,7 +12,7 @@ use std::{ use crate::{ commands::{client_builder, SharedArgs}, - configuration::ConfigParameters, + configuration::{ConfigError, ConfigParameters, ConfigSource}, utils::{ CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils, IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter, @@ -52,8 +52,9 @@ impl CardanoDbDownloadCommand { /// Command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.add_source(self.clone()).build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + let config = config_builder.build()?; + let params = ConfigParameters::new(config.try_deserialize::>()?) + .add_source(self)?; let download_dir: &String = ¶ms.require("download_dir")?; let db_dir = Path::new(download_dir).join("db"); @@ -304,34 +305,29 @@ impl CardanoDbDownloadCommand { } } -impl Source for CardanoDbDownloadCommand { - fn clone_into_box(&self) -> Box { - Box::new(self.clone()) - } - - fn collect(&self) -> Result, config::ConfigError> { - let mut map = Map::new(); - let namespace = "clap arguments".to_string(); +impl ConfigSource for CardanoDbDownloadCommand { + fn collect(&self) -> Result, ConfigError> { + let mut map = HashMap::new(); if let Some(download_dir) = self.download_dir.clone() { map.insert( "download_dir".to_string(), - Value::new( - Some(&namespace), - ValueKind::from(download_dir.to_str().ok_or_else(|| { - config::ConfigError::Message(format!( + download_dir + .to_str() + .ok_or_else(|| { + ConfigError::Conversion(format!( "Could not read download directory: '{}'.", download_dir.display() )) - })?), - ), + })? + .to_string(), ); } if let Some(genesis_verification_key) = self.genesis_verification_key.clone() { map.insert( "genesis_verification_key".to_string(), - Value::new(Some(&namespace), ValueKind::from(genesis_verification_key)), + genesis_verification_key, ); } diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs index dab41e619a0..34312fc0eed 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Context}; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind}; +use config::{builder::DefaultState, ConfigBuilder}; use std::sync::Arc; use std::{ collections::HashMap, @@ -10,7 +10,7 @@ use std::{ use crate::utils::{ExpanderUtils, IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::ConfigParameters, + configuration::{ConfigError, ConfigParameters, ConfigSource}, }; use mithril_client::common::Epoch; use mithril_client::Client; @@ -46,13 +46,11 @@ impl CardanoStakeDistributionDownloadCommand { /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder - .set_default("download_dir", ".")? - .add_source(self.clone()) - .build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); - let download_dir = ¶ms.require("download_dir")?; - let download_dir = Path::new(download_dir); + let config = config_builder.build()?; + let params = ConfigParameters::new(config.try_deserialize::>()?) + .add_source(self)?; + let download_dir = params.get_or("download_dir", "."); + let download_dir = Path::new(&download_dir); let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter @@ -224,34 +222,29 @@ impl CardanoStakeDistributionDownloadCommand { } } -impl Source for CardanoStakeDistributionDownloadCommand { - fn clone_into_box(&self) -> Box { - Box::new(self.clone()) - } - - fn collect(&self) -> Result, config::ConfigError> { - let mut map = Map::new(); - let namespace = "clap arguments".to_string(); +impl ConfigSource for CardanoStakeDistributionDownloadCommand { + fn collect(&self) -> Result, ConfigError> { + let mut map = HashMap::new(); if let Some(download_dir) = self.download_dir.clone() { map.insert( "download_dir".to_string(), - Value::new( - Some(&namespace), - ValueKind::from(download_dir.to_str().ok_or_else(|| { - config::ConfigError::Message(format!( + download_dir + .to_str() + .ok_or_else(|| { + ConfigError::Conversion(format!( "Could not read download directory: '{}'.", download_dir.display() )) - })?), - ), + })? + .to_string(), ); } if let Some(genesis_verification_key) = self.genesis_verification_key.clone() { map.insert( "genesis_verification_key".to_string(), - Value::new(Some(&namespace), ValueKind::from(genesis_verification_key)), + genesis_verification_key, ); } diff --git a/mithril-client-cli/src/commands/cardano_transaction/certify.rs b/mithril-client-cli/src/commands/cardano_transaction/certify.rs index 378e65277c6..faaa1f2281e 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/certify.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/certify.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Context}; use clap::Parser; use cli_table::{print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind}; +use config::{builder::DefaultState, ConfigBuilder}; use slog_scope::debug; use std::{collections::HashMap, sync::Arc}; @@ -13,7 +13,7 @@ use mithril_client::{ use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::ConfigParameters, + configuration::{ConfigError, ConfigParameters, ConfigSource}, }; /// Clap command to show a given Cardano transaction sets @@ -39,8 +39,9 @@ impl CardanoTransactionsCertifyCommand { /// Cardano transaction certify command pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.add_source(self.clone()).build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + let config = config_builder.build()?; + let params = ConfigParameters::new(config.try_deserialize::>()?) + .add_source(self)?; let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter @@ -189,19 +190,14 @@ No proof could be computed for some Cardano transactions. Mithril may not have s } } -impl Source for CardanoTransactionsCertifyCommand { - fn clone_into_box(&self) -> Box { - Box::new(self.clone()) - } - - fn collect(&self) -> Result, config::ConfigError> { - let mut map = Map::new(); - let namespace = "clap arguments".to_string(); +impl ConfigSource for CardanoTransactionsCertifyCommand { + fn collect(&self) -> Result, ConfigError> { + let mut map = HashMap::new(); if let Some(genesis_verification_key) = self.genesis_verification_key.clone() { map.insert( "genesis_verification_key".to_string(), - Value::new(Some(&namespace), ValueKind::from(genesis_verification_key)), + genesis_verification_key, ); } diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs index ab10946249e..c78d61bf539 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs @@ -1,6 +1,6 @@ use anyhow::Context; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind}; +use config::{builder::DefaultState, ConfigBuilder}; use std::sync::Arc; use std::{ collections::HashMap, @@ -10,7 +10,7 @@ use std::{ use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::ConfigParameters, + configuration::{ConfigError, ConfigParameters, ConfigSource}, utils::ExpanderUtils, }; use mithril_client::MessageBuilder; @@ -47,13 +47,11 @@ impl MithrilStakeDistributionDownloadCommand { /// Main command execution pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder - .set_default("download_dir", ".")? - .add_source(self.clone()) - .build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); - let download_dir = ¶ms.require("download_dir")?; - let download_dir = Path::new(download_dir); + let config = config_builder.build()?; + let params = ConfigParameters::new(config.try_deserialize::>()?) + .add_source(self)?; + let download_dir = params.get_or("download_dir", "."); + let download_dir = Path::new(&download_dir); let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter @@ -170,34 +168,29 @@ impl MithrilStakeDistributionDownloadCommand { } } -impl Source for MithrilStakeDistributionDownloadCommand { - fn clone_into_box(&self) -> Box { - Box::new(self.clone()) - } - - fn collect(&self) -> Result, config::ConfigError> { - let mut map = Map::new(); - let namespace = "clap arguments".to_string(); +impl ConfigSource for MithrilStakeDistributionDownloadCommand { + fn collect(&self) -> Result, ConfigError> { + let mut map = HashMap::new(); if let Some(download_dir) = self.download_dir.clone() { map.insert( "download_dir".to_string(), - Value::new( - Some(&namespace), - ValueKind::from(download_dir.to_str().ok_or_else(|| { - config::ConfigError::Message(format!( + download_dir + .to_str() + .ok_or_else(|| { + ConfigError::Conversion(format!( "Could not read download directory: '{}'.", download_dir.display() )) - })?), - ), + })? + .to_string(), ); } if let Some(genesis_verification_key) = self.genesis_verification_key.clone() { map.insert( "genesis_verification_key".to_string(), - Value::new(Some(&namespace), ValueKind::from(genesis_verification_key)), + genesis_verification_key, ); } From 23c3fd5ff6701944369f9d2b40adce15e8e6148a Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:21:13 +0200 Subject: [PATCH 4/6] feat(client-cli): pass a context struct to all commands Instead of passing only config parameters, this design allow to add other shared dependencies such as a common logger. --- mithril-client-cli/src/command_context.rs | 36 +++++++++++++++++++ .../src/commands/cardano_db/download.rs | 10 +++--- .../src/commands/cardano_db/list.rs | 9 ++--- .../src/commands/cardano_db/mod.rs | 6 ++-- .../src/commands/cardano_db/show.rs | 9 ++--- .../cardano_stake_distribution/download.rs | 10 +++--- .../cardano_stake_distribution/list.rs | 9 ++--- .../cardano_stake_distribution/mod.rs | 4 +-- .../commands/cardano_transaction/certify.rs | 10 +++--- .../src/commands/cardano_transaction/mod.rs | 7 ++-- .../cardano_transaction/snapshot_list.rs | 9 ++--- .../cardano_transaction/snapshot_show.rs | 9 ++--- .../mithril_stake_distribution/download.rs | 10 +++--- .../mithril_stake_distribution/list.rs | 9 ++--- .../mithril_stake_distribution/mod.rs | 4 +-- mithril-client-cli/src/lib.rs | 2 ++ mithril-client-cli/src/main.rs | 24 +++++++------ 17 files changed, 95 insertions(+), 82 deletions(-) create mode 100644 mithril-client-cli/src/command_context.rs diff --git a/mithril-client-cli/src/command_context.rs b/mithril-client-cli/src/command_context.rs new file mode 100644 index 00000000000..93ff40a0902 --- /dev/null +++ b/mithril-client-cli/src/command_context.rs @@ -0,0 +1,36 @@ +use config::builder::DefaultState; +use config::ConfigBuilder; +use slog::Logger; +use std::collections::HashMap; + +use mithril_client::MithrilResult; + +use crate::configuration::ConfigParameters; + +/// Context for the command execution +pub struct CommandContext { + config_builder: ConfigBuilder, + logger: Logger, +} + +impl CommandContext { + /// Create a new command context + pub fn new(config_builder: ConfigBuilder, logger: Logger) -> Self { + Self { + config_builder, + logger, + } + } + + /// Get the configured parameters + pub fn config_parameters(&self) -> MithrilResult { + let config = self.config_builder.clone().build()?; + let config_hash_map = config.try_deserialize::>()?; + Ok(ConfigParameters::new(config_hash_map)) + } + + /// Get the shared logger + pub fn logger(&self) -> &Logger { + &self.logger + } +} diff --git a/mithril-client-cli/src/commands/cardano_db/download.rs b/mithril-client-cli/src/commands/cardano_db/download.rs index 5c5de03c48e..d27b04be134 100644 --- a/mithril-client-cli/src/commands/cardano_db/download.rs +++ b/mithril-client-cli/src/commands/cardano_db/download.rs @@ -1,7 +1,6 @@ use anyhow::{anyhow, Context}; use chrono::Utc; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder}; use slog_scope::{debug, warn}; use std::{ collections::HashMap, @@ -12,11 +11,12 @@ use std::{ use crate::{ commands::{client_builder, SharedArgs}, - configuration::{ConfigError, ConfigParameters, ConfigSource}, + configuration::{ConfigError, ConfigSource}, utils::{ CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils, IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter, }, + CommandContext, }; use mithril_client::{ common::ProtocolMessage, Client, MessageBuilder, MithrilCertificate, MithrilResult, Snapshot, @@ -51,10 +51,8 @@ impl CardanoDbDownloadCommand { } /// Command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?) - .add_source(self)?; + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?.add_source(self)?; let download_dir: &String = ¶ms.require("download_dir")?; let db_dir = Path::new(download_dir).join("db"); diff --git a/mithril-client-cli/src/commands/cardano_db/list.rs b/mithril-client-cli/src/commands/cardano_db/list.rs index f6bc29c1052..b35216885a5 100644 --- a/mithril-client-cli/src/commands/cardano_db/list.rs +++ b/mithril-client-cli/src/commands/cardano_db/list.rs @@ -1,11 +1,9 @@ use clap::Parser; use cli_table::{format::Justify, print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::{ commands::{client_builder_with_fallback_genesis_key, SharedArgs}, - configuration::ConfigParameters, + CommandContext, }; use mithril_client::MithrilResult; @@ -23,9 +21,8 @@ impl CardanoDbListCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let items = client.snapshot().list().await?; diff --git a/mithril-client-cli/src/commands/cardano_db/mod.rs b/mithril-client-cli/src/commands/cardano_db/mod.rs index 1573f38109a..02e7542878e 100644 --- a/mithril-client-cli/src/commands/cardano_db/mod.rs +++ b/mithril-client-cli/src/commands/cardano_db/mod.rs @@ -7,8 +7,8 @@ pub use download::*; pub use list::*; pub use show::*; +use crate::CommandContext; use clap::Subcommand; -use config::{builder::DefaultState, ConfigBuilder}; use mithril_client::MithrilResult; /// Cardano db management (alias: cdb) @@ -37,7 +37,7 @@ pub enum CardanoDbSnapshotCommands { impl CardanoDbCommands { /// Execute cardano db command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::Download(cmd) => cmd.execute(config_builder).await, Self::Snapshot(cmd) => cmd.execute(config_builder).await, @@ -47,7 +47,7 @@ impl CardanoDbCommands { impl CardanoDbSnapshotCommands { /// Execute Cardano db snapshot command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::List(cmd) => cmd.execute(config_builder).await, Self::Show(cmd) => cmd.execute(config_builder).await, diff --git a/mithril-client-cli/src/commands/cardano_db/show.rs b/mithril-client-cli/src/commands/cardano_db/show.rs index fa7d318a895..c15e405a920 100644 --- a/mithril-client-cli/src/commands/cardano_db/show.rs +++ b/mithril-client-cli/src/commands/cardano_db/show.rs @@ -1,13 +1,11 @@ use anyhow::{anyhow, Context}; use clap::Parser; use cli_table::{print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::{ commands::{client_builder_with_fallback_genesis_key, SharedArgs}, - configuration::ConfigParameters, utils::ExpanderUtils, + CommandContext, }; use mithril_client::MithrilResult; @@ -30,9 +28,8 @@ impl CardanoDbShowCommand { } /// Cardano DB Show command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let get_list_of_artifact_ids = || async { diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs index 34312fc0eed..35bc804f8c5 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/download.rs @@ -1,6 +1,5 @@ use anyhow::{anyhow, Context}; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder}; use std::sync::Arc; use std::{ collections::HashMap, @@ -10,7 +9,8 @@ use std::{ use crate::utils::{ExpanderUtils, IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::{ConfigError, ConfigParameters, ConfigSource}, + configuration::{ConfigError, ConfigSource}, + CommandContext, }; use mithril_client::common::Epoch; use mithril_client::Client; @@ -45,10 +45,8 @@ impl CardanoStakeDistributionDownloadCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?) - .add_source(self)?; + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?.add_source(self)?; let download_dir = params.get_or("download_dir", "."); let download_dir = Path::new(&download_dir); diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs index bec5d34588c..baf1b09854d 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/list.rs @@ -1,11 +1,9 @@ use clap::Parser; use cli_table::{format::Justify, print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::{ commands::{client_builder_with_fallback_genesis_key, SharedArgs}, - configuration::ConfigParameters, + CommandContext, }; use mithril_client::MithrilResult; @@ -23,9 +21,8 @@ impl CardanoStakeDistributionListCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.cardano_stake_distribution().list().await?; diff --git a/mithril-client-cli/src/commands/cardano_stake_distribution/mod.rs b/mithril-client-cli/src/commands/cardano_stake_distribution/mod.rs index e35c11ca4f7..02817e66974 100644 --- a/mithril-client-cli/src/commands/cardano_stake_distribution/mod.rs +++ b/mithril-client-cli/src/commands/cardano_stake_distribution/mod.rs @@ -5,8 +5,8 @@ mod list; pub use download::*; pub use list::*; +use crate::CommandContext; use clap::Subcommand; -use config::{builder::DefaultState, ConfigBuilder}; use mithril_client::MithrilResult; /// Cardano Stake Distribution management (alias: csd) @@ -24,7 +24,7 @@ pub enum CardanoStakeDistributionCommands { impl CardanoStakeDistributionCommands { /// Execute Cardano Stake Distribution command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::List(cmd) => cmd.execute(config_builder).await, Self::Download(cmd) => cmd.execute(config_builder).await, diff --git a/mithril-client-cli/src/commands/cardano_transaction/certify.rs b/mithril-client-cli/src/commands/cardano_transaction/certify.rs index faaa1f2281e..af38ac17355 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/certify.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/certify.rs @@ -1,7 +1,6 @@ use anyhow::{anyhow, Context}; use clap::Parser; use cli_table::{print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; use slog_scope::debug; use std::{collections::HashMap, sync::Arc}; @@ -13,7 +12,8 @@ use mithril_client::{ use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::{ConfigError, ConfigParameters, ConfigSource}, + configuration::{ConfigError, ConfigSource}, + CommandContext, }; /// Clap command to show a given Cardano transaction sets @@ -38,10 +38,8 @@ impl CardanoTransactionsCertifyCommand { } /// Cardano transaction certify command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?) - .add_source(self)?; + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?.add_source(self)?; let progress_output_type = if self.is_json_output_enabled() { ProgressOutputType::JsonReporter diff --git a/mithril-client-cli/src/commands/cardano_transaction/mod.rs b/mithril-client-cli/src/commands/cardano_transaction/mod.rs index 9277ec06672..9fa1e154eae 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/mod.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/mod.rs @@ -7,9 +7,8 @@ pub use certify::*; pub use snapshot_list::*; pub use snapshot_show::*; +use crate::CommandContext; use clap::Subcommand; -use config::builder::DefaultState; -use config::ConfigBuilder; use mithril_client::MithrilResult; /// Cardano transactions management @@ -39,7 +38,7 @@ pub enum CardanoTransactionSnapshotCommands { impl CardanoTransactionCommands { /// Execute Cardano transaction command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::Snapshot(cmd) => cmd.execute(config_builder).await, Self::Certify(cmd) => cmd.execute(config_builder).await, @@ -49,7 +48,7 @@ impl CardanoTransactionCommands { impl CardanoTransactionSnapshotCommands { /// Execute Cardano transaction snapshot command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::List(cmd) => cmd.execute(config_builder).await, Self::Show(cmd) => cmd.execute(config_builder).await, diff --git a/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs b/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs index a92d97884ff..fb82434f82c 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/snapshot_list.rs @@ -1,11 +1,9 @@ use clap::Parser; use cli_table::format::Justify; use cli_table::{print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::commands::{client_builder_with_fallback_genesis_key, SharedArgs}; -use crate::configuration::ConfigParameters; +use crate::CommandContext; use mithril_client::MithrilResult; /// Cardano transaction snapshot list command @@ -22,9 +20,8 @@ impl CardanoTransactionSnapshotListCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.cardano_transaction().list_snapshots().await?; diff --git a/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs b/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs index 723e5649884..e86497c6ab3 100644 --- a/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs +++ b/mithril-client-cli/src/commands/cardano_transaction/snapshot_show.rs @@ -1,13 +1,11 @@ use anyhow::{anyhow, Context}; use clap::Parser; use cli_table::{print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::{ commands::{client_builder_with_fallback_genesis_key, SharedArgs}, - configuration::ConfigParameters, utils::ExpanderUtils, + CommandContext, }; use mithril_client::MithrilResult; @@ -31,9 +29,8 @@ impl CardanoTransactionsSnapshotShowCommand { } /// Cardano transaction snapshot Show command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let get_list_of_artifact_ids = || async { diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs index c78d61bf539..cf239010d89 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/download.rs @@ -1,6 +1,5 @@ use anyhow::Context; use clap::Parser; -use config::{builder::DefaultState, ConfigBuilder}; use std::sync::Arc; use std::{ collections::HashMap, @@ -10,8 +9,9 @@ use std::{ use crate::utils::{IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter}; use crate::{ commands::{client_builder, SharedArgs}, - configuration::{ConfigError, ConfigParameters, ConfigSource}, + configuration::{ConfigError, ConfigSource}, utils::ExpanderUtils, + CommandContext, }; use mithril_client::MessageBuilder; use mithril_client::MithrilResult; @@ -46,10 +46,8 @@ impl MithrilStakeDistributionDownloadCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?) - .add_source(self)?; + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?.add_source(self)?; let download_dir = params.get_or("download_dir", "."); let download_dir = Path::new(&download_dir); diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs index 60cf35ad34e..46ecfe0bd27 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/list.rs @@ -1,11 +1,9 @@ use clap::Parser; use cli_table::{format::Justify, print_stdout, Cell, Table}; -use config::{builder::DefaultState, ConfigBuilder}; -use std::collections::HashMap; use crate::{ commands::{client_builder_with_fallback_genesis_key, SharedArgs}, - configuration::ConfigParameters, + CommandContext, }; use mithril_client::MithrilResult; @@ -23,9 +21,8 @@ impl MithrilStakeDistributionListCommand { } /// Main command execution - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { - let config = config_builder.build()?; - let params = ConfigParameters::new(config.try_deserialize::>()?); + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { + let params = context.config_parameters()?; let client = client_builder_with_fallback_genesis_key(¶ms)?.build()?; let lines = client.mithril_stake_distribution().list().await?; diff --git a/mithril-client-cli/src/commands/mithril_stake_distribution/mod.rs b/mithril-client-cli/src/commands/mithril_stake_distribution/mod.rs index c68ada4c23f..b10cbca856e 100644 --- a/mithril-client-cli/src/commands/mithril_stake_distribution/mod.rs +++ b/mithril-client-cli/src/commands/mithril_stake_distribution/mod.rs @@ -5,8 +5,8 @@ mod list; pub use download::*; pub use list::*; +use crate::CommandContext; use clap::Subcommand; -use config::{builder::DefaultState, ConfigBuilder}; use mithril_client::MithrilResult; /// Mithril Stake Distribution management (alias: msd) @@ -23,7 +23,7 @@ pub enum MithrilStakeDistributionCommands { impl MithrilStakeDistributionCommands { /// Execute Mithril stake distribution command - pub async fn execute(&self, config_builder: ConfigBuilder) -> MithrilResult<()> { + pub async fn execute(&self, config_builder: CommandContext) -> MithrilResult<()> { match self { Self::List(cmd) => cmd.execute(config_builder).await, Self::Download(cmd) => cmd.execute(config_builder).await, diff --git a/mithril-client-cli/src/lib.rs b/mithril-client-cli/src/lib.rs index be6ac2b48eb..1dba789bdbf 100644 --- a/mithril-client-cli/src/lib.rs +++ b/mithril-client-cli/src/lib.rs @@ -7,9 +7,11 @@ // //! You can find more information on how it works reading the [documentation website](https://mithril.network/doc/mithril/mithril-network/client). +mod command_context; pub mod commands; mod configuration; mod utils; +pub use command_context::*; /// Error Clap pub type ClapError = clap::error::Error; diff --git a/mithril-client-cli/src/main.rs b/mithril-client-cli/src/main.rs index 458ff871054..e4aed187721 100644 --- a/mithril-client-cli/src/main.rs +++ b/mithril-client-cli/src/main.rs @@ -19,7 +19,7 @@ use mithril_client_cli::commands::{ cardano_transaction::CardanoTransactionCommands, mithril_stake_distribution::MithrilStakeDistributionCommands, DeprecatedCommand, Deprecation, }; -use mithril_client_cli::ClapError; +use mithril_client_cli::{ClapError, CommandContext}; enum LogOutputType { StdErr, @@ -85,7 +85,7 @@ pub struct Args { } impl Args { - pub async fn execute(&self) -> MithrilResult<()> { + pub async fn execute(&self, root_logger: Logger) -> MithrilResult<()> { debug!("Run Mode: {}", self.run_mode); let filename = format!("{}/{}.json", self.config_directory.display(), self.run_mode); debug!("Reading configuration file '{}'.", filename); @@ -93,8 +93,9 @@ impl Args { .add_source(config::File::with_name(&filename).required(false)) .add_source(self.clone()) .set_default("download_dir", "")?; + let context = CommandContext::new(config, root_logger); - self.command.execute(self.unstable, config).await + self.command.execute(self.unstable, context).await } fn log_level(&self) -> Level { @@ -202,12 +203,12 @@ impl ArtifactCommands { pub async fn execute( &self, unstable_enabled: bool, - config_builder: ConfigBuilder, + context: CommandContext, ) -> MithrilResult<()> { match self { - Self::CardanoDb(cmd) => cmd.execute(config_builder).await, - Self::MithrilStakeDistribution(cmd) => cmd.execute(config_builder).await, - Self::CardanoTransaction(cmd) => cmd.execute(config_builder).await, + Self::CardanoDb(cmd) => cmd.execute(context).await, + Self::MithrilStakeDistribution(cmd) => cmd.execute(context).await, + Self::CardanoTransaction(cmd) => cmd.execute(context).await, Self::CardanoStakeDistribution(cmd) => { if !unstable_enabled { Err(anyhow!(Self::unstable_flag_missing_message( @@ -215,7 +216,7 @@ impl ArtifactCommands { "list" ))) } else { - cmd.execute(config_builder).await + cmd.execute(context).await } } Self::GenerateDoc(cmd) => cmd @@ -242,12 +243,13 @@ async fn main() -> MithrilResult<()> { vec![DeprecatedCommand::new("snapshot", "cardano-db")], ) }); - let _guard = slog_scope::set_global_logger(args.build_logger()?); + let logger = args.build_logger()?; + let _guard = slog_scope::set_global_logger(logger.clone()); #[cfg(feature = "bundle_openssl")] openssl_probe::init_ssl_cert_env_vars(); - args.execute().await + args.execute(logger).await } #[cfg(test)] @@ -260,7 +262,7 @@ mod tests { Args::try_parse_from(["mithril-client", "cardano-stake-distribution", "list"]).unwrap(); let error = args - .execute() + .execute(Logger::root(slog::Discard, slog::o!())) .await .expect_err("Should fail if unstable flag missing"); From f1d95eb509e308f89d255afda2c3847311c46ea6 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:25:34 +0200 Subject: [PATCH 5/6] refactor(client-cli): move unstable flag to context Allowing subcommands to check it if needed. --- mithril-client-cli/src/command_context.rs | 13 ++++++++++++- mithril-client-cli/src/main.rs | 12 ++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/mithril-client-cli/src/command_context.rs b/mithril-client-cli/src/command_context.rs index 93ff40a0902..d91328d8c64 100644 --- a/mithril-client-cli/src/command_context.rs +++ b/mithril-client-cli/src/command_context.rs @@ -10,18 +10,29 @@ use crate::configuration::ConfigParameters; /// Context for the command execution pub struct CommandContext { config_builder: ConfigBuilder, + unstable_enabled: bool, logger: Logger, } impl CommandContext { /// Create a new command context - pub fn new(config_builder: ConfigBuilder, logger: Logger) -> Self { + pub fn new( + config_builder: ConfigBuilder, + unstable_enabled: bool, + logger: Logger, + ) -> Self { Self { config_builder, + unstable_enabled, logger, } } + /// Check if unstable commands are enabled + pub fn is_unstable_enabled(&self) -> bool { + self.unstable_enabled + } + /// Get the configured parameters pub fn config_parameters(&self) -> MithrilResult { let config = self.config_builder.clone().build()?; diff --git a/mithril-client-cli/src/main.rs b/mithril-client-cli/src/main.rs index e4aed187721..11663a6962f 100644 --- a/mithril-client-cli/src/main.rs +++ b/mithril-client-cli/src/main.rs @@ -93,9 +93,9 @@ impl Args { .add_source(config::File::with_name(&filename).required(false)) .add_source(self.clone()) .set_default("download_dir", "")?; - let context = CommandContext::new(config, root_logger); + let context = CommandContext::new(config, self.unstable, root_logger); - self.command.execute(self.unstable, context).await + self.command.execute(context).await } fn log_level(&self) -> Level { @@ -200,17 +200,13 @@ enum ArtifactCommands { } impl ArtifactCommands { - pub async fn execute( - &self, - unstable_enabled: bool, - context: CommandContext, - ) -> MithrilResult<()> { + pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> { match self { Self::CardanoDb(cmd) => cmd.execute(context).await, Self::MithrilStakeDistribution(cmd) => cmd.execute(context).await, Self::CardanoTransaction(cmd) => cmd.execute(context).await, Self::CardanoStakeDistribution(cmd) => { - if !unstable_enabled { + if !context.is_unstable_enabled() { Err(anyhow!(Self::unstable_flag_missing_message( "cardano-stake-distribution", "list" From 13e97a95d5a33aeafad604ef269a748e6b780855 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:13:49 +0200 Subject: [PATCH 6/6] chore: upgrade crate versions * mithril-client-cli from `0.9.15` to `0.9.16` --- Cargo.lock | 2 +- mithril-client-cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaa3aeee4f7..3e2b8225964 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3662,7 +3662,7 @@ dependencies = [ [[package]] name = "mithril-client-cli" -version = "0.9.15" +version = "0.9.16" dependencies = [ "anyhow", "async-trait", diff --git a/mithril-client-cli/Cargo.toml b/mithril-client-cli/Cargo.toml index ba8ec34102d..c2f93355d57 100644 --- a/mithril-client-cli/Cargo.toml +++ b/mithril-client-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-client-cli" -version = "0.9.15" +version = "0.9.16" description = "A Mithril Client" authors = { workspace = true } edition = { workspace = true }