mirror of
				https://github.com/WarrenHood/MCModpackManager.git
				synced 2025-11-04 08:18:40 +00:00 
			
		
		
		
	Add initial WIP modpack lock file
This commit is contained in:
		
							parent
							
								
									b360901285
								
							
						
					
					
						commit
						3a91def282
					
				
							
								
								
									
										1175
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1175
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -5,5 +5,8 @@ edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
clap = { version = "4.5.15", features = ["derive"] }
 | 
					clap = { version = "4.5.15", features = ["derive"] }
 | 
				
			||||||
 | 
					ferinth = "2.11.0"
 | 
				
			||||||
 | 
					lhash = { version = "1.1.0", features = ["sha1", "sha512"] }
 | 
				
			||||||
serde = { version = "1.0.207", features = ["derive"] }
 | 
					serde = { version = "1.0.207", features = ["derive"] }
 | 
				
			||||||
 | 
					tokio = "1.39.2"
 | 
				
			||||||
toml = "0.8.19"
 | 
					toml = "0.8.19"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -1,7 +1,10 @@
 | 
				
			||||||
mod modpack;
 | 
					mod modpack;
 | 
				
			||||||
 | 
					mod mod_meta;
 | 
				
			||||||
 | 
					mod resolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use clap::{Parser, Subcommand};
 | 
					use clap::{Parser, Subcommand};
 | 
				
			||||||
use modpack::{ModLoader, ModMeta, ModProvider, ModpackMeta};
 | 
					use mod_meta::{ModMeta, ModProvider};
 | 
				
			||||||
 | 
					use modpack::ModpackMeta;
 | 
				
			||||||
use std::{error::Error, path::PathBuf};
 | 
					use std::{error::Error, path::PathBuf};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A Minecraft Modpack Manager
 | 
					/// A Minecraft Modpack Manager
 | 
				
			||||||
| 
						 | 
					@ -128,8 +131,12 @@ fn main() -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
                for provider in providers.into_iter() {
 | 
					                for provider in providers.into_iter() {
 | 
				
			||||||
                    mod_meta = mod_meta.provider(provider);
 | 
					                    mod_meta = mod_meta.provider(provider);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                modpack_meta = modpack_meta.add_mod(mod_meta);
 | 
					                modpack_meta = modpack_meta.add_mod(&mod_meta);
 | 
				
			||||||
                modpack_meta.save_current_dir_project()?;
 | 
					                modpack_meta.save_current_dir_project()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let mut modpack_lock = resolver::PinnedPackMeta::load_from_current_directory()?;
 | 
				
			||||||
 | 
					                modpack_lock.pin_mod(&mod_meta);
 | 
				
			||||||
 | 
					                modpack_lock.save_current_dir_lock()?;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										86
									
								
								src/mod_meta.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/mod_meta.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,86 @@
 | 
				
			||||||
 | 
					use std::{borrow::BorrowMut, error::Error};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
 | 
				
			||||||
 | 
					pub enum ModProvider {
 | 
				
			||||||
 | 
					    /// Get mods from CurseForge
 | 
				
			||||||
 | 
					    CurseForge,
 | 
				
			||||||
 | 
					    /// Get mods from Modrinth
 | 
				
			||||||
 | 
					    Modrinth,
 | 
				
			||||||
 | 
					    /// Get mods from anywhere on the internet. Note: A download url is needed for this
 | 
				
			||||||
 | 
					    Raw,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl std::str::FromStr for ModProvider {
 | 
				
			||||||
 | 
					    type Err = String;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
				
			||||||
 | 
					        match s.to_lowercase().as_str() {
 | 
				
			||||||
 | 
					            "curseforge" => Ok(ModProvider::CurseForge),
 | 
				
			||||||
 | 
					            "modrinth" => Ok(ModProvider::Modrinth),
 | 
				
			||||||
 | 
					            "raw" => Ok(ModProvider::Raw),
 | 
				
			||||||
 | 
					            _ => Err(format!("Invalid mod launcher: {}", s)),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 | 
				
			||||||
 | 
					pub struct ModMeta {
 | 
				
			||||||
 | 
					    pub name: String,
 | 
				
			||||||
 | 
					    pub version: String,
 | 
				
			||||||
 | 
					    providers: Option<Vec<ModProvider>>,
 | 
				
			||||||
 | 
					    download_url: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ModMeta {
 | 
				
			||||||
 | 
					    pub fn new(mod_name: &str) -> Result<Self, Box<dyn Error>> {
 | 
				
			||||||
 | 
					        if mod_name.contains("@") {
 | 
				
			||||||
 | 
					            let mod_name_and_version: Vec<&str> = mod_name.split("@").collect();
 | 
				
			||||||
 | 
					            if mod_name_and_version.len() != 2 {
 | 
				
			||||||
 | 
					                return Err(format!("Invalid mod with version constraint: '{}'", &mod_name).into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return Ok(Self {
 | 
				
			||||||
 | 
					                name: mod_name_and_version[0].into(),
 | 
				
			||||||
 | 
					                version: mod_name_and_version[1].into(),
 | 
				
			||||||
 | 
					                ..Default::default()
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Ok(Self {
 | 
				
			||||||
 | 
					            name: mod_name.into(),
 | 
				
			||||||
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn provider(mut self, provider: ModProvider) -> Self {
 | 
				
			||||||
 | 
					        if let Some(providers) = self.providers.borrow_mut() {
 | 
				
			||||||
 | 
					            if !providers.contains(&provider) {
 | 
				
			||||||
 | 
					                providers.push(provider)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.providers = Some(vec![provider]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn url(mut self, download_url: &str) -> Self {
 | 
				
			||||||
 | 
					        self.download_url = Some(download_url.into());
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn version(mut self, version_constraint: &str) -> Self {
 | 
				
			||||||
 | 
					        self.version = version_constraint.into();
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Default for ModMeta {
 | 
				
			||||||
 | 
					    fn default() -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            name: Default::default(),
 | 
				
			||||||
 | 
					            version: "*".into(),
 | 
				
			||||||
 | 
					            providers: None,
 | 
				
			||||||
 | 
					            download_url: Default::default(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,92 +1,12 @@
 | 
				
			||||||
use std::{borrow::BorrowMut, collections::HashMap, error::Error, path::PathBuf};
 | 
					use std::{collections::HashMap, error::Error, path::PathBuf};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ferinth::Ferinth;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::mod_meta::{ModMeta, ModProvider};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MODPACK_FILENAME: &str = "modpack.toml";
 | 
					const MODPACK_FILENAME: &str = "modpack.toml";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
 | 
					 | 
				
			||||||
pub enum ModProvider {
 | 
					 | 
				
			||||||
    /// Get mods from CurseForge
 | 
					 | 
				
			||||||
    CurseForge,
 | 
					 | 
				
			||||||
    /// Get mods from Modrinth
 | 
					 | 
				
			||||||
    Modrinth,
 | 
					 | 
				
			||||||
    /// Get mods from anywhere on the internet. Note: A download url is needed for this
 | 
					 | 
				
			||||||
    Raw,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl std::str::FromStr for ModProvider {
 | 
					 | 
				
			||||||
    type Err = String;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
					 | 
				
			||||||
        match s.to_lowercase().as_str() {
 | 
					 | 
				
			||||||
            "curseforge" => Ok(ModProvider::CurseForge),
 | 
					 | 
				
			||||||
            "modrinth" => Ok(ModProvider::Modrinth),
 | 
					 | 
				
			||||||
            "raw" => Ok(ModProvider::Raw),
 | 
					 | 
				
			||||||
            _ => Err(format!("Invalid mod launcher: {}", s)),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
 | 
					 | 
				
			||||||
pub struct ModMeta {
 | 
					 | 
				
			||||||
    name: String,
 | 
					 | 
				
			||||||
    version: String,
 | 
					 | 
				
			||||||
    providers: Option<Vec<ModProvider>>,
 | 
					 | 
				
			||||||
    download_url: Option<String>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl ModMeta {
 | 
					 | 
				
			||||||
    pub fn new(mod_name: &str) -> Result<Self, Box<dyn Error>> {
 | 
					 | 
				
			||||||
        if mod_name.contains("@") {
 | 
					 | 
				
			||||||
            let mod_name_and_version: Vec<&str> = mod_name.split("@").collect();
 | 
					 | 
				
			||||||
            if mod_name_and_version.len() != 2 {
 | 
					 | 
				
			||||||
                return Err(format!("Invalid mod with version constraint: '{}'", &mod_name).into());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return Ok(Self {
 | 
					 | 
				
			||||||
                name: mod_name_and_version[0].into(),
 | 
					 | 
				
			||||||
                version: mod_name_and_version[1].into(),
 | 
					 | 
				
			||||||
                ..Default::default()
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(Self {
 | 
					 | 
				
			||||||
            name: mod_name.into(),
 | 
					 | 
				
			||||||
            ..Default::default()
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn provider(mut self, provider: ModProvider) -> Self {
 | 
					 | 
				
			||||||
        if let Some(providers) = self.providers.borrow_mut() {
 | 
					 | 
				
			||||||
            if !providers.contains(&provider) {
 | 
					 | 
				
			||||||
                providers.push(provider)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            self.providers = Some(vec![provider]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn url(mut self, download_url: &str) -> Self {
 | 
					 | 
				
			||||||
        self.download_url = Some(download_url.into());
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn version(mut self, version_constraint: &str) -> Self {
 | 
					 | 
				
			||||||
        self.version = version_constraint.into();
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for ModMeta {
 | 
					 | 
				
			||||||
    fn default() -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            name: Default::default(),
 | 
					 | 
				
			||||||
            version: "*".into(),
 | 
					 | 
				
			||||||
            providers: None,
 | 
					 | 
				
			||||||
            download_url: Default::default(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
					#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
				
			||||||
pub enum ModLoader {
 | 
					pub enum ModLoader {
 | 
				
			||||||
    Forge,
 | 
					    Forge,
 | 
				
			||||||
| 
						 | 
					@ -134,6 +54,10 @@ impl ModpackMeta {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn iter_mods(&self) -> std::collections::hash_map::Values<String, ModMeta>  {
 | 
				
			||||||
 | 
					        self.mods.values().into_iter()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn load_from_directory(directory: &PathBuf) -> Result<Self, Box<dyn Error>> {
 | 
					    pub fn load_from_directory(directory: &PathBuf) -> Result<Self, 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() {
 | 
				
			||||||
| 
						 | 
					@ -158,7 +82,7 @@ impl ModpackMeta {
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn add_mod(mut self, mod_meta: ModMeta) -> Self {
 | 
					    pub fn add_mod(mut self, mod_meta: &ModMeta) -> Self {
 | 
				
			||||||
        if let Some(old_mod_meta) = self.mods.get(&mod_meta.name) {
 | 
					        if let Some(old_mod_meta) = self.mods.get(&mod_meta.name) {
 | 
				
			||||||
            println!("Updating {} version {}->{}", mod_meta.name, old_mod_meta.version, mod_meta.version);
 | 
					            println!("Updating {} version {}->{}", mod_meta.name, old_mod_meta.version, mod_meta.version);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -168,7 +92,7 @@ impl ModpackMeta {
 | 
				
			||||||
                mod_meta.name, mod_meta.version, self.pack_name
 | 
					                mod_meta.name, mod_meta.version, self.pack_name
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.mods.insert(mod_meta.name.to_string(), mod_meta);
 | 
					        self.mods.insert(mod_meta.name.to_string(), mod_meta.clone());
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										98
									
								
								src/resolver.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/resolver.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					use std::{collections::HashMap, error::Error, path::PathBuf};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{mod_meta::ModMeta, modpack::ModpackMeta};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MODPACK_LOCK_FILENAME: &str = "modpack.lock";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize, Deserialize)]
 | 
				
			||||||
 | 
					enum FileSource {
 | 
				
			||||||
 | 
					    Download { url: String },
 | 
				
			||||||
 | 
					    Local { path: PathBuf },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize, Deserialize)]
 | 
				
			||||||
 | 
					struct PinnedMod {
 | 
				
			||||||
 | 
					    /// Source of the file
 | 
				
			||||||
 | 
					    source: FileSource,
 | 
				
			||||||
 | 
					    /// SHA1 Hash
 | 
				
			||||||
 | 
					    sha1: String,
 | 
				
			||||||
 | 
					    /// SHA512 Hash
 | 
				
			||||||
 | 
					    sha512: String,
 | 
				
			||||||
 | 
					    /// Version of mod
 | 
				
			||||||
 | 
					    version: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PinnedMod {
 | 
				
			||||||
 | 
					    pub fn resolve_mod(mod_metadata: &ModMeta) -> Self {
 | 
				
			||||||
 | 
					        // TODO: Actually implement this
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            source: FileSource::Download {
 | 
				
			||||||
 | 
					                url: format!("https://fake.url/mods/{}", mod_metadata.name),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            sha1: "FakeSha1".into(),
 | 
				
			||||||
 | 
					            sha512: "FakeSha512".into(),
 | 
				
			||||||
 | 
					            version: if mod_metadata.version == "*" {
 | 
				
			||||||
 | 
					                "1.0.0-fake-latest-version".into()
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                mod_metadata.version.clone()
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize, Deserialize)]
 | 
				
			||||||
 | 
					pub struct PinnedPackMeta {
 | 
				
			||||||
 | 
					    mods: HashMap<String, PinnedMod>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PinnedPackMeta {
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            mods: Default::default(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn pin_mod(&mut self, mod_metadata: &ModMeta) -> &mut Self {
 | 
				
			||||||
 | 
					        let pinned_mod = PinnedMod::resolve_mod(mod_metadata);
 | 
				
			||||||
 | 
					        self.mods.insert(mod_metadata.name.clone(), pinned_mod);
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn init(&mut self, modpack_meta: &ModpackMeta) {
 | 
				
			||||||
 | 
					        modpack_meta.iter_mods().for_each(|m| {
 | 
				
			||||||
 | 
					            self.pin_mod(m);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn save_to_file(&self, path: &PathBuf) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
 | 
					        std::fs::write(
 | 
				
			||||||
 | 
					            path,
 | 
				
			||||||
 | 
					            toml::to_string(self).expect("Pinned pack meta should be serializable"),
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					        println!("Saved modpack.lock to {}", path.display());
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn save_current_dir_lock(&self) -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
 | 
					        let modpack_lock_file_path =
 | 
				
			||||||
 | 
					            std::env::current_dir()?.join(PathBuf::from(MODPACK_LOCK_FILENAME));
 | 
				
			||||||
 | 
					        self.save_to_file(&modpack_lock_file_path)?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn load_from_directory(directory: &PathBuf) -> Result<Self, Box<dyn Error>> {
 | 
				
			||||||
 | 
					        let modpack_lock_file_path = directory.clone().join(PathBuf::from(MODPACK_LOCK_FILENAME));
 | 
				
			||||||
 | 
					        if !modpack_lock_file_path.exists() {
 | 
				
			||||||
 | 
					            let mut new_modpack_lock = Self::new();
 | 
				
			||||||
 | 
					            new_modpack_lock.init(&ModpackMeta::load_from_directory(directory)?);
 | 
				
			||||||
 | 
					            return Ok(new_modpack_lock);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let modpack_lock_contents = std::fs::read_to_string(modpack_lock_file_path)?;
 | 
				
			||||||
 | 
					        Ok(toml::from_str(&modpack_lock_contents)?)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn load_from_current_directory() -> Result<Self, Box<dyn Error>> {
 | 
				
			||||||
 | 
					        Self::load_from_directory(&std::env::current_dir()?)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue