From 0e35a0cd64039b2b2b6515456d59794cd78dce8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Sat, 24 Feb 2024 07:55:37 +0100 Subject: [PATCH] add account check-up command --- src/account/command/check_up.rs | 121 ++++++++++++++++++++++++++++++++ src/account/command/mod.rs | 9 ++- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/account/command/check_up.rs diff --git a/src/account/command/check_up.rs b/src/account/command/check_up.rs new file mode 100644 index 0000000..1015f81 --- /dev/null +++ b/src/account/command/check_up.rs @@ -0,0 +1,121 @@ +use anyhow::Result; +use clap::Parser; +use email::backend::context::BackendContextBuilder; +use log::info; + +use crate::{ + account::arg::name::OptionalAccountNameArg, backend, config::TomlConfig, printer::Printer, +}; + +/// Check up the given account. +/// +/// This command performs a checkup of the given account. It checks if +/// the configuration is valid, if backend can be created and if +/// sessions work. +#[derive(Debug, Parser)] +pub struct AccountCheckUpCommand { + #[command(flatten)] + pub account: OptionalAccountNameArg, +} + +impl AccountCheckUpCommand { + pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { + info!("executing check up account command"); + + let account = self.account.name.as_ref().map(String::as_str); + + printer.print_log("Checking configuration integrity…")?; + + let (toml_account_config, account_config) = + config.clone().into_account_configs(account, true)?; + let used_backends = toml_account_config.get_used_backends(); + + printer.print_log("Checking backend context integrity…")?; + + let ctx_builder = backend::BackendContextBuilder::new( + toml_account_config.clone(), + account_config, + Vec::from_iter(used_backends), + ) + .await?; + + let ctx = ctx_builder.clone().build().await?; + + #[cfg(feature = "maildir")] + { + printer.print_log("Checking Maildir integrity…")?; + + let maildir = ctx_builder + .maildir + .as_ref() + .and_then(|maildir| maildir.check_up()) + .and_then(|f| ctx.maildir.as_ref().and_then(|ctx| f(ctx))); + + if let Some(maildir) = maildir.as_ref() { + maildir.check_up().await?; + } + } + + #[cfg(feature = "imap")] + { + printer.print_log("Checking IMAP integrity…")?; + + let imap = ctx_builder + .imap + .as_ref() + .and_then(|imap| imap.check_up()) + .and_then(|f| ctx.imap.as_ref().and_then(|ctx| f(ctx))); + + if let Some(imap) = imap.as_ref() { + imap.check_up().await?; + } + } + + #[cfg(feature = "notmuch")] + { + printer.print_log("Checking Notmuch integrity…")?; + + let notmuch = ctx_builder + .notmuch + .as_ref() + .and_then(|notmuch| notmuch.check_up()) + .and_then(|f| ctx.notmuch.as_ref().and_then(|ctx| f(ctx))); + + if let Some(notmuch) = notmuch.as_ref() { + notmuch.check_up().await?; + } + } + + #[cfg(feature = "smtp")] + { + printer.print_log("Checking SMTP integrity…")?; + + let smtp = ctx_builder + .smtp + .as_ref() + .and_then(|smtp| smtp.check_up()) + .and_then(|f| ctx.smtp.as_ref().and_then(|ctx| f(ctx))); + + if let Some(smtp) = smtp.as_ref() { + smtp.check_up().await?; + } + } + + #[cfg(feature = "sendmail")] + { + printer.print_log("Checking Sendmail integrity…")?; + + let sendmail = ctx_builder + .sendmail + .as_ref() + .and_then(|sendmail| sendmail.check_up()) + .and_then(|f| ctx.sendmail.as_ref().and_then(|ctx| f(ctx))); + + if let Some(sendmail) = sendmail.as_ref() { + sendmail.check_up().await?; + } + } + + printer.print("Checkup successfully completed!") + } +} diff --git a/src/account/command/mod.rs b/src/account/command/mod.rs index 549068e..7698214 100644 --- a/src/account/command/mod.rs +++ b/src/account/command/mod.rs @@ -1,3 +1,4 @@ +mod check_up; mod configure; mod list; #[cfg(feature = "account-sync")] @@ -10,7 +11,9 @@ use crate::{config::TomlConfig, printer::Printer}; #[cfg(feature = "account-sync")] use self::sync::AccountSyncCommand; -use self::{configure::AccountConfigureCommand, list::AccountListCommand}; +use self::{ + check_up::AccountCheckUpCommand, configure::AccountConfigureCommand, list::AccountListCommand, +}; /// Manage accounts. /// @@ -19,6 +22,9 @@ use self::{configure::AccountConfigureCommand, list::AccountListCommand}; /// file. This subcommand allows you to manage them. #[derive(Debug, Subcommand)] pub enum AccountSubcommand { + #[command(alias = "checkup")] + CheckUp(AccountCheckUpCommand), + #[command(alias = "cfg")] Configure(AccountConfigureCommand), @@ -34,6 +40,7 @@ impl AccountSubcommand { #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + Self::CheckUp(cmd) => cmd.execute(printer, config).await, Self::Configure(cmd) => cmd.execute(printer, config).await, Self::List(cmd) => cmd.execute(printer, config).await, #[cfg(feature = "account-sync")]