use clap::{Parser, Subcommand};
use modlist::{config::Cfg, mod_add, mod_remove, db::{lists_get, config_get_current_list, lists_get_all_ids}, IDSelector, download, update, List, get_current_list, import, devdir, export, list_add, Modloader, list_version, list_remove, list_change};
//TODO make default list optional
#[derive(Parser)]
#[command(author, version, about)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
r#Mod {
#[command(subcommand)]
command: ModCommands,
},
List {
#[command(subcommand)]
command: ListCommands
},
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,
},
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,
},
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>
}
}
#[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("modlist.toml").unwrap();
println!("{:?}", config);
//TODO setup? maybe setup on install
match cli.command {
Commands::Mod { command } => {
match command {
#[allow(unused_variables)]
ModCommands::Add { id, version, list, download, lock } => {
let listf = match list {
Some(list) => lists_get(config.clone(), list).unwrap(),
None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(),
};
let marked_id = match version {
true => IDSelector::VersionID(id),
false => IDSelector::ModificationID(id),
};
mod_add(config, vec![marked_id], listf, download, lock).await
}
ModCommands::Remove { id, list } => {
//TODO add output
//TODO add success even if no file found
let listf = match list {
Some(list) => lists_get(config.clone(), list).unwrap(),
None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(),
};
mod_remove(config, &id, listf)
}
}
},
Commands::List { command } => {
match command {
ListCommands::Add { id, directory, modloader, version } => {
let ml = match modloader {
Some(ml) => Modloader::from(&ml).unwrap(),
//TODO add default modloader to config
None => Modloader::Fabric,
};
let ver = match version {
Some(ver) => ver,
//TODO get latest version
//TODO impl config for specific version or latest or latest snap
None => "1.19.4".to_string(),
};
list_add(config, id, ver, ml, directory)
},
ListCommands::Remove { id } => {
list_remove(config, id)
},
ListCommands::List => {
todo!()
},
ListCommands::Change { id } => {
list_change(config, id)
},
ListCommands::Version { id, version, download, remove } => {
list_version(config, id, version, download, remove).await
}
}
},
//TODO a add specific list
Commands::Update { all, download, clean, remove } => {
let mut liststack: Vec<List> = vec![];
if all {
let list_ids = lists_get_all_ids(config.clone()).unwrap();
for id in list_ids {
liststack.push(lists_get(config.clone(), id).unwrap());
}
} else {
let current = get_current_list(config.clone()).unwrap();
println!("Update list {}:", current.id);
liststack.push(current)
}
update(config, liststack, clean, download, remove).await
},
//TODO add specific list
Commands::Download { all, clean, remove } => {
download(config, all, clean, remove).await
},
Commands::Import { file, download } => {
let filestr: String = match file {
Some(args) => args,
None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()),
};
import(config, filestr, download).await
},
Commands::Export { list } => {
export(config, list)
},
}.unwrap();
}