/ crates / acdc / src / commands / update.rs
update.rs
  1  //! Update command.
  2  
  3  use anyhow::Result;
  4  
  5  pub async fn run(self_only: bool, check: bool) -> Result<()> {
  6      if check {
  7          // Check for updates without installing
  8          let info = acdc_update::check().await?;
  9          println!("{}", info.format());
 10          return Ok(());
 11      }
 12  
 13      if self_only {
 14          // Update only ac-dc itself
 15          println!("Checking for ac-dc updates...");
 16          acdc_update::update_self(false).await?;
 17      } else {
 18          // Update everything
 19          println!("Checking for updates...");
 20  
 21          // Check for self-update first
 22          let info = acdc_update::check().await?;
 23  
 24          if info.update_available {
 25              println!(
 26                  "AC/DC update available: {} -> {}",
 27                  info.current_version,
 28                  info.latest_version.as_deref().unwrap_or("unknown")
 29              );
 30              println!("Updating ac-dc...");
 31              acdc_update::update_self(false).await?;
 32          } else {
 33              println!("AC/DC is up to date ({})", info.current_version);
 34          }
 35  
 36          // Update components
 37          if !info.component_updates.is_empty() {
 38              println!("\nUpdating components...");
 39              acdc_update::update_components(None).await?;
 40          } else {
 41              println!("All components are up to date.");
 42          }
 43      }
 44  
 45      Ok(())
 46  }
 47  
 48  /// Rollback to a previous version.
 49  pub async fn rollback(component: Option<&str>) -> Result<()> {
 50      match component {
 51          Some(name) => {
 52              println!("Rolling back {}...", name);
 53              acdc_update::rollback::rollback_component(name).await?;
 54          }
 55          None => {
 56              println!("Rolling back ac-dc...");
 57              acdc_update::rollback().await?;
 58          }
 59      }
 60  
 61      Ok(())
 62  }
 63  
 64  /// List available rollback targets.
 65  pub fn list_rollbacks() -> Result<()> {
 66      let rollbacks = acdc_update::rollback::list_available_rollbacks();
 67  
 68      if rollbacks.is_empty() {
 69          println!("No rollback targets available.");
 70          return Ok(());
 71      }
 72  
 73      println!("Available Rollback Targets");
 74      println!("==========================\n");
 75  
 76      for info in rollbacks {
 77          println!("  {} (backup: {})", info.name, info.format_time());
 78      }
 79  
 80      Ok(())
 81  }
 82  
 83  /// Check for updates.
 84  pub async fn check_updates() -> Result<()> {
 85      let info = acdc_update::check().await?;
 86      println!("{}", info.format());
 87      Ok(())
 88  }
 89  
 90  /// Update a specific component.
 91  pub async fn update_component(name: &str) -> Result<()> {
 92      println!("Updating {}...", name);
 93      acdc_update::update_components(Some(name)).await?;
 94      Ok(())
 95  }
 96  
 97  /// List installed components.
 98  pub fn list_components() -> Result<()> {
 99      let components = acdc_update::components::list_installed();
100  
101      println!("Installed Components");
102      println!("====================\n");
103  
104      for (component, version) in components {
105          match version {
106              Some(v) => println!("  {}: v{}", component.name(), v),
107              None => println!("  {}: not installed", component.name()),
108          }
109      }
110  
111      Ok(())
112  }