use console::Emoji; use harmony::instrumentation::{self, HarmonyEvent}; use indicatif::{ProgressBar, ProgressStyle}; use lazy_static::lazy_static; use log::error; use std::{ sync::{Arc, Mutex}, time::Duration, }; static EMOJI_HARMONY: Emoji<'_, '_> = Emoji("🎼", ""); static EMOJI_SUCCESS: Emoji<'_, '_> = Emoji("✅", ""); static EMOJI_ERROR: Emoji<'_, '_> = Emoji("⚠️", ""); static EMOJI_DEPLOY: Emoji<'_, '_> = Emoji("🚀", ""); static EMOJI_TOPOLOGY: Emoji<'_, '_> = Emoji("📦", ""); lazy_static! { pub static ref SPINNER_STYLE: ProgressStyle = ProgressStyle::default_spinner() .template(" {spinner:.green} {msg}") .unwrap() .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]); pub static ref SUCCESS_SPINNER_STYLE: ProgressStyle = SPINNER_STYLE .clone() .tick_strings(&[format!("{}", EMOJI_SUCCESS).as_str()]); pub static ref ERROR_SPINNER_STYLE: ProgressStyle = SPINNER_STYLE .clone() .tick_strings(&[format!("{}", EMOJI_ERROR).as_str()]); } pub async fn init() { instrumentation::subscribe("CLI Logger", { let current_spinner = Arc::new(Mutex::new(None::)); move |event| { let spinner_clone = Arc::clone(¤t_spinner); async move { let mut spinner_guard = spinner_clone.lock().unwrap(); match event { HarmonyEvent::ProjectInitializationStarted => { println!("{} Initializing Harmony project...", EMOJI_HARMONY); } HarmonyEvent::ProjectInitialized => println!("\n"), HarmonyEvent::ProjectCompilationStarted { details } => { let progress = ProgressBar::new_spinner(); progress.set_style(SPINNER_STYLE.clone()); progress.set_message(details); progress.enable_steady_tick(Duration::from_millis(100)); *spinner_guard = Some(progress); } HarmonyEvent::ProjectCompiled => { if let Some(progress) = spinner_guard.take() { progress.set_style(SUCCESS_SPINNER_STYLE.clone()); progress.finish_with_message("project compiled"); } } HarmonyEvent::ProjectCompilationFailed { details } => { if let Some(progress) = spinner_guard.take() { progress.set_style(ERROR_SPINNER_STYLE.clone()); progress.finish_with_message("failed to compile project"); error!("{details}"); } } HarmonyEvent::DeploymentStarted { target } => { println!("{} Starting deployment to {target}...", EMOJI_DEPLOY); } HarmonyEvent::DeploymentCompleted { details } => println!("\n"), HarmonyEvent::PrepareTopologyStarted { name } => { println!("{} Preparing environment: {name}...", EMOJI_TOPOLOGY); } HarmonyEvent::Shutdown => { if let Some(progress) = spinner_guard.take() { progress.abandon(); } return false; } } true } } }) .await }