Skip to main content

conduit_cli/core/
remover.rs

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