mirror of
https://github.com/WarrenHood/MCModpackManager.git
synced 2025-04-30 00:04:59 +01:00
Added an add
command
This commit is contained in:
parent
52efc9780d
commit
077fadabbf
28
src/main.rs
28
src/main.rs
|
@ -14,7 +14,7 @@ struct Cli {
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Initialises a new mcmpmgr project in the specified directory (or current dir if not specified)
|
/// Initialise a new mcmpmgr project in the specified directory (or current dir if not specified)
|
||||||
Init {
|
Init {
|
||||||
/// The root modpack project directory
|
/// The root modpack project directory
|
||||||
directory: Option<PathBuf>,
|
directory: Option<PathBuf>,
|
||||||
|
@ -28,7 +28,7 @@ enum Commands {
|
||||||
#[arg(long, default_value_t = modpack::ModLoader::Fabric)]
|
#[arg(long, default_value_t = modpack::ModLoader::Fabric)]
|
||||||
modloader: modpack::ModLoader,
|
modloader: modpack::ModLoader,
|
||||||
},
|
},
|
||||||
/// Creates and initialises a new mcmpmgr project in the current directory
|
/// Create and initialise a new mcmpmgr project in the current directory
|
||||||
New {
|
New {
|
||||||
/// Name of the new modpack project
|
/// Name of the new modpack project
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -39,6 +39,17 @@ enum Commands {
|
||||||
#[arg(long, default_value_t = modpack::ModLoader::Fabric)]
|
#[arg(long, default_value_t = modpack::ModLoader::Fabric)]
|
||||||
modloader: modpack::ModLoader,
|
modloader: modpack::ModLoader,
|
||||||
},
|
},
|
||||||
|
/// Add a new mod to the modpack
|
||||||
|
Add {
|
||||||
|
/// Name of the mod to add to the project, optionally including a version
|
||||||
|
name: String,
|
||||||
|
/// Providers to download the mods from
|
||||||
|
#[arg(long)]
|
||||||
|
providers: Vec<ModProvider>,
|
||||||
|
/// URL to download the mod from
|
||||||
|
#[arg(long)]
|
||||||
|
url: Option<String>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
@ -88,6 +99,19 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let mc_modpack_meta: ModpackMeta = ModpackMeta::new(&name, &mc_version, modloader);
|
let mc_modpack_meta: ModpackMeta = ModpackMeta::new(&name, &mc_version, modloader);
|
||||||
mc_modpack_meta.init_project(&dir)?;
|
mc_modpack_meta.init_project(&dir)?;
|
||||||
}
|
}
|
||||||
|
Commands::Add { name, providers, url } => {
|
||||||
|
let mut modpack_meta = ModpackMeta::load_from_current_directory()?;
|
||||||
|
|
||||||
|
let mut mod_meta = ModMeta::new(&name)?;
|
||||||
|
if let Some(url) = url {
|
||||||
|
mod_meta = mod_meta.url(&url);
|
||||||
|
}
|
||||||
|
for provider in providers.into_iter() {
|
||||||
|
mod_meta = mod_meta.provider(provider);
|
||||||
|
}
|
||||||
|
modpack_meta = modpack_meta.add_mod(mod_meta);
|
||||||
|
modpack_meta.save_current_dir_project()?;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@ use std::{borrow::BorrowMut, error::Error, path::PathBuf};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
const MODPACK_FILENAME: &str = "modpack.toml";
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
pub enum ModProvider {
|
pub enum ModProvider {
|
||||||
/// Get mods from CurseForge
|
/// Get mods from CurseForge
|
||||||
CurseForge,
|
CurseForge,
|
||||||
|
@ -12,6 +14,19 @@ pub enum ModProvider {
|
||||||
Raw,
|
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)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct ModMeta {
|
pub struct ModMeta {
|
||||||
mod_name: String,
|
mod_name: String,
|
||||||
|
@ -29,11 +44,22 @@ struct ModMetaBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModMeta {
|
impl ModMeta {
|
||||||
pub fn new(mod_name: &str) -> Self {
|
pub fn new(mod_name: &str) -> Result<Self, Box<dyn Error>> {
|
||||||
Self {
|
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 {
|
||||||
|
mod_name: mod_name_and_version[0].into(),
|
||||||
|
version: mod_name_and_version[1].into(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(Self {
|
||||||
mod_name: mod_name.into(),
|
mod_name: mod_name.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provider(mut self, provider: ModProvider) -> Self {
|
pub fn provider(mut self, provider: ModProvider) -> Self {
|
||||||
|
@ -116,6 +142,23 @@ impl ModpackMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_from_directory(directory: &PathBuf) -> Result<Self, Box<dyn Error>> {
|
||||||
|
let modpack_meta_file_path = directory.clone().join(PathBuf::from(MODPACK_FILENAME));
|
||||||
|
if !modpack_meta_file_path.exists() {
|
||||||
|
return Err(format!(
|
||||||
|
"Directory '{}' does not seem to be a valid modpack project directory.",
|
||||||
|
directory.display()
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
};
|
||||||
|
let modpack_contents = std::fs::read_to_string(modpack_meta_file_path)?;
|
||||||
|
Ok(toml::from_str(&modpack_contents)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_from_current_directory() -> Result<Self, Box<dyn Error>> {
|
||||||
|
Self::load_from_directory(&std::env::current_dir()?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn provider(mut self, provider: ModProvider) -> Self {
|
pub fn provider(mut self, provider: ModProvider) -> Self {
|
||||||
if !self.default_providers.contains(&provider) {
|
if !self.default_providers.contains(&provider) {
|
||||||
self.default_providers.push(provider);
|
self.default_providers.push(provider);
|
||||||
|
@ -125,13 +168,22 @@ impl ModpackMeta {
|
||||||
|
|
||||||
pub fn add_mod(mut self, mod_meta: ModMeta) -> Self {
|
pub fn add_mod(mut self, mod_meta: ModMeta) -> Self {
|
||||||
if !self.mods.contains(&mod_meta) {
|
if !self.mods.contains(&mod_meta) {
|
||||||
|
self.mods = self
|
||||||
|
.mods
|
||||||
|
.into_iter()
|
||||||
|
.filter(|m| m.mod_name != mod_meta.mod_name)
|
||||||
|
.collect();
|
||||||
|
println!(
|
||||||
|
"Adding {}@{} to modpack '{}'...",
|
||||||
|
mod_meta.mod_name, mod_meta.version, self.pack_name
|
||||||
|
);
|
||||||
self.mods.push(mod_meta);
|
self.mods.push(mod_meta);
|
||||||
}
|
}
|
||||||
self
|
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("mcmodpack.toml"));
|
let modpack_meta_file_path = directory.clone().join(PathBuf::from(MODPACK_FILENAME));
|
||||||
if modpack_meta_file_path.exists() {
|
if modpack_meta_file_path.exists() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"mcmodpack.toml already exists at {}",
|
"mcmodpack.toml already exists at {}",
|
||||||
|
@ -140,15 +192,25 @@ impl ModpackMeta {
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fs::write(
|
self.save_to_file(&modpack_meta_file_path)?;
|
||||||
modpack_meta_file_path,
|
|
||||||
toml::to_string(self)
|
|
||||||
.expect("MC Modpack Meta should be serializable"),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
println!("MC modpack project initialized at {}", directory.display());
|
println!("MC modpack project initialized at {}", directory.display());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_to_file(&self, path: &PathBuf) -> Result<(), Box<dyn Error>> {
|
||||||
|
std::fs::write(
|
||||||
|
path,
|
||||||
|
toml::to_string(self).expect("MC Modpack Meta should be serializable"),
|
||||||
|
)?;
|
||||||
|
println!("Saved modpack metadata to {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_current_dir_project(&self) -> Result<(), Box<dyn Error>> {
|
||||||
|
let modpack_meta_file_path = std::env::current_dir()?.join(PathBuf::from(MODPACK_FILENAME));
|
||||||
|
self.save_to_file(&modpack_meta_file_path)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for ModpackMeta {
|
impl std::default::Default for ModpackMeta {
|
||||||
|
|
Loading…
Reference in a new issue