From ceafabf430c7acc3a74d0bd831b5ce2aee3955ed Mon Sep 17 00:00:00 2001 From: Ian Letourneau Date: Tue, 9 Sep 2025 17:59:14 -0400 Subject: [PATCH] wip: Report harmony execution outcome --- harmony/src/domain/interpret/mod.rs | 21 ++++++ harmony/src/modules/dhcp.rs | 41 +++++----- harmony/src/modules/dns.rs | 17 ++--- harmony/src/modules/helm/chart.rs | 35 ++++----- harmony/src/modules/inventory/mod.rs | 7 +- harmony/src/modules/k8s/ingress.rs | 75 +++++++++++++++++-- .../src/modules/okd/bootstrap_01_prepare.rs | 25 +++---- .../src/modules/okd/bootstrap_02_bootstrap.rs | 28 +++---- .../modules/okd/bootstrap_03_control_plane.rs | 17 ++--- .../src/modules/okd/bootstrap_04_workers.rs | 33 ++------ .../modules/okd/bootstrap_05_sanity_check.rs | 40 +++------- .../okd/bootstrap_06_installation_report.rs | 32 ++------ harmony_cli/src/cli_reporter.rs | 32 ++++++++ harmony_cli/src/lib.rs | 2 + .../src/harmony_composer_logger.rs | 1 - harmony_composer/src/instrumentation.rs | 1 - 16 files changed, 217 insertions(+), 190 deletions(-) create mode 100644 harmony_cli/src/cli_reporter.rs diff --git a/harmony/src/domain/interpret/mod.rs b/harmony/src/domain/interpret/mod.rs index f1abcda..17afa86 100644 --- a/harmony/src/domain/interpret/mod.rs +++ b/harmony/src/domain/interpret/mod.rs @@ -34,6 +34,7 @@ pub enum InterpretName { CephClusterHealth, Custom(&'static str), RHOBAlerting, + K8sIngress, } impl std::fmt::Display for InterpretName { @@ -64,6 +65,7 @@ impl std::fmt::Display for InterpretName { InterpretName::CephClusterHealth => f.write_str("CephClusterHealth"), InterpretName::Custom(name) => f.write_str(name), InterpretName::RHOBAlerting => f.write_str("RHOBAlerting"), + InterpretName::K8sIngress => f.write_str("K8sIngress"), } } } @@ -82,6 +84,7 @@ pub trait Interpret: std::fmt::Debug + Send { pub struct Outcome { pub status: InterpretStatus, pub message: String, + pub details: Vec, } impl Outcome { @@ -89,6 +92,7 @@ impl Outcome { Self { status: InterpretStatus::NOOP, message: String::new(), + details: vec![], } } @@ -96,6 +100,23 @@ impl Outcome { Self { status: InterpretStatus::SUCCESS, message, + details: vec![], + } + } + + pub fn success_with_details(message: String, details: Vec) -> Self { + Self { + status: InterpretStatus::SUCCESS, + message, + details, + } + } + + pub fn running(message: String) -> Self { + Self { + status: InterpretStatus::RUNNING, + message, + details: vec![], } } } diff --git a/harmony/src/modules/dhcp.rs b/harmony/src/modules/dhcp.rs index eff2912..e261220 100644 --- a/harmony/src/modules/dhcp.rs +++ b/harmony/src/modules/dhcp.rs @@ -69,17 +69,14 @@ impl DhcpInterpret { dhcp_server.set_pxe_options(pxe_options).await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!( - "Dhcp Interpret Set next boot to [{:?}], boot_filename to [{:?}], filename to [{:?}], filename64 to [{:?}], filenameipxe to [:{:?}]", - self.score.boot_filename, - self.score.boot_filename, - self.score.filename, - self.score.filename64, - self.score.filenameipxe - ), - )) + Ok(Outcome::success(format!( + "Dhcp Interpret Set next boot to [{:?}], boot_filename to [{:?}], filename to [{:?}], filename64 to [{:?}], filenameipxe to [:{:?}]", + self.score.boot_filename, + self.score.boot_filename, + self.score.filename, + self.score.filename64, + self.score.filenameipxe + ))) } } @@ -122,8 +119,7 @@ impl Interpret for DhcpInterpret { topology.commit_config().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, + Ok(Outcome::success( "Dhcp Interpret execution successful".to_string(), )) } @@ -197,10 +193,10 @@ impl DhcpHostBindingInterpret { } } - Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!("Dhcp Interpret registered {} entries", number_new_entries), - )) + Ok(Outcome::success(format!( + "Dhcp Interpret registered {} entries", + number_new_entries + ))) } } @@ -236,12 +232,9 @@ impl Interpret for DhcpHostBindingInterpret { topology.commit_config().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!( - "Dhcp Host Binding Interpret execution successful on {} hosts", - self.score.host_binding.len() - ), - )) + Ok(Outcome::success(format!( + "Dhcp Host Binding Interpret execution successful on {} hosts", + self.score.host_binding.len() + ))) } } diff --git a/harmony/src/modules/dns.rs b/harmony/src/modules/dns.rs index 9608fa1..b0d3a1d 100644 --- a/harmony/src/modules/dns.rs +++ b/harmony/src/modules/dns.rs @@ -55,8 +55,7 @@ impl DnsInterpret { dns.register_dhcp_leases(register).await?; } - Ok(Outcome::new( - InterpretStatus::SUCCESS, + Ok(Outcome::success( "DNS Interpret execution successfull".to_string(), )) } @@ -68,13 +67,10 @@ impl DnsInterpret { let entries = &self.score.dns_entries; dns_server.ensure_hosts_registered(entries.clone()).await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!( - "DnsInterpret registered {} hosts successfully", - entries.len() - ), - )) + Ok(Outcome::success(format!( + "DnsInterpret registered {} hosts successfully", + entries.len() + ))) } } @@ -111,8 +107,7 @@ impl Interpret for DnsInterpret { topology.commit_config().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, + Ok(Outcome::success( "Dns Interpret execution successful".to_string(), )) } diff --git a/harmony/src/modules/helm/chart.rs b/harmony/src/modules/helm/chart.rs index 37769d7..e2f8057 100644 --- a/harmony/src/modules/helm/chart.rs +++ b/harmony/src/modules/helm/chart.rs @@ -197,13 +197,10 @@ impl Interpret for HelmChartInterpret { self.score.release_name, ns ); - return Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!( - "Helm Chart '{}' already installed to namespace {ns} and install_only=true", - self.score.release_name - ), - )); + return Ok(Outcome::success(format!( + "Helm Chart '{}' already installed to namespace {ns} and install_only=true", + self.score.release_name + ))); } else { info!( "Release '{}' not found in namespace '{}'. Proceeding with installation.", @@ -228,18 +225,18 @@ impl Interpret for HelmChartInterpret { }; match status { - helm_wrapper_rs::HelmDeployStatus::Deployed => Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!("Helm Chart {} deployed", self.score.release_name), - )), - helm_wrapper_rs::HelmDeployStatus::PendingInstall => Ok(Outcome::new( - InterpretStatus::RUNNING, - format!("Helm Chart {} pending install...", self.score.release_name), - )), - helm_wrapper_rs::HelmDeployStatus::PendingUpgrade => Ok(Outcome::new( - InterpretStatus::RUNNING, - format!("Helm Chart {} pending upgrade...", self.score.release_name), - )), + helm_wrapper_rs::HelmDeployStatus::Deployed => Ok(Outcome::success(format!( + "Helm Chart {} deployed", + self.score.release_name + ))), + helm_wrapper_rs::HelmDeployStatus::PendingInstall => Ok(Outcome::running(format!( + "Helm Chart {} pending install...", + self.score.release_name + ))), + helm_wrapper_rs::HelmDeployStatus::PendingUpgrade => Ok(Outcome::running(format!( + "Helm Chart {} pending upgrade...", + self.score.release_name + ))), helm_wrapper_rs::HelmDeployStatus::Failed => Err(InterpretError::new(format!( "Helm Chart {} installation failed", self.score.release_name diff --git a/harmony/src/modules/inventory/mod.rs b/harmony/src/modules/inventory/mod.rs index 0274dc4..174231b 100644 --- a/harmony/src/modules/inventory/mod.rs +++ b/harmony/src/modules/inventory/mod.rs @@ -133,10 +133,9 @@ impl Interpret for DiscoverInventoryAgentInterpret { }, ) .await; - Ok(Outcome { - status: InterpretStatus::SUCCESS, - message: "Discovery process completed successfully".to_string(), - }) + Ok(Outcome::success( + "Discovery process completed successfully".to_string(), + )) } fn get_name(&self) -> InterpretName { diff --git a/harmony/src/modules/k8s/ingress.rs b/harmony/src/modules/k8s/ingress.rs index eb5478f..d94a1aa 100644 --- a/harmony/src/modules/k8s/ingress.rs +++ b/harmony/src/modules/k8s/ingress.rs @@ -1,11 +1,15 @@ +use async_trait::async_trait; use harmony_macros::ingress_path; +use harmony_types::id::Id; use k8s_openapi::api::networking::v1::Ingress; use log::{debug, trace}; use serde::Serialize; use serde_json::json; use crate::{ - interpret::Interpret, + data::Version, + interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, + inventory::Inventory, score::Score, topology::{K8sclient, Topology}, }; @@ -57,7 +61,7 @@ impl Score for K8sIngressScore { let ingress_class = match self.ingress_class_name.clone() { Some(ingress_class_name) => ingress_class_name, - None => format!("\"default\""), + None => "\"default\"".to_string(), }; let ingress = json!( @@ -97,11 +101,12 @@ impl Score for K8sIngressScore { "Successfully built Ingress for host {:?}", ingress.metadata.name ); - Box::new(K8sResourceInterpret { - score: K8sResourceScore::single( - ingress.clone(), - self.namespace.clone().map(|f| f.to_string()), - ), + + Box::new(K8sIngressInterpret { + ingress, + service: self.name.to_string(), + namespace: self.namespace.clone().map(|f| f.to_string()), + host: self.host.clone(), }) } @@ -109,3 +114,59 @@ impl Score for K8sIngressScore { format!("{} K8sIngressScore", self.name) } } + +#[derive(std::fmt::Debug)] +struct K8sIngressInterpret { + ingress: Ingress, + service: String, + namespace: Option, + host: fqdn::FQDN, +} + +#[async_trait] +impl Interpret for K8sIngressInterpret { + async fn execute( + &self, + inventory: &Inventory, + topology: &T, + ) -> Result { + let result = K8sResourceInterpret { + score: K8sResourceScore::single(self.ingress.clone(), self.namespace.clone()), + } + .execute(inventory, topology) + .await; + + match result { + Ok(outcome) => match outcome.status { + InterpretStatus::SUCCESS => { + let details = match &self.namespace { + Some(namespace) => { + vec![format!("{} ({namespace}): {}", self.service, self.host)] + } + None => vec![format!("{}: {}", self.service, self.host)], + }; + + Ok(Outcome::success_with_details(outcome.message, details)) + } + _ => Ok(outcome), + }, + Err(e) => Err(e), + } + } + + fn get_name(&self) -> InterpretName { + InterpretName::K8sIngress + } + + fn get_version(&self) -> Version { + Version::from("0.0.1").unwrap() + } + + fn get_status(&self) -> InterpretStatus { + todo!() + } + + fn get_children(&self) -> Vec { + vec![] + } +} diff --git a/harmony/src/modules/okd/bootstrap_01_prepare.rs b/harmony/src/modules/okd/bootstrap_01_prepare.rs index d3409e2..57b71d9 100644 --- a/harmony/src/modules/okd/bootstrap_01_prepare.rs +++ b/harmony/src/modules/okd/bootstrap_01_prepare.rs @@ -1,19 +1,19 @@ -use async_trait::async_trait; -use derive_new::new; -use harmony_types::id::Id; -use log::{error, info, warn}; -use serde::Serialize; - use crate::{ data::Version, hardware::PhysicalHost, infra::inventory::InventoryRepositoryFactory, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::{HostRole, Inventory}, - modules::inventory::{DiscoverHostForRoleScore, LaunchDiscoverInventoryAgentScore}, + modules::inventory::DiscoverHostForRoleScore, score::Score, topology::HAClusterTopology, }; +use async_trait::async_trait; +use derive_new::new; +use harmony_types::id::Id; +use log::info; +use serde::Serialize; + // ------------------------------------------------------------------------------------------------- // Step 01: Inventory (default PXE + Kickstart in RAM + Rust agent) // - This score exposes/ensures the default inventory assets and waits for discoveries. @@ -109,12 +109,9 @@ When you can dig them, confirm to continue. .await?; } - Ok(Outcome::new( - InterpretStatus::SUCCESS, - format!( - "Found and assigned bootstrap node: {}", - bootstrap_host.unwrap().summary() - ), - )) + Ok(Outcome::success(format!( + "Found and assigned bootstrap node: {}", + bootstrap_host.unwrap().summary() + ))) } } diff --git a/harmony/src/modules/okd/bootstrap_02_bootstrap.rs b/harmony/src/modules/okd/bootstrap_02_bootstrap.rs index 5b940fb..e9b3a6a 100644 --- a/harmony/src/modules/okd/bootstrap_02_bootstrap.rs +++ b/harmony/src/modules/okd/bootstrap_02_bootstrap.rs @@ -1,25 +1,13 @@ -use std::{fmt::Write, path::PathBuf}; - -use async_trait::async_trait; -use derive_new::new; -use harmony_secret::SecretManager; -use harmony_types::id::Id; -use log::{debug, error, info, warn}; -use serde::{Deserialize, Serialize}; -use tokio::{fs::File, io::AsyncWriteExt, process::Command}; - use crate::{ config::secret::{RedhatSecret, SshKeyPair}, data::{FileContent, FilePath, Version}, hardware::PhysicalHost, infra::inventory::InventoryRepositoryFactory, - instrumentation::{HarmonyEvent, instrument}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::{HostRole, Inventory}, modules::{ dhcp::DhcpHostBindingScore, http::{IPxeMacBootFileScore, StaticFilesHttpScore}, - inventory::LaunchDiscoverInventoryAgentScore, okd::{ bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, templates::{BootstrapIpxeTpl, InstallConfigYaml}, @@ -28,6 +16,15 @@ use crate::{ score::Score, topology::{HAClusterTopology, HostBinding}, }; +use async_trait::async_trait; +use derive_new::new; +use harmony_secret::SecretManager; +use harmony_types::id::Id; +use log::{debug, info}; +use serde::Serialize; +use std::path::PathBuf; +use tokio::{fs::File, io::AsyncWriteExt, process::Command}; + // ------------------------------------------------------------------------------------------------- // Step 02: Bootstrap // - Select bootstrap node (from discovered set). @@ -313,7 +310,7 @@ impl OKDSetup02BootstrapInterpret { info!("[Bootstrap] Rebooting bootstrap node via SSH"); // TODO reboot programatically, there are some logical checks and refactoring to do such as // accessing the bootstrap node config (ip address) from the inventory - let confirmation = inquire::Confirm::new( + let _ = inquire::Confirm::new( "Now reboot the bootstrap node so it picks up its pxe boot file. Press enter when ready.", ) .prompt() @@ -379,9 +376,6 @@ impl Interpret for OKDSetup02BootstrapInterpret { self.reboot_target().await?; self.wait_for_bootstrap_complete().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - "Bootstrap phase complete".into(), - )) + Ok(Outcome::success("Bootstrap phase complete".into())) } } diff --git a/harmony/src/modules/okd/bootstrap_03_control_plane.rs b/harmony/src/modules/okd/bootstrap_03_control_plane.rs index a387e1e..ba9e12d 100644 --- a/harmony/src/modules/okd/bootstrap_03_control_plane.rs +++ b/harmony/src/modules/okd/bootstrap_03_control_plane.rs @@ -1,11 +1,3 @@ -use std::{fmt::Write, path::PathBuf}; - -use async_trait::async_trait; -use derive_new::new; -use harmony_types::id::Id; -use log::{debug, info}; -use serde::Serialize; - use crate::{ data::Version, hardware::PhysicalHost, @@ -19,6 +11,12 @@ use crate::{ score::Score, topology::{HAClusterTopology, HostBinding}, }; +use async_trait::async_trait; +use derive_new::new; +use harmony_types::id::Id; +use log::{debug, info}; +use serde::Serialize; + // ------------------------------------------------------------------------------------------------- // Step 03: Control Plane // - Render per-MAC PXE & ignition for cp0/cp1/cp2. @@ -269,8 +267,7 @@ impl Interpret for OKDSetup03ControlPlaneInterpret { // the `wait-for bootstrap-complete` command. info!("[ControlPlane] Provisioning initiated. Monitor the cluster convergence manually."); - Ok(Outcome::new( - InterpretStatus::SUCCESS, + Ok(Outcome::success( "Control plane provisioning has been successfully initiated.".into(), )) } diff --git a/harmony/src/modules/okd/bootstrap_04_workers.rs b/harmony/src/modules/okd/bootstrap_04_workers.rs index d5ed87c..461cab9 100644 --- a/harmony/src/modules/okd/bootstrap_04_workers.rs +++ b/harmony/src/modules/okd/bootstrap_04_workers.rs @@ -1,33 +1,17 @@ -use std::{fmt::Write, path::PathBuf}; - use async_trait::async_trait; use derive_new::new; -use harmony_secret::SecretManager; use harmony_types::id::Id; -use log::{debug, error, info, warn}; -use serde::{Deserialize, Serialize}; -use tokio::{fs::File, io::AsyncWriteExt, process::Command}; +use log::info; +use serde::Serialize; use crate::{ - config::secret::{RedhatSecret, SshKeyPair}, - data::{FileContent, FilePath, Version}, - hardware::PhysicalHost, - infra::inventory::InventoryRepositoryFactory, - instrumentation::{HarmonyEvent, instrument}, + data::Version, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, - inventory::{HostRole, Inventory}, - modules::{ - dhcp::DhcpHostBindingScore, - http::{IPxeMacBootFileScore, StaticFilesHttpScore}, - inventory::LaunchDiscoverInventoryAgentScore, - okd::{ - bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, - templates::{BootstrapIpxeTpl, InstallConfigYaml}, - }, - }, + inventory::Inventory, score::Score, - topology::{HAClusterTopology, HostBinding}, + topology::HAClusterTopology, }; + // ------------------------------------------------------------------------------------------------- // Step 04: Workers // - Render per-MAC PXE & ignition for workers; join nodes. @@ -94,9 +78,6 @@ impl Interpret for OKDSetup04WorkersInterpret { _topology: &HAClusterTopology, ) -> Result { self.render_and_reboot().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - "Workers provisioned".into(), - )) + Ok(Outcome::success("Workers provisioned".into())) } } diff --git a/harmony/src/modules/okd/bootstrap_05_sanity_check.rs b/harmony/src/modules/okd/bootstrap_05_sanity_check.rs index f1a4c2a..23a24b5 100644 --- a/harmony/src/modules/okd/bootstrap_05_sanity_check.rs +++ b/harmony/src/modules/okd/bootstrap_05_sanity_check.rs @@ -1,33 +1,16 @@ -use std::{fmt::Write, path::PathBuf}; - +use crate::{ + data::Version, + interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, + inventory::Inventory, + score::Score, + topology::HAClusterTopology, +}; use async_trait::async_trait; use derive_new::new; -use harmony_secret::SecretManager; use harmony_types::id::Id; -use log::{debug, error, info, warn}; -use serde::{Deserialize, Serialize}; -use tokio::{fs::File, io::AsyncWriteExt, process::Command}; +use log::info; +use serde::Serialize; -use crate::{ - config::secret::{RedhatSecret, SshKeyPair}, - data::{FileContent, FilePath, Version}, - hardware::PhysicalHost, - infra::inventory::InventoryRepositoryFactory, - instrumentation::{HarmonyEvent, instrument}, - interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, - inventory::{HostRole, Inventory}, - modules::{ - dhcp::DhcpHostBindingScore, - http::{IPxeMacBootFileScore, StaticFilesHttpScore}, - inventory::LaunchDiscoverInventoryAgentScore, - okd::{ - bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, - templates::{BootstrapIpxeTpl, InstallConfigYaml}, - }, - }, - score::Score, - topology::{HAClusterTopology, HostBinding}, -}; // ------------------------------------------------------------------------------------------------- // Step 05: Sanity Check // - Validate API reachability, ClusterOperators, ingress, and SDN status. @@ -93,9 +76,6 @@ impl Interpret for OKDSetup05SanityCheckInterpret { _topology: &HAClusterTopology, ) -> Result { self.run_checks().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - "Sanity checks passed".into(), - )) + Ok(Outcome::success("Sanity checks passed".into())) } } diff --git a/harmony/src/modules/okd/bootstrap_06_installation_report.rs b/harmony/src/modules/okd/bootstrap_06_installation_report.rs index 2713bd2..07d379c 100644 --- a/harmony/src/modules/okd/bootstrap_06_installation_report.rs +++ b/harmony/src/modules/okd/bootstrap_06_installation_report.rs @@ -1,32 +1,15 @@ -// ------------------------------------------------------------------------------------------------- use async_trait::async_trait; use derive_new::new; -use harmony_secret::SecretManager; use harmony_types::id::Id; -use log::{debug, error, info, warn}; -use serde::{Deserialize, Serialize}; -use std::{fmt::Write, path::PathBuf}; -use tokio::{fs::File, io::AsyncWriteExt, process::Command}; +use log::info; +use serde::Serialize; use crate::{ - config::secret::{RedhatSecret, SshKeyPair}, - data::{FileContent, FilePath, Version}, - hardware::PhysicalHost, - infra::inventory::InventoryRepositoryFactory, - instrumentation::{HarmonyEvent, instrument}, + data::Version, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, - inventory::{HostRole, Inventory}, - modules::{ - dhcp::DhcpHostBindingScore, - http::{IPxeMacBootFileScore, StaticFilesHttpScore}, - inventory::LaunchDiscoverInventoryAgentScore, - okd::{ - bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, - templates::{BootstrapIpxeTpl, InstallConfigYaml}, - }, - }, + inventory::Inventory, score::Score, - topology::{HAClusterTopology, HostBinding}, + topology::HAClusterTopology, }; // Step 06: Installation Report @@ -93,9 +76,6 @@ impl Interpret for OKDSetup06InstallationReportInterpret { _topology: &HAClusterTopology, ) -> Result { self.generate().await?; - Ok(Outcome::new( - InterpretStatus::SUCCESS, - "Installation report generated".into(), - )) + Ok(Outcome::success("Installation report generated".into())) } } diff --git a/harmony_cli/src/cli_reporter.rs b/harmony_cli/src/cli_reporter.rs new file mode 100644 index 0000000..da43a8a --- /dev/null +++ b/harmony_cli/src/cli_reporter.rs @@ -0,0 +1,32 @@ +use std::sync::Mutex; + +use harmony::instrumentation::{self, HarmonyEvent}; +use log::info; + +pub fn init() { + let details: Mutex> = Mutex::new(vec![]); + + instrumentation::subscribe("Harmony CLI Reporter", { + move |event| { + let mut details = details.lock().unwrap(); + + if let HarmonyEvent::InterpretExecutionFinished { + execution_id: _, + topology: _, + interpret: _, + score: _, + outcome: Ok(outcome), + } = event + { + if outcome.status == harmony::interpret::InterpretStatus::SUCCESS { + details.extend(outcome.details.clone()); + } + } else if let HarmonyEvent::HarmonyFinished = event { + info!("Here's a summary of what happened:"); + for detail in details.iter() { + println!("{detail}"); + } + } + } + }); +} diff --git a/harmony_cli/src/lib.rs b/harmony_cli/src/lib.rs index 0bfb1e7..4a0dbe7 100644 --- a/harmony_cli/src/lib.rs +++ b/harmony_cli/src/lib.rs @@ -8,6 +8,7 @@ use inquire::Confirm; use log::debug; pub mod cli_logger; // FIXME: Don't make me pub +mod cli_reporter; pub mod progress; pub mod theme; @@ -116,6 +117,7 @@ pub async fn run_cli( args: Args, ) -> Result<(), Box> { cli_logger::init(); + cli_reporter::init(); let mut maestro = Maestro::initialize(inventory, topology).await.unwrap(); maestro.register_all(scores); diff --git a/harmony_composer/src/harmony_composer_logger.rs b/harmony_composer/src/harmony_composer_logger.rs index 040a167..6351751 100644 --- a/harmony_composer/src/harmony_composer_logger.rs +++ b/harmony_composer/src/harmony_composer_logger.rs @@ -21,7 +21,6 @@ pub fn handle_events() { instrumentation::subscribe("Harmony Composer Logger", { move |event| match event { - HarmonyComposerEvent::HarmonyComposerStarted => {} HarmonyComposerEvent::ProjectInitializationStarted => { progress_tracker.add_section( SETUP_SECTION, diff --git a/harmony_composer/src/instrumentation.rs b/harmony_composer/src/instrumentation.rs index b9164b7..509d39c 100644 --- a/harmony_composer/src/instrumentation.rs +++ b/harmony_composer/src/instrumentation.rs @@ -5,7 +5,6 @@ use crate::{HarmonyProfile, HarmonyTarget}; #[derive(Debug, Clone)] pub enum HarmonyComposerEvent { - HarmonyComposerStarted, ProjectInitializationStarted, ProjectInitialized, ProjectCompilationStarted {