mirror of
				https://github.com/WarrenHood/MCModpackManager.git
				synced 2025-11-04 07:58:40 +00:00 
			
		
		
		
	Added a remove command
This commit is contained in:
		
							parent
							
								
									72407055ca
								
							
						
					
					
						commit
						6a18ac39bb
					
				
							
								
								
									
										40
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -60,6 +60,11 @@ enum Commands {
 | 
				
			||||||
        #[arg(long)]
 | 
					        #[arg(long)]
 | 
				
			||||||
        url: Option<String>,
 | 
					        url: Option<String>,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    /// Remove a mod from the modpack
 | 
				
			||||||
 | 
					    Remove {
 | 
				
			||||||
 | 
					        /// Name of the mod to remove from the modpack
 | 
				
			||||||
 | 
					        name: String,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[tokio::main(flavor = "multi_thread")]
 | 
					#[tokio::main(flavor = "multi_thread")]
 | 
				
			||||||
| 
						 | 
					@ -152,7 +157,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                match resolver::PinnedPackMeta::load_from_current_directory().await {
 | 
					                match resolver::PinnedPackMeta::load_from_current_directory().await {
 | 
				
			||||||
                    Ok(mut modpack_lock) => {
 | 
					                    Ok(mut modpack_lock) => {
 | 
				
			||||||
                        let pin_result = modpack_lock.pin_mod_and_deps(&mod_meta, &modpack_meta).await;
 | 
					                        let pin_result = modpack_lock
 | 
				
			||||||
 | 
					                            .pin_mod_and_deps(&mod_meta, &modpack_meta)
 | 
				
			||||||
 | 
					                            .await;
 | 
				
			||||||
                        if let Err(e) = pin_result {
 | 
					                        if let Err(e) = pin_result {
 | 
				
			||||||
                            revert_modpack_meta(e);
 | 
					                            revert_modpack_meta(e);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
| 
						 | 
					@ -166,6 +173,37 @@ async fn main() -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            Commands::Remove { name } => {
 | 
				
			||||||
 | 
					                let mut modpack_meta = ModpackMeta::load_from_current_directory()?;
 | 
				
			||||||
 | 
					                let old_modpack_meta = modpack_meta.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                modpack_meta = modpack_meta.remove_mod(&name);
 | 
				
			||||||
 | 
					                modpack_meta.save_current_dir_project()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let revert_modpack_meta = |e| -> ! {
 | 
				
			||||||
 | 
					                    let revert_result = old_modpack_meta.save_current_dir_project();
 | 
				
			||||||
 | 
					                    if let Err(result) = revert_result {
 | 
				
			||||||
 | 
					                        panic!("Failed to revert modpack meta: {}", result);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    panic!("Reverted modpack meta:\n{}", e);
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                match resolver::PinnedPackMeta::load_from_current_directory().await {
 | 
				
			||||||
 | 
					                    Ok(mut modpack_lock) => {
 | 
				
			||||||
 | 
					                        let remove_result = modpack_lock.remove_mod(&name, &modpack_meta);
 | 
				
			||||||
 | 
					                        if let Err(e) = remove_result {
 | 
				
			||||||
 | 
					                            revert_modpack_meta(e);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if let Err(e) = modpack_lock.save_current_dir_lock() {
 | 
				
			||||||
 | 
					                            revert_modpack_meta(e);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Err(e) => {
 | 
				
			||||||
 | 
					                        revert_modpack_meta(e);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ pub struct ModpackMeta {
 | 
				
			||||||
    pack_name: String,
 | 
					    pack_name: String,
 | 
				
			||||||
    pub mc_version: String,
 | 
					    pub mc_version: String,
 | 
				
			||||||
    pub modloader: ModLoader,
 | 
					    pub modloader: ModLoader,
 | 
				
			||||||
    mods: HashMap<String, ModMeta>,
 | 
					    pub mods: HashMap<String, ModMeta>,
 | 
				
			||||||
    pub default_providers: Vec<ModProvider>,
 | 
					    pub default_providers: Vec<ModProvider>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,11 @@ impl ModpackMeta {
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn remove_mod(mut self, mod_name: &str) -> Self {
 | 
				
			||||||
 | 
					        self.mods.remove(mod_name);
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn init_project(&self, directory: &PathBuf) -> Result<(), Box<dyn Error>> {
 | 
					    pub fn init_project(&self, directory: &PathBuf) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
        let modpack_meta_file_path = directory.clone().join(PathBuf::from(MODPACK_FILENAME));
 | 
					        let modpack_meta_file_path = directory.clone().join(PathBuf::from(MODPACK_FILENAME));
 | 
				
			||||||
        if modpack_meta_file_path.exists() {
 | 
					        if modpack_meta_file_path.exists() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,6 +124,65 @@ impl PinnedPackMeta {
 | 
				
			||||||
        .into())
 | 
					        .into())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_dependent_mods(&self, mod_name: &str) -> HashSet<String> {
 | 
				
			||||||
 | 
					        let mut dependent_mods = HashSet::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (pinned_mod_name, pinned_mod) in self.mods.iter() {
 | 
				
			||||||
 | 
					            if let Some(deps) = &pinned_mod.deps {
 | 
				
			||||||
 | 
					                for dep in deps.iter() {
 | 
				
			||||||
 | 
					                    if dep.name == mod_name {
 | 
				
			||||||
 | 
					                        dependent_mods.insert(pinned_mod_name.clone());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        dependent_mods
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn remove_mod(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        mod_name: &str,
 | 
				
			||||||
 | 
					        pack_metadata: &ModpackMeta,
 | 
				
			||||||
 | 
					    ) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
 | 
					        let dependent_mods = self.get_dependent_mods(mod_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if dependent_mods.len() > 0 {
 | 
				
			||||||
 | 
					            return Err(format!(
 | 
				
			||||||
 | 
					                "Cannot remove mod {}.The following mods depend on it:\n{:#?}",
 | 
				
			||||||
 | 
					                mod_name, dependent_mods
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .into());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let removed_mod = self.mods.remove(mod_name);
 | 
				
			||||||
 | 
					        if let Some(removed_mod) = removed_mod {
 | 
				
			||||||
 | 
					            println!("Removed mod {}@{}", mod_name, removed_mod.version);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.prune_mods(pack_metadata)?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Remove all mods from lockfile that aren't in the pack metadata or depended on by another mod
 | 
				
			||||||
 | 
					    fn prune_mods(&mut self, pack_metadata: &ModpackMeta) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
 | 
					        let mods_to_remove: HashSet<String> = self
 | 
				
			||||||
 | 
					            .mods
 | 
				
			||||||
 | 
					            .keys()
 | 
				
			||||||
 | 
					            .filter(|mod_name| {
 | 
				
			||||||
 | 
					                !pack_metadata.mods.contains_key(*mod_name)
 | 
				
			||||||
 | 
					                    && self.get_dependent_mods(mod_name).len() == 0
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .map(|mod_name| mod_name.into())
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for mod_name in mods_to_remove {
 | 
				
			||||||
 | 
					            let removed_mod = self.mods.remove(&mod_name);
 | 
				
			||||||
 | 
					            if let Some(removed_mod) = removed_mod {
 | 
				
			||||||
 | 
					                println!("Pruned mod {}@{}", mod_name, removed_mod.version);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn init(&mut self, modpack_meta: &ModpackMeta) -> Result<(), Box<dyn Error>> {
 | 
					    pub async fn init(&mut self, modpack_meta: &ModpackMeta) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
        for mod_meta in modpack_meta.iter_mods() {
 | 
					        for mod_meta in modpack_meta.iter_mods() {
 | 
				
			||||||
            self.pin_mod_and_deps(mod_meta, modpack_meta).await?;
 | 
					            self.pin_mod_and_deps(mod_meta, modpack_meta).await?;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue