mirror of
https://github.com/WarrenHood/MCModpackManager.git
synced 2025-04-30 00:04:59 +01:00
Added a remove command
This commit is contained in:
parent
72407055ca
commit
6a18ac39bb
42
src/main.rs
42
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")]
|
||||||
|
@ -120,7 +125,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
mc_modpack_meta = mc_modpack_meta.provider(provider);
|
mc_modpack_meta = mc_modpack_meta.provider(provider);
|
||||||
}
|
}
|
||||||
mc_modpack_meta.init_project(&dir)?;
|
mc_modpack_meta.init_project(&dir)?;
|
||||||
|
|
||||||
let modpack_lock = resolver::PinnedPackMeta::load_from_directory(&dir).await?;
|
let modpack_lock = resolver::PinnedPackMeta::load_from_directory(&dir).await?;
|
||||||
modpack_lock.save_to_dir(&dir)?;
|
modpack_lock.save_to_dir(&dir)?;
|
||||||
}
|
}
|
||||||
|
@ -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