summaryrefslogblamecommitdiff
path: root/src/main.rs
blob: 1b8f041612741799db4c5857915f660fc0e79d98 (plain) (tree)
1
2
3
4
5
6
7
8
                               





                 
               







                                                                                                                    
                
 




                                  
 


                           









                              
                              
 
                                      

                               




                              
 






                                                  
 


                                                                   




                              
 


                                          
 






                                                  



                                                                   










                                           
                             
      
         






                                 
 













                                                                   
                             






                                                                   

                             















                                         
                   



                                       
                   













                                          
      
 


                 
                           
 
                                                      
 
                       
                                                                       


                             
                                                                  




                          
                 
              

                                                  
                                                                   
                                    
                                                                     

                    
                                          
                                                               
                                                                     
                  
                                        
             
 
                                                                     
         





                            

                                                  
                                                                   
                                    
                                                                     

                    
                                          
                                                               
                                                                     
                  
                                        
             
 

                                                             


                                                





                                          
              
 
                                                     
         
                                                           
                                 

              
 


























































                                                                   
                                                              

















                                                          
                                                          
         


                                                                  




                               
                                                                          

     
use clap::{Parser, Subcommand};

pub mod apis;
pub mod cache;
pub mod commands;
pub mod config;
pub mod db;
pub mod errors;
pub mod files;
pub mod data;

use commands::{download::download, io::{export, import}, list, modification::{mod_add, mod_remove}, update::update};
use config::Cfg;
use data::{gameversion::VersionLevel, list::List, modification::{AddMod, IDSelector}, modloader::Modloader};
pub use data::{STYLE_BAR_POS, STYLE_MESSAGE, STYLE_SPINNER, STYLE_BAR_BYTE, STYLE_OPERATION, PROGRESS_CHARS};
use db::{config_get_current_list, lists_get, lists_get_all_ids};
use errors::MLE;

#[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 } => handle_mod(config, command).await,
        Commands::List {
            command,
            force_gameupdate,
        } => handle_list(config, command, force_gameupdate).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 => List::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 => List::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();
}

async fn handle_mod(config: Cfg, command: ModCommands) -> MLE<()> {
    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 = if version {
                IDSelector::VersionID(id)
            } else {
                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)
        }
    }
}

async fn handle_list(
    config: Cfg,
    command: ListCommands,
    force_gameupdate: bool,
) -> MLE<()> {
    match command {
        ListCommands::Add {
            id,
            directory,
            modloader,
            version,
        } => {
            let ml = match modloader {
                Some(ml) => Modloader::try_from(ml.as_str())?,
                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,
    }
}