diff options
Diffstat (limited to 'src/commands/update.rs')
-rw-r--r-- | src/commands/update.rs | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/src/commands/update.rs b/src/commands/update.rs index 42d19aa..c8f0880 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use std::io::{Error, ErrorKind}; | 1 | use std::{io::{Error, ErrorKind}, fs::{rename, remove_file}}; |
2 | 2 | ||
3 | use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get}, List, input::Input, download_file}; | 3 | use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, userlist_add_disabled_versions, mods_change_versions}, List, input::Input, files::get_file_path, download_versions}; |
4 | 4 | ||
5 | pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> { | 5 | pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> { |
6 | 6 | ||
7 | let mut liststack: Vec<List> = vec![]; | 7 | let mut liststack: Vec<List> = vec![]; |
8 | if input.all_lists { | 8 | if input.all_lists { |
9 | let list_ids = lists_get_all_ids(config.clone())?; | 9 | let list_ids = lists_get_all_ids(config.clone())?; |
@@ -11,18 +11,22 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error: | |||
11 | liststack.push(lists_get(config.clone(), id)?); | 11 | liststack.push(lists_get(config.clone(), id)?); |
12 | } | 12 | } |
13 | } else { | 13 | } else { |
14 | liststack.push(get_current_list(config.clone())?) | 14 | let current = get_current_list(config.clone())?; |
15 | println!("Checking for updates of mods in {}", current.id); | ||
16 | liststack.push(current) | ||
15 | } | 17 | } |
16 | 18 | ||
17 | for current_list in liststack { | 19 | for current_list in liststack { |
18 | let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; | 20 | let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; |
21 | |||
22 | let mut current_versions: Vec<(String, String)> = vec![]; | ||
19 | 23 | ||
20 | let mut versions = mods_get_versions(config.clone(), mods.clone())?; | 24 | let mut versions = mods_get_versions(config.clone(), mods.clone())?; |
21 | versions.sort_by_key(|ver| ver.mod_id.clone()); | 25 | versions.sort_by_key(|ver| ver.mod_id.clone()); |
22 | 26 | ||
23 | let mut projects = projects(String::from(&config.apis.modrinth), mods).await; | 27 | let mut projects = projects(String::from(&config.apis.modrinth), mods).await; |
24 | projects.sort_by_key(|pro| pro.id.clone()); | 28 | projects.sort_by_key(|pro| pro.id.clone()); |
25 | 29 | ||
26 | let mut updatestack: Vec<Version> = vec![]; | 30 | let mut updatestack: Vec<Version> = vec![]; |
27 | for (index, project) in projects.into_iter().enumerate() { | 31 | for (index, project) in projects.into_iter().enumerate() { |
28 | //Get versions for project and check if they match up | 32 | //Get versions for project and check if they match up |
@@ -30,14 +34,26 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error: | |||
30 | let p_id = String::from(&project.id); | 34 | let p_id = String::from(&project.id); |
31 | let v_id = ¤t_version.mod_id; | 35 | let v_id = ¤t_version.mod_id; |
32 | if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) }; | 36 | if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) }; |
33 | 37 | ||
38 | //Getting current installed version for disable or delete | ||
39 | let disable_version = userlist_get_current_version(config.clone(), String::from(¤t_list.id), String::from(&project.id))?; | ||
40 | |||
41 | let version_db_string = project.versions.join("|"); | ||
34 | 42 | ||
35 | //Adding to stack if not the same versions in the list OR if clean == true | 43 | //Adding to stack if not the same versions in the list OR if clean == true |
36 | if input.clone().clean || (project.versions.join("|") != current_version.versions) { | 44 | if input.clone().clean || (version_db_string != current_version.versions) { |
37 | updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project.clone()).await { | 45 | updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project.clone()).await { |
38 | Ok(ver) => ver, | 46 | Ok(ver) => { |
47 | current_versions.push((disable_version, p_id)); | ||
48 | ver | ||
49 | }, | ||
39 | //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE") | 50 | //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE") |
40 | Err(_) => { println!("({}) No new version found for the specified minecraft version", project.title); continue; }, | 51 | Err(e) => { |
52 | //Updating versions in modlist for no repeating version calls | ||
53 | mods_change_versions(config.clone(), version_db_string, project.id)?; | ||
54 | println!("({}) No new version found for the specified minecraft version({})", project.title, e); | ||
55 | continue; | ||
56 | }, | ||
41 | }); | 57 | }); |
42 | } else { | 58 | } else { |
43 | println!("({}) No new version found", project.title); | 59 | println!("({}) No new version found", project.title); |
@@ -53,14 +69,19 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error: | |||
53 | } | 69 | } |
54 | } | 70 | } |
55 | 71 | ||
56 | if input.direct_download { download_updates(current_list, updatestack).await?; }; | 72 | if input.direct_download { download_versions(current_list.clone(), updatestack).await?; }; |
73 | |||
74 | //Disable old versions | ||
75 | for ver in current_versions { | ||
76 | if input.delete_old { delete_old(current_list.clone(), ver.0, ver.1)? } else { disable_old(config.clone(), current_list.clone(), ver.0, ver.1)? }; | ||
77 | } | ||
57 | } | 78 | } |
58 | 79 | ||
59 | Ok(()) | 80 | Ok(()) |
60 | } | 81 | } |
61 | 82 | ||
62 | async fn specific_update(config: Cfg, input: Input, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> { | 83 | async fn specific_update(config: Cfg, input: Input, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> { |
63 | print!("Checking update for '{}' in {}", project.title, list.id); | 84 | println!("Checking update for '{}' in {}", project.title, list.id); |
64 | 85 | ||
65 | let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; | 86 | let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; |
66 | 87 | ||
@@ -88,17 +109,25 @@ async fn specific_update(config: Cfg, input: Input, list: List, project: Project | |||
88 | Ok(current[0].clone()) | 109 | Ok(current[0].clone()) |
89 | } | 110 | } |
90 | 111 | ||
91 | async fn download_updates(current_list: List, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { | 112 | fn disable_old(config: Cfg, current_list: List, versionid: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> { |
113 | println!("Disabling version {} for mod {}", versionid, mod_id); | ||
114 | let file = get_file_path(current_list.clone(), String::from(&versionid))?; | ||
115 | let disabled = format!("{}.disabled", file); | ||
92 | 116 | ||
93 | let dl_path = String::from(¤t_list.download_folder); | 117 | rename(file, disabled)?; |
94 | 118 | ||
95 | for ver in versions { | 119 | userlist_add_disabled_versions(config, current_list.id, versionid, mod_id)?; |
96 | let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); | 120 | |
97 | download_file(primary_file.url, current_list.clone().download_folder, primary_file.filename).await?; | 121 | Ok(()) |
98 | } | 122 | } |
99 | 123 | ||
124 | fn delete_old(current_list: List, versionid: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> { | ||
125 | println!("Deleting version {} for mod {}", versionid, mod_id); | ||
126 | let file = get_file_path(current_list, String::from(&versionid))?; | ||
127 | |||
128 | remove_file(file)?; | ||
100 | 129 | ||
101 | Ok(dl_path) | 130 | Ok(()) |
102 | } | 131 | } |
103 | 132 | ||
104 | #[tokio::test] | 133 | #[tokio::test] |
@@ -138,5 +167,5 @@ async fn download_updates_test() { | |||
138 | "fabric".to_string() | 167 | "fabric".to_string() |
139 | ] | 168 | ] |
140 | }]; | 169 | }]; |
141 | assert!(download_updates(current_list, versions).await.is_ok()) | 170 | assert!(download_versions(current_list, versions).await.is_ok()) |
142 | } | 171 | } |