Skip to main content

conduit_cli/core/
remover.rs

1use crate::core::error::CoreResult;
2use crate::core::events::{CoreCallbacks, CoreEvent};
3use crate::core::io::project::{ConduitConfig, ConduitLock};
4use crate::core::paths::CorePaths;
5use std::collections::HashSet;
6use std::fs;
7
8pub struct RemoveReport {
9    pub removed_slug: String,
10    pub purged_slugs: Vec<String>,
11}
12
13pub fn remove_mod(
14    paths: &CorePaths,
15    slug: &str,
16    config: &mut ConduitConfig,
17    lock: &mut ConduitLock,
18    callbacks: &mut dyn CoreCallbacks,
19) -> CoreResult<Option<RemoveReport>> {
20    if !config.mods.contains_key(slug) {
21        return Ok(None);
22    }
23
24    config.mods.remove(slug);
25
26    let mut mods_to_keep = HashSet::new();
27    for root_slug in config.mods.keys() {
28        collect_dependencies(root_slug, lock, &mut mods_to_keep);
29    }
30
31    let mut purged = Vec::new();
32    let all_locked_slugs: Vec<String> = lock.locked_mods.keys().cloned().collect();
33    for locked_slug in all_locked_slugs {
34        if !mods_to_keep.contains(&locked_slug)
35            && let Some(mod_data) = lock.locked_mods.remove(&locked_slug) {
36                let dest_path = paths.mods_dir().join(&mod_data.filename);
37                if dest_path.exists() {
38                    fs::remove_file(dest_path)?;
39                }
40                purged.push(locked_slug.clone());
41                callbacks.on_event(CoreEvent::Purged { slug: locked_slug });
42            }
43    }
44
45    Ok(Some(RemoveReport {
46        removed_slug: slug.to_string(),
47        purged_slugs: purged,
48    }))
49}
50
51fn collect_dependencies(slug: &str, lock: &ConduitLock, kept: &mut HashSet<String>) {
52    if kept.contains(slug) {
53        return;
54    }
55    if let Some(mod_data) = lock.locked_mods.get(slug) {
56        kept.insert(slug.to_string());
57        for dep_id in &mod_data.dependencies {
58            if let Some((dep_slug, _)) = lock.locked_mods.iter().find(|(_, m)| &m.id == dep_id) {
59                collect_dependencies(dep_slug, lock, kept);
60            }
61        }
62    }
63}