Skip to content

Commit 5ce2df9

Browse files
Implement recursive, resolution-time dependencies
1 parent c6c7a1d commit 5ce2df9

File tree

11 files changed

+605
-241
lines changed

11 files changed

+605
-241
lines changed

Cargo.lock

Lines changed: 414 additions & 142 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,21 @@ rfd = { version = "0.14", optional = true, default-features = false, features =
4646
reqwest = { version = "0.12", default-features = false, features = [
4747
"rustls-tls",
4848
] }
49-
tokio = { version = "1.40", default-features = false, features = [
49+
tokio = { version = "1.41", default-features = false, features = [
5050
"rt-multi-thread",
5151
"macros",
5252
] }
5353
clap = { version = "4.5", features = ["derive"] }
5454
clap_complete = "4.5"
5555
serde_json = "1.0"
5656
indicatif = "0.17"
57-
octocrab = "0.41"
57+
octocrab = "0.42"
5858
fs_extra = "1.3"
5959
ferinth = "2.11"
6060
colored = "2.1"
61-
futures = "0.3"
6261
inquire = "0.7"
63-
libium = { git = "https://github.com/gorilla-devs/libium", rev = "b7d2cd767b840313bc71dca643e4252c4e16dd3e" }
64-
# libium = { path = "../libium" }
62+
# libium = { git = "https://github.com/gorilla-devs/libium", rev = "b7d2cd767b840313bc71dca643e4252c4e16dd3e" }
63+
libium = { path = "../libium" }
6564
# libium = "1.32"
6665
anyhow = "1.0"
6766
furse = "1.5"

src/download.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use fs_extra::{
77
dir::{copy as copy_dir, CopyOptions as DirCopyOptions},
88
file::{move_file, CopyOptions as FileCopyOptions},
99
};
10-
use futures::{stream::FuturesUnordered, StreamExt as _};
1110
use indicatif::ProgressBar;
1211
use libium::{iter_ext::IterExt as _, upgrade::DownloadData};
1312
use std::{
@@ -17,7 +16,7 @@ use std::{
1716
sync::{Arc, Mutex},
1817
time::Duration,
1918
};
20-
use tokio::sync::Semaphore;
19+
use tokio::{sync::Semaphore, task::JoinSet};
2120

2221
/// Check the given `directory`
2322
///
@@ -112,7 +111,7 @@ pub async fn download(
112111
.lock()
113112
.expect("Mutex poisoned")
114113
.enable_steady_tick(Duration::from_millis(100));
115-
let mut tasks = FuturesUnordered::new();
114+
let mut tasks = JoinSet::new();
116115
let semaphore = Arc::new(Semaphore::new(
117116
*PARALLEL_NETWORK.get_or_init(|| DEFAULT_PARALLEL_NETWORK),
118117
));
@@ -124,7 +123,7 @@ pub async fn download(
124123
let client = client.clone();
125124
let output_dir = output_dir.clone();
126125

127-
tasks.push(async move {
126+
tasks.spawn(async move {
128127
let _permit = semaphore.acquire_owned().await?;
129128

130129
let (length, filename) = downloadable
@@ -150,7 +149,7 @@ pub async fn download(
150149
Ok::<(), Error>(())
151150
});
152151
}
153-
while let Some(res) = tasks.next().await {
152+
for res in tasks.join_all().await {
154153
res?;
155154
}
156155
Arc::try_unwrap(progress_bar)

src/main.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const CROSS: &str = "×";
4545
static TICK: LazyLock<ColoredString> = LazyLock::new(|| "✓".green());
4646

4747
pub static PARALLEL_NETWORK: OnceLock<usize> = OnceLock::new();
48+
// Bump up the default to ~50
4849
pub const DEFAULT_PARALLEL_NETWORK: usize = 10;
4950

5051
/// Indicatif themes
@@ -184,7 +185,9 @@ async fn actual_main(mut cli_app: Ferium) -> Result<()> {
184185
(filename, None, None) => {
185186
println!("{} {}", "Unknown file:".yellow(), filename.dimmed());
186187
}
187-
(_, Some(mr_id), None) => send_ids.push(ModIdentifier::ModrinthProject(mr_id)),
188+
(_, Some(mr_id), None) => {
189+
send_ids.push(ModIdentifier::ModrinthProject(mr_id));
190+
}
188191
(_, None, Some(cf_id)) => {
189192
send_ids.push(ModIdentifier::CurseForgeProject(cf_id));
190193
}
@@ -265,13 +268,15 @@ async fn actual_main(mut cli_app: Ferium) -> Result<()> {
265268
format!("{} {:8}", "CF".red(), id.to_string().dimmed()),
266269
ModIdentifier::ModrinthProject(id) =>
267270
format!("{} {:8}", "MR".green(), id.dimmed()),
268-
ModIdentifier::GitHubRepository(_) => "GH".purple().to_string(),
271+
ModIdentifier::GitHubRepository(..) => "GH".purple().to_string(),
272+
_ => todo!(),
269273
},
270274
match &mod_.identifier {
271275
ModIdentifier::ModrinthProject(_)
272276
| ModIdentifier::CurseForgeProject(_) => mod_.name.bold().to_string(),
273-
ModIdentifier::GitHubRepository(id) =>
274-
format!("{}/{}", id.0.dimmed(), id.1.bold()),
277+
ModIdentifier::GitHubRepository(owner, repo) =>
278+
format!("{}/{}", owner.dimmed(), repo.bold()),
279+
_ => todo!(),
275280
},
276281
);
277282
}
@@ -458,7 +463,7 @@ fn get_active_profile(config: &mut Config) -> Result<&mut Profile> {
458463
bail!("There are no profiles configured, add a profile using `ferium profile create`")
459464
}
460465
1 => config.active_profile = 0,
461-
n if n <= config.active_profile => {
466+
n if config.active_profile >= n => {
462467
println!(
463468
"{}",
464469
"Active profile specified incorrectly, please pick a profile to use"

src/subcommands/list.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use anyhow::{Context as _, Result};
33
use colored::Colorize as _;
44
use ferinth::structures::{project::Project, user::TeamMember};
55
use furse::structures::mod_structs::Mod;
6-
use futures::{stream::FuturesUnordered, StreamExt as _};
76
use libium::{
87
config::structs::{ModIdentifier, Profile},
98
iter_ext::IterExt as _,
109
CURSEFORGE_API, GITHUB_API, MODRINTH_API,
1110
};
1211
use octocrab::models::{repos::Release, Repository};
12+
use tokio::task::JoinSet;
1313

1414
enum Metadata {
1515
CF(Mod),
@@ -31,7 +31,7 @@ impl Metadata {
3131
Metadata::CF(p) => ModIdentifier::CurseForgeProject(p.id),
3232
Metadata::MD(p, _) => ModIdentifier::ModrinthProject(p.id.clone()),
3333
Metadata::GH(p, _) => {
34-
ModIdentifier::GitHubRepository((p.owner.clone().unwrap().login, p.name.clone()))
34+
ModIdentifier::GitHubRepository(p.owner.clone().unwrap().login, p.name.clone())
3535
}
3636
}
3737
}
@@ -42,26 +42,23 @@ pub async fn verbose(profile: &mut Profile, markdown: bool) -> Result<()> {
4242
eprint!("Querying metadata... ");
4343
}
4444

45-
let mut tasks = FuturesUnordered::new();
45+
let mut tasks = JoinSet::new();
4646
let mut mr_ids = Vec::new();
4747
let mut cf_ids = Vec::new();
4848
for mod_ in &profile.mods {
4949
match mod_.identifier.clone() {
5050
ModIdentifier::CurseForgeProject(project_id) => cf_ids.push(project_id),
5151
ModIdentifier::ModrinthProject(project_id) => mr_ids.push(project_id),
52-
ModIdentifier::GitHubRepository((owner, repo)) => {
53-
tasks.push(async {
52+
ModIdentifier::GitHubRepository(owner, repo) => {
53+
let repo = GITHUB_API.repos(owner, repo);
54+
tasks.spawn(async move {
5455
Ok::<_, anyhow::Error>((
55-
GITHUB_API.repos(&owner, &repo).get().await?,
56-
GITHUB_API
57-
.repos(owner, repo)
58-
.releases()
59-
.list()
60-
.send()
61-
.await?,
56+
repo.get().await?,
57+
repo.releases().list().send().await?,
6258
))
6359
});
6460
}
61+
_ => todo!(),
6562
}
6663
}
6764

@@ -93,7 +90,7 @@ pub async fn verbose(profile: &mut Profile, markdown: bool) -> Result<()> {
9390
for project in cf_projects {
9491
metadata.push(Metadata::CF(project));
9592
}
96-
while let Some(res) = tasks.next().await {
93+
for res in tasks.join_all().await {
9794
let (repo, releases) = res?;
9895
metadata.push(Metadata::GH(repo, releases.items));
9996
}

src/subcommands/modpack/switch.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ pub fn switch(config: &mut Config, modpack_name: Option<String>) -> Result<()> {
4040
})
4141
.collect_vec();
4242

43-
if let Ok(selection) = Select::new("Select which modpack to switch to", modpack_info)
44-
.with_starting_cursor(config.active_modpack)
45-
.raw_prompt()
46-
{
43+
let mut select = Select::new("Select which modpack to switch to", modpack_info);
44+
if config.active_modpack < config.modpacks.len() {
45+
select.starting_cursor = config.active_modpack;
46+
}
47+
if let Ok(selection) = select.raw_prompt() {
4748
config.active_modpack = selection.index;
4849
}
4950
Ok(())

src/subcommands/modpack/upgrade.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::{
44
};
55
use anyhow::{Context as _, Result};
66
use colored::Colorize as _;
7-
use futures::{stream::FuturesUnordered, StreamExt as _};
87
use indicatif::ProgressBar;
98
use libium::{
109
config::structs::{Modpack, ModpackIdentifier},
@@ -22,6 +21,7 @@ use std::{
2221
path::{Path, PathBuf},
2322
time::Duration,
2423
};
24+
use tokio::task::JoinSet;
2525

2626
pub async fn upgrade(modpack: &'_ Modpack) -> Result<()> {
2727
let mut to_download: Vec<DownloadData> = Vec::new();
@@ -58,7 +58,7 @@ pub async fn upgrade(modpack: &'_ Modpack) -> Result<()> {
5858
let files = CURSEFORGE_API.get_files(file_ids).await?;
5959
println!("{} Fetched {} mods", &*TICK, files.len());
6060

61-
let mut tasks = FuturesUnordered::new();
61+
let mut tasks = JoinSet::new();
6262
let mut msg_shown = false;
6363
for file in files {
6464
match try_from_cf_file(file) {
@@ -81,7 +81,7 @@ pub async fn upgrade(modpack: &'_ Modpack) -> Result<()> {
8181
println!("\n{}", "The following mod(s) have denied 3rd parties such as Ferium from downloading it".red().bold());
8282
}
8383
msg_shown = true;
84-
tasks.push(async move {
84+
tasks.spawn(async move {
8585
let project = CURSEFORGE_API.get_mod(mod_id).await?;
8686
eprintln!(
8787
"- {}
@@ -97,7 +97,7 @@ pub async fn upgrade(modpack: &'_ Modpack) -> Result<()> {
9797
}
9898
}
9999

100-
while let Some(res) = tasks.next().await {
100+
for res in tasks.join_all().await {
101101
res?;
102102
}
103103

src/subcommands/profile/switch.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ pub fn switch(config: &mut Config, profile_name: Option<String>) -> Result<()> {
4444
})
4545
.collect_vec();
4646

47-
if let Ok(selection) = Select::new("Select which profile to switch to", profile_info)
48-
.with_starting_cursor(config.active_profile)
49-
.raw_prompt()
50-
{
47+
let mut select = Select::new("Select which profile to switch to", profile_info);
48+
if config.active_profile < config.profiles.len() {
49+
select.starting_cursor = config.active_profile;
50+
}
51+
if let Ok(selection) = select.raw_prompt() {
5152
config.active_profile = selection.index;
5253
}
5354
Ok(())

src/subcommands/remove.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ pub fn remove(profile: &mut Profile, to_remove: Vec<String>) -> Result<()> {
2020
match &mod_.identifier {
2121
ModIdentifier::CurseForgeProject(id) => format!("CF {:8}", id.to_string()),
2222
ModIdentifier::ModrinthProject(id) => format!("MR {id:8}"),
23-
ModIdentifier::GitHubRepository(_) => "GH".to_string(),
23+
ModIdentifier::GitHubRepository(..) => "GH".to_string(),
24+
_ => todo!(),
2425
},
2526
match &mod_.identifier {
2627
ModIdentifier::ModrinthProject(_) | ModIdentifier::CurseForgeProject(_) =>
2728
mod_.name.clone(),
28-
ModIdentifier::GitHubRepository(id) => format!("{}/{}", id.0, id.1),
29+
ModIdentifier::GitHubRepository(owner, repo) => format!("{owner}/{repo}"),
30+
_ => todo!(),
2931
},
3032
)
3133
})
@@ -44,9 +46,10 @@ pub fn remove(profile: &mut Profile, to_remove: Vec<String>) -> Result<()> {
4446
|| match &mod_.identifier {
4547
ModIdentifier::CurseForgeProject(id) => id.to_string() == to_remove,
4648
ModIdentifier::ModrinthProject(id) => id == &to_remove,
47-
ModIdentifier::GitHubRepository((owner, name)) => {
49+
ModIdentifier::GitHubRepository(owner, name) => {
4850
format!("{owner}/{name}").eq_ignore_ascii_case(&to_remove)
4951
}
52+
_ => todo!(),
5053
}
5154
}) {
5255
items_to_remove.push(index);

0 commit comments

Comments
 (0)