ggen_cli_lib/cmds/
update.rs

1use anyhow::{Context, Result};
2use clap::Args;
3use ggen_core::{CacheManager, LockfileManager, RegistryClient};
4use std::env;
5
6#[derive(Args, Debug)]
7pub struct UpdateArgs {
8    /// Specific rpack ID to update (if not provided, updates all)
9    pub rpack_id: Option<String>,
10}
11
12pub async fn run(args: &UpdateArgs) -> Result<()> {
13    // Get current working directory
14    let current_dir = env::current_dir()?;
15    let lockfile_manager = LockfileManager::new(&current_dir);
16    let cache_manager = CacheManager::new()?;
17    let registry_client = RegistryClient::new()?;
18
19    // Get installed packs
20    let installed_packs = lockfile_manager.list()?;
21
22    if installed_packs.is_empty() {
23        println!("No rpacks installed in this project");
24        return Ok(());
25    }
26
27    // Filter packs to update
28    let packs_to_update = if let Some(rpack_id) = &args.rpack_id {
29        installed_packs
30            .into_iter()
31            .filter(|pack| pack.id == *rpack_id)
32            .collect::<Vec<_>>()
33    } else {
34        installed_packs
35    };
36
37    if packs_to_update.is_empty() {
38        if let Some(rpack_id) = &args.rpack_id {
39            println!("Rpack '{}' is not installed", rpack_id);
40        }
41        return Ok(());
42    }
43
44    let mut updated_count = 0;
45
46    for pack in packs_to_update {
47        println!("Checking for updates to '{}'...", pack.id);
48
49        // Check for updates
50        match registry_client.check_updates(&pack.id, &pack.version).await {
51            Ok(Some(new_pack)) => {
52                println!("Found update: {} -> {}", pack.version, new_pack.version);
53
54                // Download new version
55                let _cached_pack = cache_manager
56                    .ensure(&new_pack)
57                    .await
58                    .with_context(|| format!("Failed to download updated rpack '{}'", pack.id))?;
59
60                // Update lockfile
61                lockfile_manager.upsert(
62                    &new_pack.id,
63                    &new_pack.version,
64                    &new_pack.sha256,
65                    &new_pack.git_url,
66                )?;
67
68                println!("✅ Updated '{}' to version {}", pack.id, new_pack.version);
69                updated_count += 1;
70            }
71            Ok(None) => {
72                println!("'{}' is up to date", pack.id);
73            }
74            Err(e) => {
75                println!("Warning: Failed to check updates for '{}': {}", pack.id, e);
76            }
77        }
78    }
79
80    if updated_count > 0 {
81        println!("\nUpdated {} rpack(s)", updated_count);
82    } else {
83        println!("\nAll rpacks are up to date");
84    }
85
86    Ok(())
87}