diff options
-rw-r--r-- | src/commands/download.rs | 12 | ||||
-rw-r--r-- | src/commands/io.rs | 29 | ||||
-rw-r--r-- | src/commands/list.rs | 53 | ||||
-rw-r--r-- | src/commands/modification.rs | 44 | ||||
-rw-r--r-- | src/commands/update.rs | 22 | ||||
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/db.rs | 10 | ||||
-rw-r--r-- | src/lib.rs | 20 | ||||
-rw-r--r-- | src/main.rs | 278 |
9 files changed, 289 insertions, 181 deletions
diff --git a/src/commands/download.rs b/src/commands/download.rs index 2714630..4baecee 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use crate::{files::{get_downloaded_versions, download_versions, delete_version, disable_version, clean_list_dir}, db::{userlist_get_all_current_versions_with_mods, lists_get_all_ids, lists_get}, modrinth::get_raw_versions, error::{MLE, ErrorType, MLError}}; | 1 | use crate::{files::{get_downloaded_versions, download_versions, delete_version, disable_version, clean_list_dir}, db::{userlist_get_all_current_versions_with_mods, lists_get_all_ids, lists_get}, modrinth::get_raw_versions, error::{MLE, ErrorType, MLError}}; |
2 | use crate::{List, get_current_list, config::Cfg, input::Input}; | 2 | use crate::{List, get_current_list, config::Cfg}; |
3 | 3 | ||
4 | pub async fn download(config: Cfg, input: Input) -> MLE<()> { | 4 | pub async fn download(config: Cfg, all_lists: bool, clean: bool, delete_old: bool) -> MLE<()> { |
5 | 5 | ||
6 | let mut liststack: Vec<List> = vec![]; | 6 | let mut liststack: Vec<List> = vec![]; |
7 | if input.all_lists { | 7 | if all_lists { |
8 | let list_ids = lists_get_all_ids(config.clone())?; | 8 | let list_ids = lists_get_all_ids(config.clone())?; |
9 | for id in list_ids { | 9 | for id in list_ids { |
10 | liststack.push(lists_get(config.clone(), id)?); | 10 | liststack.push(lists_get(config.clone(), id)?); |
@@ -33,7 +33,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> { | |||
33 | 33 | ||
34 | let current_download = downloaded_versions.get(&mod_id); | 34 | let current_download = downloaded_versions.get(&mod_id); |
35 | 35 | ||
36 | if current_download.is_none() || input.clean { | 36 | if current_download.is_none() || clean { |
37 | to_download.push(current_version); | 37 | to_download.push(current_version); |
38 | } else { | 38 | } else { |
39 | let downloaded_version = current_download.ok_or("SOMETHING_HAS_REALLY_GONE_WRONG").unwrap(); | 39 | let downloaded_version = current_download.ok_or("SOMETHING_HAS_REALLY_GONE_WRONG").unwrap(); |
@@ -44,7 +44,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> { | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | if input.clean { clean_list_dir(¤t_list)? }; | 47 | if clean { clean_list_dir(¤t_list)? }; |
48 | 48 | ||
49 | if !to_download.is_empty() { | 49 | if !to_download.is_empty() { |
50 | download_versions(current_list.clone(), config.clone(), get_raw_versions(&config.apis.modrinth, to_download).await).await?; | 50 | download_versions(current_list.clone(), config.clone(), get_raw_versions(&config.apis.modrinth, to_download).await).await?; |
@@ -54,7 +54,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> { | |||
54 | 54 | ||
55 | if !to_disable.is_empty() { | 55 | if !to_disable.is_empty() { |
56 | for ver in to_disable { | 56 | for ver in to_disable { |
57 | if input.delete_old { | 57 | if delete_old { |
58 | println!("Deleting version {} for mod {}", ver.1, ver.0); | 58 | println!("Deleting version {} for mod {}", ver.1, ver.0); |
59 | delete_version(current_list.clone(), ver.1)?; | 59 | delete_version(current_list.clone(), ver.1)?; |
60 | } else { | 60 | } else { |
diff --git a/src/commands/io.rs b/src/commands/io.rs index a3d056f..5de8dd1 100644 --- a/src/commands/io.rs +++ b/src/commands/io.rs | |||
@@ -2,7 +2,7 @@ use std::fs::File; | |||
2 | use std::io::prelude::*; | 2 | use std::io::prelude::*; |
3 | use serde::{Serialize, Deserialize}; | 3 | use serde::{Serialize, Deserialize}; |
4 | 4 | ||
5 | use crate::{input::{Input, IoOptions}, db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mods_add, IDSelector}; | 5 | use crate::{db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mod_add, IDSelector}; |
6 | 6 | ||
7 | #[derive(Debug, Serialize, Deserialize)] | 7 | #[derive(Debug, Serialize, Deserialize)] |
8 | struct Export { | 8 | struct Export { |
@@ -32,22 +32,12 @@ impl ExportList { | |||
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | pub async fn io(config: Cfg, input: Input) -> MLE<()> { | 35 | pub fn export(config: Cfg, list: Option<String>) -> MLE<()> { |
36 | |||
37 | match input.clone().io_options.unwrap() { | ||
38 | IoOptions::Export => { export(config, input)? }, | ||
39 | IoOptions::Import => { import(config, input).await? }, | ||
40 | } | ||
41 | |||
42 | Ok(()) | ||
43 | } | ||
44 | |||
45 | fn export(config: Cfg, input: Input) -> MLE<()> { | ||
46 | let mut list_ids: Vec<String> = vec![]; | 36 | let mut list_ids: Vec<String> = vec![]; |
47 | if input.all_lists { | 37 | if list.is_none() { |
48 | list_ids = lists_get_all_ids(config.clone())?; | 38 | list_ids = lists_get_all_ids(config.clone())?; |
49 | } else { | 39 | } else { |
50 | list_ids.push(lists_get(config.clone(), input.list.unwrap().id)?.id); | 40 | list_ids.push(lists_get(config.clone(), list.unwrap())?.id); |
51 | } | 41 | } |
52 | let mut lists: Vec<ExportList> = vec![]; | 42 | let mut lists: Vec<ExportList> = vec![]; |
53 | for list_id in list_ids { | 43 | for list_id in list_ids { |
@@ -64,14 +54,9 @@ fn export(config: Cfg, input: Input) -> MLE<()> { | |||
64 | Ok(()) | 54 | Ok(()) |
65 | } | 55 | } |
66 | 56 | ||
67 | async fn import(config: Cfg, input: Input) -> MLE<()> { | 57 | pub async fn import(config: Cfg, file_str: String, direct_download: bool) -> MLE<()> { |
68 | 58 | ||
69 | let filestr: String = match input.file { | 59 | let mut file = File::open(file_str)?; |
70 | Some(args) => args, | ||
71 | None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()), | ||
72 | }; | ||
73 | |||
74 | let mut file = File::open(filestr)?; | ||
75 | let mut content = String::new(); | 60 | let mut content = String::new(); |
76 | file.read_to_string(&mut content)?; | 61 | file.read_to_string(&mut content)?; |
77 | let export: Export = toml::from_str(&content)?; | 62 | let export: Export = toml::from_str(&content)?; |
@@ -86,7 +71,7 @@ async fn import(config: Cfg, input: Input) -> MLE<()> { | |||
86 | }; | 71 | }; |
87 | //TODO impl set_version and good direct download | 72 | //TODO impl set_version and good direct download |
88 | //TODO impl all at once, dafuck | 73 | //TODO impl all at once, dafuck |
89 | mods_add(config.clone(), mod_ids, list, input.direct_download, false).await?; | 74 | mod_add(config.clone(), mod_ids, list, direct_download, false).await?; |
90 | } | 75 | } |
91 | Ok(()) | 76 | Ok(()) |
92 | } | 77 | } |
diff --git a/src/commands/list.rs b/src/commands/list.rs index 8e86973..80e801a 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use crate::{db::{lists_insert, lists_remove, config_change_current_list, config_get_current_list, lists_get, lists_version}, Modloader, config::Cfg, input::{Input, ListOptions}, cmd_update, error::MLE}; | 1 | use crate::{db::{lists_insert, lists_remove, config_change_current_list, config_get_current_list, lists_get, lists_version}, Modloader, config::Cfg, update, error::MLE}; |
2 | 2 | ||
3 | #[derive(Debug, Clone, PartialEq, Eq)] | 3 | #[derive(Debug, Clone, PartialEq, Eq)] |
4 | pub struct List { | 4 | pub struct List { |
@@ -8,44 +8,23 @@ pub struct List { | |||
8 | pub download_folder: String, | 8 | pub download_folder: String, |
9 | } | 9 | } |
10 | 10 | ||
11 | pub async fn list(config: Cfg, input: Input) -> MLE<()> { | ||
12 | |||
13 | match input.clone().list_options.unwrap() { | ||
14 | ListOptions::Add => { | ||
15 | add(config, input) | ||
16 | }, | ||
17 | ListOptions::Change => { | ||
18 | change(config, input) | ||
19 | }, | ||
20 | ListOptions::Remove => { | ||
21 | remove(config, input) | ||
22 | }, | ||
23 | ListOptions::Version => { | ||
24 | version(config, input).await | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | |||
29 | pub fn get_current_list(config: Cfg) -> MLE<List> { | 11 | pub fn get_current_list(config: Cfg) -> MLE<List> { |
30 | let id = config_get_current_list(config.clone())?; | 12 | let id = config_get_current_list(config.clone())?; |
31 | lists_get(config, id) | 13 | lists_get(config, id) |
32 | } | 14 | } |
33 | 15 | ||
34 | fn add(config: Cfg, input: Input) -> MLE<()> { | 16 | pub fn list_add(config: Cfg, id: String, mc_version: String, modloader: Modloader, directory: String) -> MLE<()> { |
35 | let id = input.list_id.unwrap(); | 17 | lists_insert(config, id, mc_version, modloader, directory) |
36 | let mc_version = input.list_mcversion.unwrap(); | ||
37 | let mod_loader = input.modloader.unwrap(); | ||
38 | let download_folder = input.directory.unwrap(); | ||
39 | lists_insert(config, id, mc_version, mod_loader, download_folder) | ||
40 | } | 18 | } |
41 | 19 | ||
42 | fn change(config: Cfg, input: Input) -> MLE<()> { | 20 | pub fn list_change(config: Cfg, id: String) -> MLE<()> { |
43 | println!("Change default list to: {}", input.clone().list.unwrap().id); | 21 | //TODO check if list exists |
44 | config_change_current_list(config, input.list.unwrap().id) | 22 | println!("Change default list to: {}", id); |
23 | config_change_current_list(config, id) | ||
45 | } | 24 | } |
46 | 25 | ||
47 | fn remove(config: Cfg, input: Input) -> MLE<()> { | 26 | pub fn list_remove(config: Cfg, id: String) -> MLE<()> { |
48 | lists_remove(config, input.list.unwrap().id) | 27 | lists_remove(config, id) |
49 | } | 28 | } |
50 | 29 | ||
51 | ///Changing the current lists version and updating it | 30 | ///Changing the current lists version and updating it |
@@ -54,14 +33,12 @@ fn remove(config: Cfg, input: Input) -> MLE<()> { | |||
54 | /// | 33 | /// |
55 | /// * `config` - The current config | 34 | /// * `config` - The current config |
56 | /// * `args` - All args, to extract the new version | 35 | /// * `args` - All args, to extract the new version |
57 | async fn version(config: Cfg, input: Input) -> MLE<()> { | 36 | pub async fn list_version(config: Cfg, id: String, mc_version: String, download: bool, delete: bool) -> MLE<()> { |
58 | println!("Change version for list {} to minecraft version: {}", input.clone().list.unwrap().id, input.clone().list_mcversion.unwrap()); | 37 | println!("Change version for list {} to minecraft version: {}", id, mc_version); |
59 | 38 | ||
60 | lists_version(config.clone(), input.clone().list.ok_or("").unwrap().id, input.clone().list_mcversion.ok_or("").unwrap())?; | 39 | lists_version(config.clone(), &id, &mc_version)?; |
61 | |||
62 | //Linebreak readability | ||
63 | println!(""); | ||
64 | 40 | ||
65 | println!("Check for updates for new minecraft version in list {}", input.clone().list.unwrap().id); | 41 | println!("\nCheck for updates for new minecraft version in list {}", id); |
66 | cmd_update(config, vec![input.list.ok_or("").unwrap()], true, input.direct_download, input.delete_old).await | 42 | let list = lists_get(config.clone(), id)?; |
43 | update(config, vec![list], true, download, delete).await | ||
67 | } | 44 | } |
diff --git a/src/commands/modification.rs b/src/commands/modification.rs index 31e50af..454e148 100644 --- a/src/commands/modification.rs +++ b/src/commands/modification.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use crate::{modrinth::{versions, extract_current_version, Version, projects, get_raw_versions, project}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, userlist_get_all_ids, userlist_get_current_version, lists_get_all_ids, mods_remove}, input::{Input, ModOptions}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}}; | 1 | use crate::{modrinth::{versions, extract_current_version, Version, projects, get_raw_versions, project}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, userlist_get_all_ids, userlist_get_current_version, lists_get_all_ids, mods_remove}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}}; |
2 | 2 | ||
3 | #[derive(Debug, Clone, PartialEq, Eq)] | 3 | #[derive(Debug, Clone, PartialEq, Eq)] |
4 | pub enum IDSelector { | 4 | pub enum IDSelector { |
@@ -6,24 +6,6 @@ pub enum IDSelector { | |||
6 | VersionID(String) | 6 | VersionID(String) |
7 | } | 7 | } |
8 | 8 | ||
9 | pub async fn modification(config: Cfg, input: Input) -> MLE<()> { | ||
10 | match input.clone().mod_options.ok_or("").unwrap() { | ||
11 | ModOptions::Add => { | ||
12 | add(config, input).await | ||
13 | }, | ||
14 | ModOptions::Remove => { | ||
15 | remove(config, input) | ||
16 | }, | ||
17 | } | ||
18 | } | ||
19 | |||
20 | async fn add(config: Cfg, input: Input) -> MLE<()> { | ||
21 | |||
22 | mods_add(config, vec![input.mod_id.unwrap()], input.list.unwrap(), input.direct_download, input.set_version).await?; | ||
23 | |||
24 | Ok(()) | ||
25 | } | ||
26 | |||
27 | #[derive(Debug, Clone)] | 9 | #[derive(Debug, Clone)] |
28 | pub struct ProjectInfo { | 10 | pub struct ProjectInfo { |
29 | pub mod_id: String, | 11 | pub mod_id: String, |
@@ -34,7 +16,7 @@ pub struct ProjectInfo { | |||
34 | pub download_link: String, | 16 | pub download_link: String, |
35 | } | 17 | } |
36 | 18 | ||
37 | pub async fn mods_add(config: Cfg, ids: Vec<IDSelector>, list: List, direct_download: bool, set_version: bool) -> MLE<()> { | 19 | pub async fn mod_add(config: Cfg, ids: Vec<IDSelector>, list: List, direct_download: bool, set_version: bool) -> MLE<()> { |
38 | println!("Add mods to {}", list.id); | 20 | println!("Add mods to {}", list.id); |
39 | println!(" â””Add mods:"); | 21 | println!(" â””Add mods:"); |
40 | 22 | ||
@@ -156,22 +138,24 @@ async fn get_ver_info(config: Cfg, ver_ids: Vec<String>) -> MLE<Vec<ProjectInfo> | |||
156 | Ok(projectinfo) | 138 | Ok(projectinfo) |
157 | } | 139 | } |
158 | 140 | ||
159 | fn remove(config: Cfg, input: Input) -> MLE<()> { | 141 | /// Remove mod from a list |
160 | 142 | /// # Arguments | |
161 | let id = match input.clone().mod_id.unwrap() { | 143 | /// |
162 | IDSelector::ModificationID(id) => id, | 144 | /// * `config` - config struct |
163 | IDSelector::VersionID(..) => return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ID")), | 145 | /// * `id` - name, slug or id of the mod |
164 | }; | 146 | /// * `list` - List struct |
147 | pub fn mod_remove(config: Cfg, id: &str, list: List) -> MLE<()> { | ||
165 | 148 | ||
166 | let mod_id = mods_get_id(&config.data, &id)?; | 149 | let mod_id = mods_get_id(&config.data, id)?; |
167 | 150 | ||
168 | let version = userlist_get_current_version(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; | 151 | let version = userlist_get_current_version(config.clone(), &list.id, &mod_id)?; |
169 | 152 | ||
170 | userlist_remove(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; | 153 | userlist_remove(config.clone(), &list.id, &mod_id)?; |
171 | delete_version(input.list.unwrap(), version)?; | 154 | delete_version(list, version)?; |
172 | 155 | ||
173 | let list_ids = lists_get_all_ids(config.clone())?; | 156 | let list_ids = lists_get_all_ids(config.clone())?; |
174 | 157 | ||
158 | // Remove mod from main list if not used elsewhere | ||
175 | let mut mod_used = false; | 159 | let mut mod_used = false; |
176 | for id in list_ids { | 160 | for id in list_ids { |
177 | let mods = userlist_get_all_ids(config.clone(), id)?; | 161 | let mods = userlist_get_all_ids(config.clone(), id)?; |
diff --git a/src/commands/update.rs b/src/commands/update.rs index 75bee39..e5751c0 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs | |||
@@ -1,21 +1,6 @@ | |||
1 | use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, userlist_get_set_version, mods_get_info}, List, input::Input, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; | 1 | use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, userlist_get_current_version, userlist_get_set_version, mods_get_info}, List, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; |
2 | |||
3 | pub async fn update(config: Cfg, input: Input) -> MLE<()> { | ||
4 | let mut liststack: Vec<List> = vec![]; | ||
5 | if input.all_lists { | ||
6 | let list_ids = lists_get_all_ids(config.clone())?; | ||
7 | for id in list_ids { | ||
8 | liststack.push(lists_get(config.clone(), id)?); | ||
9 | } | ||
10 | } else { | ||
11 | let current = get_current_list(config.clone())?; | ||
12 | println!("Update list {}:", current.id); | ||
13 | liststack.push(current) | ||
14 | } | ||
15 | cmd_update(config, liststack, input.clean, input.direct_download, input.delete_old).await | ||
16 | } | ||
17 | 2 | ||
18 | pub async fn cmd_update(config: Cfg, liststack: Vec<List>, clean: bool, direct_download: bool, delete_old: bool) -> MLE<()> { | 3 | pub async fn update(config: Cfg, liststack: Vec<List>, clean: bool, direct_download: bool, delete_old: bool) -> MLE<()> { |
19 | for current_list in liststack { | 4 | for current_list in liststack { |
20 | let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; | 5 | let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; |
21 | 6 | ||
@@ -34,7 +19,7 @@ pub async fn cmd_update(config: Cfg, liststack: Vec<List>, clean: bool, direct_d | |||
34 | } | 19 | } |
35 | 20 | ||
36 | //Getting current installed version for disable or delete | 21 | //Getting current installed version for disable or delete |
37 | let disable_version = userlist_get_current_version(config.clone(), String::from(¤t_list.id), String::from(&id))?; | 22 | let disable_version = userlist_get_current_version(config.clone(), ¤t_list.id, &id)?; |
38 | 23 | ||
39 | updatestack.push( | 24 | updatestack.push( |
40 | match specific_update(config.clone(), clean, current_list.clone(), String::from(&id)).await { | 25 | match specific_update(config.clone(), clean, current_list.clone(), String::from(&id)).await { |
@@ -110,6 +95,7 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML | |||
110 | }?; | 95 | }?; |
111 | current.push(current_ver.clone()); | 96 | current.push(current_ver.clone()); |
112 | 97 | ||
98 | //TODO implement version selection if no primary | ||
113 | let link = match current_ver.files.into_iter().find(|f| f.primary).ok_or("!no primary in links") { | 99 | let link = match current_ver.files.into_iter().find(|f| f.primary).ok_or("!no primary in links") { |
114 | Ok(p) => Ok(p), | 100 | Ok(p) => Ok(p), |
115 | Err(e) => Err(MLError::new(ErrorType::Other, e)), | 101 | Err(e) => Err(MLError::new(ErrorType::Other, e)), |
diff --git a/src/config.rs b/src/config.rs index ded0062..075d884 100644 --- a/src/config.rs +++ b/src/config.rs | |||
@@ -27,7 +27,7 @@ impl Cfg { | |||
27 | let default_cfg = Cfg { data: String::from("./"), apis: Apis { modrinth: String::from("https://api.modrinth.com/v2/") } }; | 27 | let default_cfg = Cfg { data: String::from("./"), apis: Apis { modrinth: String::from("https://api.modrinth.com/v2/") } }; |
28 | let mut file = File::create(devdir(configfile.to_str().unwrap()))?; | 28 | let mut file = File::create(devdir(configfile.to_str().unwrap()))?; |
29 | println!("Created config file"); | 29 | println!("Created config file"); |
30 | file.write_all(&toml::to_string(&default_cfg)?.as_bytes())?; | 30 | file.write_all(toml::to_string(&default_cfg)?.as_bytes())?; |
31 | File::open(devdir(configfile.to_str().unwrap()))? | 31 | File::open(devdir(configfile.to_str().unwrap()))? |
32 | } else { | 32 | } else { |
33 | return Err(err.into()); | 33 | return Err(err.into()); |
@@ -49,6 +49,9 @@ pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error:: | |||
49 | /// | 49 | /// |
50 | ///Will return `MLError` when no mod id is found | 50 | ///Will return `MLError` when no mod id is found |
51 | pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> { | 51 | pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> { |
52 | |||
53 | //TODO check if "slug" is id | ||
54 | |||
52 | let data = devdir(format!("{}/data.db", data).as_str()); | 55 | let data = devdir(format!("{}/data.db", data).as_str()); |
53 | let connection = Connection::open(data)?; | 56 | let connection = Connection::open(data)?; |
54 | 57 | ||
@@ -192,8 +195,7 @@ pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> { | |||
192 | } | 195 | } |
193 | } | 196 | } |
194 | 197 | ||
195 | 198 | pub fn userlist_remove(config: Cfg, list_id: &str, mod_id: &str) -> MLE<()> { | |
196 | pub fn userlist_remove(config: Cfg, list_id: String, mod_id: String) -> MLE<()> { | ||
197 | let data = devdir(format!("{}/data.db", config.data).as_str()); | 199 | let data = devdir(format!("{}/data.db", config.data).as_str()); |
198 | let connection = Connection::open(data)?; | 200 | let connection = Connection::open(data)?; |
199 | 201 | ||
@@ -242,7 +244,7 @@ pub fn userlist_get_all_applicable_versions_with_mods(config: Cfg, list_id: Stri | |||
242 | Ok(versions) | 244 | Ok(versions) |
243 | } | 245 | } |
244 | 246 | ||
245 | pub fn userlist_get_current_version(config: Cfg, list_id: String, mod_id: String) -> MLE<String> { | 247 | pub fn userlist_get_current_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<String> { |
246 | let data = devdir(format!("{}/data.db", config.data).as_str()); | 248 | let data = devdir(format!("{}/data.db", config.data).as_str()); |
247 | let connection = Connection::open(data).unwrap(); | 249 | let connection = Connection::open(data).unwrap(); |
248 | 250 | ||
@@ -425,7 +427,7 @@ pub fn lists_get(config: Cfg, list_id: String) -> MLE<List> { | |||
425 | Ok(list) | 427 | Ok(list) |
426 | } | 428 | } |
427 | 429 | ||
428 | pub fn lists_version(config: Cfg, list_id: String, version: String) -> MLE<()> { | 430 | pub fn lists_version(config: Cfg, list_id: &str, version: &str) -> MLE<()> { |
429 | let data = devdir(format!("{}/data.db", config.data).as_str()); | 431 | let data = devdir(format!("{}/data.db", config.data).as_str()); |
430 | let connection = Connection::open(data).unwrap(); | 432 | let connection = Connection::open(data).unwrap(); |
431 | 433 | ||
@@ -6,7 +6,7 @@ pub mod db; | |||
6 | pub mod error; | 6 | pub mod error; |
7 | pub mod files; | 7 | pub mod files; |
8 | 8 | ||
9 | use std::path::Path; | 9 | use std::{path::Path, fmt::Display}; |
10 | 10 | ||
11 | pub use apis::*; | 11 | pub use apis::*; |
12 | pub use commands::*; | 12 | pub use commands::*; |
@@ -19,14 +19,7 @@ pub enum Modloader { | |||
19 | } | 19 | } |
20 | 20 | ||
21 | impl Modloader { | 21 | impl Modloader { |
22 | fn to_string(&self) -> String { | 22 | pub fn from(string: &str) -> MLE<Modloader> { |
23 | match self { | ||
24 | Modloader::Fabric => String::from("fabric"), | ||
25 | Modloader::Forge => String::from("forge"), | ||
26 | } | ||
27 | } | ||
28 | |||
29 | fn from(string: &str) -> MLE<Modloader> { | ||
30 | match string { | 23 | match string { |
31 | "forge" => Ok(Modloader::Forge), | 24 | "forge" => Ok(Modloader::Forge), |
32 | "fabric" => Ok(Modloader::Fabric), | 25 | "fabric" => Ok(Modloader::Fabric), |
@@ -35,6 +28,15 @@ impl Modloader { | |||
35 | } | 28 | } |
36 | } | 29 | } |
37 | 30 | ||
31 | impl Display for Modloader { | ||
32 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
33 | match self { | ||
34 | Modloader::Fabric => write!(f, "fabric"), | ||
35 | Modloader::Forge => write!(f, "forge"), | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
38 | pub fn devdir(path: &str) -> String { | 40 | pub fn devdir(path: &str) -> String { |
39 | let p = Path::new(path); | 41 | let p = Path::new(path); |
40 | let dev = std::env::var("DEV"); | 42 | let dev = std::env::var("DEV"); |
diff --git a/src/main.rs b/src/main.rs index 32727c7..0dfc190 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,65 +1,237 @@ | |||
1 | use std::{env, process}; | 1 | use clap::{Parser, Subcommand}; |
2 | 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}; | ||
2 | 3 | ||
3 | use modlist::{config::Cfg, input::{get_input, Cmd}, update, download, list, io, modification, setup}; | 4 | //TODO make default list optional |
5 | |||
6 | #[derive(Parser)] | ||
7 | #[command(author, version, about)] | ||
8 | struct Cli { | ||
9 | #[command(subcommand)] | ||
10 | command: Commands, | ||
11 | } | ||
12 | |||
13 | #[derive(Subcommand)] | ||
14 | enum Commands { | ||
15 | r#Mod { | ||
16 | #[command(subcommand)] | ||
17 | command: ModCommands, | ||
18 | }, | ||
19 | List { | ||
20 | #[command(subcommand)] | ||
21 | command: ListCommands | ||
22 | }, | ||
23 | Download { | ||
24 | /// download all lists | ||
25 | #[arg(short, long)] | ||
26 | all: bool, | ||
27 | |||
28 | /// clean all mods before downloading them | ||
29 | #[arg(short, long)] | ||
30 | clean: bool, | ||
31 | |||
32 | /// remove disabled versions | ||
33 | #[arg(short, long)] | ||
34 | remove: bool, | ||
35 | }, | ||
36 | Update { | ||
37 | /// download all lists | ||
38 | #[arg(short, long)] | ||
39 | all: bool, | ||
40 | |||
41 | /// directly download updated mods | ||
42 | #[arg(short, long)] | ||
43 | download: bool, | ||
44 | |||
45 | /// clean all mods before downloading them | ||
46 | #[arg(short, long)] | ||
47 | clean: bool, | ||
48 | |||
49 | /// delete disabled versions | ||
50 | #[arg(short, long)] | ||
51 | remove: bool, | ||
52 | }, | ||
53 | Import { | ||
54 | #[arg(short, long)] | ||
55 | file: Option<String>, | ||
56 | |||
57 | /// directly download imported mods | ||
58 | #[arg(short, long)] | ||
59 | download: bool, | ||
60 | }, | ||
61 | Export { | ||
62 | /// the list you want to export | ||
63 | list: Option<String> | ||
64 | } | ||
65 | } | ||
66 | |||
67 | #[derive(Subcommand)] | ||
68 | enum ModCommands { | ||
69 | Add { | ||
70 | /// id of the mod/version | ||
71 | id: String, | ||
72 | |||
73 | /// set id mode to version | ||
74 | #[arg(short, long)] | ||
75 | version: bool, | ||
76 | |||
77 | /// directly download the mod | ||
78 | #[arg(short, long)] | ||
79 | download: bool, | ||
80 | |||
81 | /// lock the version added | ||
82 | #[arg(/* short , */long)] | ||
83 | lock: bool, | ||
84 | |||
85 | /// optional List selection, else default list will be used | ||
86 | #[arg(short, long)] | ||
87 | list: Option<String> | ||
88 | }, | ||
89 | Remove { | ||
90 | /// id, name or title of the mod | ||
91 | id: String, | ||
92 | |||
93 | /// optional List selection, else default list will be used | ||
94 | #[arg(short, long)] | ||
95 | list: Option<String> | ||
96 | } | ||
97 | } | ||
98 | |||
99 | #[derive(Subcommand)] | ||
100 | enum ListCommands { | ||
101 | Add { | ||
102 | /// list id | ||
103 | id: String, | ||
104 | |||
105 | directory: String, | ||
106 | |||
107 | modloader: Option<String>, | ||
108 | |||
109 | version: Option<String>, | ||
110 | }, | ||
111 | Remove { | ||
112 | /// id, name or title of the list | ||
113 | id: String | ||
114 | }, | ||
115 | List, | ||
116 | Change { | ||
117 | /// id of the list to change to | ||
118 | id: String | ||
119 | }, | ||
120 | Version { | ||
121 | /// list id | ||
122 | id: String, | ||
123 | /// desired minecraft version | ||
124 | version: String, | ||
125 | |||
126 | /// directly download updated mods | ||
127 | #[arg(long, short)] | ||
128 | download: bool, | ||
129 | |||
130 | /// delete disabled versions | ||
131 | #[arg(short, long)] | ||
132 | remove: bool, | ||
133 | } | ||
134 | } | ||
4 | 135 | ||
5 | #[tokio::main] | 136 | #[tokio::main] |
6 | async fn main() { | 137 | async fn main() { |
138 | |||
139 | let cli = Cli::parse(); | ||
140 | |||
7 | let config = Cfg::init("modlist.toml").unwrap(); | 141 | let config = Cfg::init("modlist.toml").unwrap(); |
8 | 142 | println!("{:?}", config); | |
9 | let mut args: Vec<String> = env::args().collect(); | 143 | |
10 | args.reverse(); | 144 | //TODO setup? maybe setup on install |
11 | args.pop(); | 145 | match cli.command { |
12 | args.reverse(); | 146 | Commands::Mod { command } => { |
13 | 147 | ||
14 | if args.is_empty() { | 148 | match command { |
15 | println!("Please enter an argument"); | 149 | #[allow(unused_variables)] |
16 | process::exit(1); | 150 | ModCommands::Add { id, version, list, download, lock } => { |
17 | }; | 151 | let listf = match list { |
18 | 152 | Some(list) => lists_get(config.clone(), list).unwrap(), | |
19 | let input = match get_input(config.clone(), args).await { | 153 | None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(), |
20 | Ok(i) => i, | 154 | }; |
21 | Err(e) => { | 155 | |
22 | println!("{}", e); | 156 | let marked_id = match version { |
23 | process::exit(1); | 157 | true => IDSelector::VersionID(id), |
24 | } | 158 | false => IDSelector::ModificationID(id), |
25 | }; | 159 | }; |
26 | 160 | ||
27 | match input.clone().command.unwrap() { | 161 | mod_add(config, vec![marked_id], listf, download, lock).await |
28 | Cmd::Mod => { | 162 | } |
29 | modification(config, input).await | 163 | ModCommands::Remove { id, list } => { |
30 | }, | 164 | //TODO add output |
31 | Cmd::List => { | 165 | //TODO add success even if no file found |
32 | list(config, input).await | 166 | let listf = match list { |
33 | }, | 167 | Some(list) => lists_get(config.clone(), list).unwrap(), |
34 | Cmd::Update => { | 168 | None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(), |
35 | update(config, input).await | 169 | }; |
36 | }, | 170 | mod_remove(config, &id, listf) |
37 | Cmd::Download => { | 171 | } |
38 | download(config, input).await | 172 | } |
39 | }, | 173 | }, |
40 | Cmd::Io => { | 174 | Commands::List { command } => { |
41 | io(config, input).await | 175 | match command { |
176 | ListCommands::Add { id, directory, modloader, version } => { | ||
177 | let ml = match modloader { | ||
178 | Some(ml) => Modloader::from(&ml).unwrap(), | ||
179 | //TODO add default modloader to config | ||
180 | None => Modloader::Fabric, | ||
181 | }; | ||
182 | |||
183 | let ver = match version { | ||
184 | Some(ver) => ver, | ||
185 | //TODO get latest version | ||
186 | //TODO impl config for specific version or latest or latest snap | ||
187 | None => "1.19.4".to_string(), | ||
188 | }; | ||
189 | |||
190 | list_add(config, id, ver, ml, directory) | ||
191 | }, | ||
192 | ListCommands::Remove { id } => { | ||
193 | list_remove(config, id) | ||
194 | }, | ||
195 | ListCommands::List => { | ||
196 | todo!() | ||
197 | }, | ||
198 | ListCommands::Change { id } => { | ||
199 | list_change(config, id) | ||
200 | }, | ||
201 | ListCommands::Version { id, version, download, remove } => { | ||
202 | list_version(config, id, version, download, remove).await | ||
203 | } | ||
204 | } | ||
42 | }, | 205 | }, |
43 | Cmd::Version => { | 206 | //TODO a add specific list |
44 | show_version(); | 207 | Commands::Update { all, download, clean, remove } => { |
45 | Ok(()) | 208 | let mut liststack: Vec<List> = vec![]; |
209 | if all { | ||
210 | let list_ids = lists_get_all_ids(config.clone()).unwrap(); | ||
211 | for id in list_ids { | ||
212 | liststack.push(lists_get(config.clone(), id).unwrap()); | ||
213 | } | ||
214 | } else { | ||
215 | let current = get_current_list(config.clone()).unwrap(); | ||
216 | println!("Update list {}:", current.id); | ||
217 | liststack.push(current) | ||
218 | } | ||
219 | update(config, liststack, clean, download, remove).await | ||
46 | }, | 220 | }, |
47 | Cmd::Setup => { | 221 | //TODO add specific list |
48 | setup(config).await | 222 | Commands::Download { all, clean, remove } => { |
223 | download(config, all, clean, remove).await | ||
49 | }, | 224 | }, |
50 | }.unwrap() | 225 | Commands::Import { file, download } => { |
51 | } | 226 | let filestr: String = match file { |
227 | Some(args) => args, | ||
228 | None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()), | ||
229 | }; | ||
52 | 230 | ||
53 | fn show_version() { | 231 | import(config, filestr, download).await |
54 | match std::env::var("DEV") { | ||
55 | Ok(dev) => { | ||
56 | let devint = dev.parse::<i32>().unwrap(); | ||
57 | if devint >= 1 { | ||
58 | println!("Modlist by FxQnLr v{} (DEV)", env!("CARGO_PKG_VERSION")); | ||
59 | } else { | ||
60 | println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")); | ||
61 | } | ||
62 | }, | 232 | }, |
63 | Err(..) => println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")), | 233 | Commands::Export { list } => { |
64 | } | 234 | export(config, list) |
235 | }, | ||
236 | }.unwrap(); | ||
65 | } | 237 | } |