/ crates / acdc-update / src / lib.rs
lib.rs
  1  //! Update system for AC/DC.
  2  //!
  3  //! This crate handles updates for AC/DC itself and installed components:
  4  //! - Self-update functionality for the ac-dc binary
  5  //! - Component updates (ADNet, ADL, SDK)
  6  //! - Version checking
  7  //! - Rollback support
  8  
  9  use acdc_core::Result;
 10  use serde::{Deserialize, Serialize};
 11  
 12  pub mod components;
 13  pub mod rollback;
 14  pub mod self_update;
 15  pub mod version;
 16  
 17  pub use version::VersionInfo;
 18  
 19  /// Check for available updates.
 20  pub async fn check() -> Result<UpdateInfo> {
 21      let current_version = env!("CARGO_PKG_VERSION").to_string();
 22  
 23      // Check for self-update
 24      let latest_version = self_update::check_version().await.ok().flatten();
 25      let update_available = latest_version
 26          .as_ref()
 27          .map(|v| v != &current_version)
 28          .unwrap_or(false);
 29  
 30      // Check for component updates
 31      let component_updates = components::check().await.unwrap_or_default();
 32  
 33      Ok(UpdateInfo {
 34          current_version,
 35          latest_version,
 36          update_available,
 37          component_updates,
 38      })
 39  }
 40  
 41  /// Update AC/DC itself.
 42  pub async fn update_self(force: bool) -> Result<()> {
 43      self_update::update(force).await
 44  }
 45  
 46  /// Update installed components.
 47  pub async fn update_components(component: Option<&str>) -> Result<()> {
 48      if let Some(name) = component {
 49          components::update(name).await
 50      } else {
 51          components::update_all().await
 52      }
 53  }
 54  
 55  /// Rollback to previous version.
 56  pub async fn rollback() -> Result<()> {
 57      rollback::rollback().await
 58  }
 59  
 60  /// Information about available updates.
 61  #[derive(Debug, Clone, Serialize, Deserialize)]
 62  pub struct UpdateInfo {
 63      /// Current AC/DC version
 64      pub current_version: String,
 65      /// Latest available version
 66      pub latest_version: Option<String>,
 67      /// Whether an update is available
 68      pub update_available: bool,
 69      /// Component updates available
 70      pub component_updates: Vec<ComponentUpdate>,
 71  }
 72  
 73  impl UpdateInfo {
 74      /// Format update info for display.
 75      pub fn format(&self) -> String {
 76          let mut output = String::new();
 77  
 78          output.push_str("Update Status\n");
 79          output.push_str("═════════════\n\n");
 80  
 81          output.push_str(&format!("AC/DC Version: {}\n", self.current_version));
 82  
 83          if let Some(ref latest) = self.latest_version {
 84              if self.update_available {
 85                  output.push_str(&format!("Latest Version: {} (update available!)\n", latest));
 86              } else {
 87                  output.push_str(&format!("Latest Version: {} (up to date)\n", latest));
 88              }
 89          } else {
 90              output.push_str("Latest Version: Unable to check\n");
 91          }
 92  
 93          if !self.component_updates.is_empty() {
 94              output.push_str("\nComponent Updates Available:\n");
 95              for update in &self.component_updates {
 96                  output.push_str(&format!(
 97                      "  {} {} → {}\n",
 98                      update.name, update.current, update.latest
 99                  ));
100              }
101          } else {
102              output.push_str("\nAll components are up to date.\n");
103          }
104  
105          output
106      }
107  }
108  
109  /// Information about a component update.
110  #[derive(Debug, Clone, Serialize, Deserialize)]
111  pub struct ComponentUpdate {
112      /// Component name
113      pub name: String,
114      /// Current version
115      pub current: String,
116      /// Latest version
117      pub latest: String,
118  }