use clap::{Parser, Subcommand};
use modlist::{
config::Cfg,
db::{config_get_current_list, lists_get, lists_get_all_ids},
download, export, get_current_list, import, list_add, list_change, list_list, list_remove,
list_version, mod_add, mod_remove, update, AddMod, IDSelector, List, Modloader, VersionLevel,
};
#[derive(Parser)]
#[command(author, version, about)]
struct Cli {
#[command(subcommand)]
command: Commands,
/// config file path
#[arg(short, long)]
config: Option<String>,
}
#[derive(Subcommand)]
enum Commands {
r#Mod {
#[command(subcommand)]
command: ModCommands,
},
List {
#[command(subcommand)]
command: ListCommands,
/// Force GameVersion update
#[arg(long)]
force_gameupdate: bool,
},
Download {
/// download all lists
#[arg(short, long)]
all: bool,
/// clean all mods before downloading them
#[arg(short, long)]
clean: bool,
/// remove disabled versions
#[arg(short, long)]
remove: bool,
/// optional List selection, else default list will be used
#[arg(short, long)]
list: Option<String>,
},
Update {
/// download all lists
#[arg(short, long)]
all: bool,
/// directly download updated mods
#[arg(short, long)]
download: bool,
/// clean all mods before downloading them
#[arg(short, long)]
clean: bool,
/// delete disabled versions
#[arg(short, long)]
remove: bool,
/// optional List selection, else default list will be used
#[arg(short, long)]
list: Option<String>,
},
Import {
#[arg(short, long)]
file: Option<String>,
/// directly download imported mods
#[arg(short, long)]
download: bool,
},
Export {
/// the list you want to export
list: Option<String>,
},
Test,
}
#[derive(Subcommand)]
enum ModCommands {
Add {
/// id of the mod/version
id: String,
/// set id mode to version
#[arg(short, long)]
version: bool,
/// directly download the mod
#[arg(short, long)]
download: bool,
/// lock the version added
#[arg(/* short , */long)]
lock: bool,
/// optional List selection, else default list will be used
#[arg(short, long)]
list: Option<String>,
},
Remove {
/// id, name or title of the mod
id: String,
/// optional List selection, else default list will be used
#[arg(short, long)]
list: Option<String>,
},
}
#[derive(Subcommand)]
enum ListCommands {
Add {
/// list id
id: String,
directory: String,
modloader: Option<String>,
version: Option<String>,
},
Remove {
/// id, name or title of the list
id: String,
},
List,
Change {
/// id of the list to change to
id: String,
},
Version {
/// list id
id: String,
/// desired minecraft version
version: String,
/// directly download updated mods
#[arg(long, short)]
download: bool,
/// delete disabled versions
#[arg(short, long)]
remove: bool,
},
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
let config = Cfg::init(cli.config).await.unwrap();
match cli.command {
Commands::Mod { command } => match command {
ModCommands::Add {
id,
version,
list,
download,
lock,
} => {
let listf = match list {
Some(list) => lists_get(&config, &list).unwrap(),
None => lists_get(&config, &config_get_current_list(&config).unwrap()).unwrap(),
};
let marked_id = match version {
true => IDSelector::VersionID(id),
false => IDSelector::ModificationID(id),
};
let add_id = AddMod {
id: marked_id,
set_version: lock,
};
mod_add(&config, vec![add_id], listf, download).await
}
ModCommands::Remove { id, list } => {
let listf = match list {
Some(list) => lists_get(&config, &list).unwrap(),
None => lists_get(&config, &config_get_current_list(&config).unwrap()).unwrap(),
};
mod_remove(&config, &id, &listf)
}
},
Commands::List {
command,
force_gameupdate,
} => match command {
ListCommands::Add {
id,
directory,
modloader,
version,
} => {
let ml = match modloader {
Some(ml) => Modloader::from(&ml).unwrap(),
None => config.defaults.modloader.clone(),
};
let versions_path = &config.versions;
let ver = match version {
Some(ver) => VersionLevel::from(&ver)
.get(versions_path, force_gameupdate)
.await
.unwrap(),
None => config
.defaults
.version
.clone()
.get(versions_path, force_gameupdate)
.await
.unwrap(),
};
list_add(&config, &id, &ver, &ml, &directory)
}
ListCommands::Remove { id } => list_remove(&config, &id),
ListCommands::List => list_list(&config),
ListCommands::Change { id } => list_change(&config, &id),
ListCommands::Version {
id,
version,
download,
remove,
} => list_version(&config, &id, version, download, remove).await,
},
Commands::Update {
all,
download,
clean,
remove,
list,
} => {
let mut liststack: Vec<List> = vec![];
if all {
let list_ids = lists_get_all_ids(&config).unwrap();
for id in list_ids {
liststack.push(lists_get(&config, &id).unwrap());
}
} else {
let current = match list {
Some(l) => lists_get(&config, &l).unwrap(),
None => get_current_list(&config).unwrap(),
};
liststack.push(current)
}
update(&config, liststack, clean, download, remove).await
}
Commands::Download {
all,
clean,
remove,
list,
} => {
let mut liststack: Vec<List> = vec![];
if all {
let list_ids = lists_get_all_ids(&config).unwrap();
for id in list_ids {
liststack.push(lists_get(&config, &id).unwrap());
}
} else {
let current = match list {
Some(l) => lists_get(&config, &l).unwrap(),
None => get_current_list(&config).unwrap(),
};
liststack.push(current)
}
download(&config, liststack, clean, remove).await
}
Commands::Import { file, download } => {
let filestr: String = match file {
Some(args) => args,
None => dirs::home_dir()
.unwrap()
.join("mlexport.toml")
.into_os_string()
.into_string()
.unwrap(),
};
import(&config, &filestr, download).await
}
Commands::Export { list } => export(&config, list),
Commands::Test => Ok(()),
}
.unwrap();
}