Skip to content

Commit

Permalink
Add Quilt support
Browse files Browse the repository at this point in the history
  • Loading branch information
theRookieCoder committed Apr 24, 2022
1 parent 0475f7c commit eeb3e82
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 68 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog for Ferium

## [3.22.0] - 24.04.2022

- Update to Libium 1.9
- Added static variables for a yellow tick and the dialoguer colourful theme
- Extracted the pick mod loader code to `profile/mod.rs`
- Added a yellow tick if the mod was compatible due to backwards compatibility

## [3.21.0] - 20.04.2022

- Removed `no_patch_check` flag for the upgrade command
Expand Down
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ferium"
version = "3.21.0"
version = "3.22.0"
edition = "2021"
authors = ["Ilesh Thiada (theRookieCoder) <[email protected]>", "Daniel Hauck (SolidTux)"]
description = "Ferium is a CLI program for managing Minecraft mods from Modrinth, CurseForge, and Github Releases"
Expand Down
4 changes: 2 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub enum ProfileSubCommands {
#[clap(long)]
#[clap(arg_enum)]
#[clap(help("The mod loader to check compatibility for"))]
mod_loader: Option<libium::config::structs::ModLoaders>,
mod_loader: Option<libium::config::structs::ModLoader>,
#[clap(long)]
#[clap(help("The name of the profile"))]
name: Option<String>,
Expand All @@ -97,7 +97,7 @@ pub enum ProfileSubCommands {
#[clap(long)]
#[clap(arg_enum)]
#[clap(help("The mod loader to check compatibility for"))]
mod_loader: Option<libium::config::structs::ModLoaders>,
mod_loader: Option<libium::config::structs::ModLoader>,
#[clap(long)]
#[clap(help("The name of the profile"))]
name: Option<String>,
Expand Down
43 changes: 29 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use tokio::{
const CROSS: &str = "×";
lazy_static! {
pub static ref TICK: ColoredString = "✓".green();
pub static ref YELLOW_TICK: ColoredString = "✓".yellow();
pub static ref THEME: dialoguer::theme::ColorfulTheme =
dialoguer::theme::ColorfulTheme::default();
}

struct Downloadable {
Expand Down Expand Up @@ -201,12 +204,13 @@ async fn actual_main() -> Result<()> {
check_empty_profile(profile)?;
create_dir_all(&profile.output_dir).await?;
let mut to_download = Vec::new();
let mut backwards_compat = false;
let mut error = false;

println!("{}\n", "Determining the Latest Compatible Versions".bold());
for mod_ in &profile.mods {
use libium::config::structs::ModIdentifier;
let result: Result<Downloadable, _> = match &mod_.identifier {
let result: Result<(Downloadable, bool), _> = match &mod_.identifier {
ModIdentifier::CurseForgeProject(project_id) => upgrade::curseforge(
&curseforge,
profile,
Expand All @@ -215,7 +219,7 @@ async fn actual_main() -> Result<()> {
mod_.check_mod_loader,
)
.await
.map(std::convert::Into::into),
.map(|ok| (ok.0.into(), ok.1)),
ModIdentifier::ModrinthProject(project_id) => upgrade::modrinth(
&modrinth,
profile,
Expand All @@ -224,13 +228,14 @@ async fn actual_main() -> Result<()> {
mod_.check_mod_loader,
)
.await
.map(|version| {
.map(|ok| {
let version = ok.0;
for file in &version.files {
if file.primary {
return file.clone().into();
return (file.clone().into(), ok.1);
}
}
version.files[0].clone().into()
(version.files[0].clone().into(), ok.1)
}),
ModIdentifier::GitHubRepository(full_name) => upgrade::github(
&github.repos(&full_name.0, &full_name.1),
Expand All @@ -239,15 +244,20 @@ async fn actual_main() -> Result<()> {
mod_.check_mod_loader,
)
.await
.map(std::convert::Into::into),
.map(|ok| (ok.0.into(), ok.1)),
};
match result {
Ok(result) => {
println!(
"{} {:40}{}",
*TICK,
if result.1 {
backwards_compat = true;
YELLOW_TICK.clone()
} else {
TICK.clone()
},
mod_.name,
format!("({})", result.filename).dimmed()
format!("({})", result.0.filename).dimmed()
);
to_download.push(result);
},
Expand All @@ -257,6 +267,12 @@ async fn actual_main() -> Result<()> {
},
}
}
if backwards_compat {
println!(
"{}",
"Fabric mod using Quilt backwards compatibility".yellow()
);
}

eprint!("\n{}", "Downloading Mod Files... ".bold());
for file in std::fs::read_dir(&profile.output_dir)? {
Expand All @@ -265,10 +281,9 @@ async fn actual_main() -> Result<()> {
if path.is_file() {
let mut index = None;
// If a file is already downloaded
if let Some(downloadable) = to_download
.iter()
.find_position(|thing| file.file_name().to_str().unwrap() == thing.filename)
{
if let Some(downloadable) = to_download.iter().find_position(|thing| {
file.file_name().to_str().unwrap() == thing.0.filename
}) {
index = Some(downloadable.0);
}
match index {
Expand All @@ -283,11 +298,11 @@ async fn actual_main() -> Result<()> {
}
match {
for downloadable in to_download {
let contents = reqwest::get(downloadable.download_url)
let contents = reqwest::get(downloadable.0.download_url)
.await?
.bytes()
.await?;
upgrade::write_mod_file(profile, contents, &downloadable.filename).await?;
upgrade::write_mod_file(profile, contents, &downloadable.0.filename).await?;
}
Ok::<(), anyhow::Error>(())
} {
Expand Down
26 changes: 7 additions & 19 deletions src/subcommands/profile/configure.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::subcommands::profile::pick_mod_loader;
use anyhow::Result;
use dialoguer::{theme::ColorfulTheme, Input, Select};
use dialoguer::{Input, Select};
use libium::{config, file_picker, misc};
use std::path::PathBuf;

pub async fn configure(
profile: &mut config::structs::Profile,
game_version: Option<String>,
mod_loader: Option<config::structs::ModLoaders>,
mod_loader: Option<config::structs::ModLoader>,
name: Option<String>,
output_dir: Option<PathBuf>,
) -> Result<()> {
Expand Down Expand Up @@ -44,7 +45,7 @@ pub async fn configure(
];

loop {
let selection = Select::with_theme(&ColorfulTheme::default())
let selection = Select::with_theme(&*crate::THEME)
.with_prompt("Which setting would you like to change")
.items(&items)
.interact_opt()?;
Expand All @@ -59,7 +60,7 @@ pub async fn configure(
1 => {
// Let user pick mc version from latest 10 versions
let mut versions = misc::get_major_mc_versions(10).await?;
let index = Select::with_theme(&ColorfulTheme::default())
let index = Select::with_theme(&*crate::THEME)
.with_prompt("Select a Minecraft version")
.items(&versions)
.default(0)
Expand All @@ -70,23 +71,10 @@ pub async fn configure(
},
2 => {
// Let user pick mod loader
let mod_loaders = ["Fabric", "Forge"];
let index = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Pick a mod loader")
.items(&mod_loaders)
.default(match profile.mod_loader {
config::structs::ModLoaders::Fabric => 0,
config::structs::ModLoaders::Forge => 1,
})
.interact_opt()?;
if index == Some(0) {
profile.mod_loader = config::structs::ModLoaders::Fabric;
} else if index == Some(1) {
profile.mod_loader = config::structs::ModLoaders::Forge;
}
profile.mod_loader = pick_mod_loader(Some(&profile.mod_loader))?;
},
3 => {
let name = Input::with_theme(&ColorfulTheme::default())
let name = Input::with_theme(&*crate::THEME)
.with_prompt("Change the profile's name")
.default(profile.name.clone())
.interact_text()?;
Expand Down
24 changes: 6 additions & 18 deletions src/subcommands/profile/create.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{bail, Result};
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
use dialoguer::{Confirm, Input, Select};
use ferinth::Ferinth;
use libium::{config, file_picker, misc};
use std::path::PathBuf;
Expand All @@ -9,7 +9,7 @@ pub async fn create(
config: &mut config::structs::Config,
game_version: Option<String>,
force_game_version: bool,
mod_loader: Option<config::structs::ModLoaders>,
mod_loader: Option<config::structs::ModLoader>,
name: Option<String>,
output_dir: Option<PathBuf>,
) -> Result<()> {
Expand Down Expand Up @@ -53,7 +53,7 @@ pub async fn create(
// Let user pick mods directory
let mut selected_mods_dir = misc::get_mods_dir();
println!("The default mods directory is {:?}", selected_mods_dir);
if Confirm::with_theme(&ColorfulTheme::default())
if Confirm::with_theme(&*crate::THEME)
.with_prompt("Would you like to specify a custom mods directory?")
.interact()?
{
Expand All @@ -65,7 +65,7 @@ pub async fn create(
let mut name = String::new();
let mut prompt = true;
while prompt {
name = Input::with_theme(&ColorfulTheme::default())
name = Input::with_theme(&*crate::THEME)
.with_prompt("What should this profile be called?")
.interact_text()?;

Expand All @@ -82,31 +82,19 @@ pub async fn create(
// Let user pick Minecraft version
let mut latest_versions: Vec<String> = misc::get_major_mc_versions(10).await?;
println!();
let selected_version = Select::with_theme(&ColorfulTheme::default())
let selected_version = Select::with_theme(&*crate::THEME)
.with_prompt("Which version of Minecraft do you play?")
.items(&latest_versions)
.default(0)
.interact()?;
let selected_version = latest_versions.swap_remove(selected_version);

// Let user pick mod loader
let mod_loaders = ["Fabric", "Forge"];
let selected_loader = if Select::with_theme(&ColorfulTheme::default())
.with_prompt("Which mod loader do you use?")
.items(&mod_loaders)
.interact()?
== 0
{
config::structs::ModLoaders::Fabric
} else {
config::structs::ModLoaders::Forge
};
config.profiles.push(config::structs::Profile {
name,
output_dir: selected_mods_dir,
mods: Vec::new(),
game_version: selected_version,
mod_loader: selected_loader,
mod_loader: super::pick_mod_loader(None)?,
});
},
_ => {
Expand Down
4 changes: 2 additions & 2 deletions src/subcommands/profile/delete.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::subcommands::switch::switch;
use anyhow::{bail, Result};
use dialoguer::{theme::ColorfulTheme, Select};
use dialoguer::Select;
use libium::config;

pub fn delete(config: &mut config::structs::Config, profile_name: Option<String>) -> Result<()> {
Expand All @@ -23,7 +23,7 @@ pub fn delete(config: &mut config::structs::Config, profile_name: Option<String>
.map(|profile| &profile.name)
.collect::<Vec<_>>();

let selection = Select::with_theme(&ColorfulTheme::default())
let selection = Select::with_theme(&*crate::THEME)
.with_prompt("Select which profile to delete")
.items(&profile_names)
.default(config.active_profile)
Expand Down
2 changes: 1 addition & 1 deletion src/subcommands/profile/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub fn list(config: &config::structs::Config) {
"{}{}
\r Output directory: {}
\r Minecraft Version: {}
\r Mod Loader: {}
\r Mod Loader: {:?}
\r Mods: {}\n",
profile.name,
if i == config.active_profile { " *" } else { "" },
Expand Down
22 changes: 22 additions & 0 deletions src/subcommands/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,25 @@ pub use configure::configure;
pub use create::create;
pub use delete::delete;
pub use list::list;

fn pick_mod_loader(
default: Option<&libium::config::structs::ModLoader>,
) -> std::io::Result<libium::config::structs::ModLoader> {
let mut picker = dialoguer::Select::with_theme(&*crate::THEME);
picker
.with_prompt("Which mod loader do you use?")
.items(&["Quilt", "Fabric", "Forge"]);
if let Some(default) = default {
picker.default(match default {
libium::config::structs::ModLoader::Quilt => 0,
libium::config::structs::ModLoader::Fabric => 1,
libium::config::structs::ModLoader::Forge => 2,
});
}
match picker.interact()? {
0 => Ok(libium::config::structs::ModLoader::Quilt),
1 => Ok(libium::config::structs::ModLoader::Fabric),
2 => Ok(libium::config::structs::ModLoader::Forge),
_ => unreachable!(),
}
}
4 changes: 2 additions & 2 deletions src/subcommands/remove.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{bail, Result};
use dialoguer::{theme::ColorfulTheme, MultiSelect};
use dialoguer::MultiSelect;
use libium::config;

/// Display a list of mods and repos in the profile to select from and remove selected ones
Expand Down Expand Up @@ -28,7 +28,7 @@ pub fn remove(
}
},
None => {
items_to_remove = match MultiSelect::with_theme(&ColorfulTheme::default())
items_to_remove = match MultiSelect::with_theme(&*crate::THEME)
.with_prompt("Select mods to remove")
.items(&names)
.interact_opt()?
Expand Down
Loading

0 comments on commit eeb3e82

Please sign in to comment.