apicurio_cli/commands/
remove.rs

1use crate::{config::load_repo_config, constants::APICURIO_CONFIG, identifier::Identifier};
2use anyhow::{anyhow, Result};
3use dialoguer::Select;
4use std::{fs, path::PathBuf};
5
6pub async fn run(identifier_str: String) -> Result<()> {
7    let repo_path = PathBuf::from(APICURIO_CONFIG);
8    let mut repo = load_repo_config(&repo_path)?;
9
10    if repo.dependencies.is_empty() {
11        println!("No dependencies to remove.");
12        return Ok(());
13    }
14
15    // Parse the identifier
16    let identifier = Identifier::parse(&identifier_str);
17
18    // Find matching dependencies
19    let matches = identifier.find_matches(&repo.dependencies);
20
21    if matches.is_empty() {
22        println!("No dependencies found matching identifier: '{identifier_str}'");
23        println!("Available dependencies:");
24        for dep in &repo.dependencies {
25            println!(
26                "  - {} ({}@{})",
27                dep.name,
28                dep.resolved_artifact_id(),
29                dep.version
30            );
31        }
32        return Ok(());
33    }
34
35    let dependency_name = if matches.len() == 1 {
36        // Exact match or single fuzzy match
37        matches[0].name.clone()
38    } else {
39        // Multiple matches, let user choose
40        println!("Multiple dependencies match the identifier:");
41        let items: Vec<String> = matches
42            .iter()
43            .map(|dep| {
44                format!(
45                    "{} ({}@{} from {})",
46                    dep.name,
47                    dep.resolved_artifact_id(),
48                    dep.version,
49                    dep.registry
50                )
51            })
52            .collect();
53
54        let selection = Select::new()
55            .with_prompt("Select dependency to remove")
56            .items(&items)
57            .default(0)
58            .interact()?;
59
60        matches[selection].name.clone()
61    };
62
63    // Remove the dependency
64    let before_count = repo.dependencies.len();
65    repo.dependencies.retain(|d| d.name != dependency_name);
66
67    if repo.dependencies.len() < before_count {
68        let serialized = serde_yaml::to_string(&repo)?;
69        fs::write(repo_path, serialized)?;
70        println!("✅ Removed dependency: {dependency_name}");
71    } else {
72        return Err(anyhow!("Failed to remove dependency: {}", dependency_name));
73    }
74
75    Ok(())
76}