diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b4a9b3..e2e4663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog for Ferium +## [3.21.0] - 20.04.2022 + +- Removed `no_patch_check` flag for the upgrade command +- There are now overrides for game version and mod loader checks. For now there is no UI, you have to edit the config file manually + +## [3.20.1] - 16.04.2022 + +When picking a file from a version, Ferium will get the primary file rather than the first file + ## [3.20.0] - 16.04.2022 - Added a `Downloadable` struct that represents (and be converted from) a mod file from Modrinth, GitHub Releases, or CurseForge diff --git a/Cargo.lock b/Cargo.lock index 6ea4b26..e52c766 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,9 +208,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" dependencies = [ "addr2line", "cc", @@ -324,9 +324,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.9" +version = "3.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe" +checksum = "3124f3f75ce09e22d1410043e1e24f2ecc44fad3afe4f08408f1f7663d68da2b" dependencies = [ "atty", "bitflags", @@ -499,7 +499,7 @@ dependencies = [ [[package]] name = "ferium" -version = "3.20.0" +version = "3.21.0" dependencies = [ "anyhow", "bytes", @@ -898,9 +898,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" @@ -986,15 +986,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.123" +version = "0.2.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" [[package]] name = "libium" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d118e25a140a51c51ca457ee51cbd6491fcd7d52141835603bad79e6a17d7e" +checksum = "8cd258b2c491a46b83302ec9552e2ebba004c4d23e9e301578274dca331dcb86" dependencies = [ "bytes", "clap", @@ -1006,7 +1006,6 @@ dependencies = [ "octocrab", "reqwest", "rfd", - "semver", "serde", "serde_json", "thiserror", @@ -1052,12 +1051,11 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg", ] [[package]] @@ -1163,9 +1161,9 @@ dependencies = [ [[package]] name = "object" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456" dependencies = [ "memchr", ] @@ -1441,9 +1439,9 @@ dependencies = [ [[package]] name = "rfd" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca9214be1b6d296d4d539a31e795e556cdb43e60cbf0b77003be5b01075c13" +checksum = "92e3107b2e81967df7c0617e978dc656795583a73ad0ddbf645ce60109caf8c2" dependencies = [ "block", "dispatch", @@ -2121,9 +2119,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0128fa8e65e0616e45033d68dc0b7fbd521080b7844e5cad3a4a4d201c4b2bd2" +checksum = "08746b4b7ac95f708b3cccceb97b7f9a21a8916dd47fc99b0e6aaf7208f26fd7" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -2134,33 +2132,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +checksum = "db3bc5134e8ce0da5d64dcec3529793f1d33aee5a51fc2b4662e0f881dd463e6" [[package]] name = "windows_i686_gnu" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +checksum = "0343a6f35bf43a07b009b8591b78b10ea03de86b06f48e28c96206cd0f453b50" [[package]] name = "windows_i686_msvc" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +checksum = "1acdcbf4ca63d8e7a501be86fee744347186275ec2754d129ddeab7a1e3a02e4" [[package]] name = "windows_x86_64_gnu" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +checksum = "893c0924c5a990ec73cd2264d1c0cba1773a929e1a3f5dbccffd769f8c4edebb" [[package]] name = "windows_x86_64_msvc" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +checksum = "a29bd61f32889c822c99a8fdf2e93378bd2fae4d7efd2693fab09fcaaf7eff4b" [[package]] name = "winreg" diff --git a/Cargo.toml b/Cargo.toml index a6470cb..dde7fe8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ferium" -version = "3.20.0" +version = "3.21.0" edition = "2021" authors = ["Ilesh Thiada (theRookieCoder) ", "Daniel Hauck (SolidTux)"] description = "Ferium is a CLI program for managing Minecraft mods from Modrinth, CurseForge, and Github Releases" diff --git a/src/cli.rs b/src/cli.rs index eeed90d..df290da 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -63,15 +63,7 @@ pub enum SubCommands { #[clap(about("Sort all your mods in alphabetical order"))] Sort, #[clap(about("Download and install the latest version of the mods specified"))] - Upgrade { - #[clap(long)] - #[clap(help( - "Do not check for the full game version, only check for the major and minor versions - \rSome Minecraft versions (e.g. 1.18 & 1.18.1) are compatible with each other, - \rthis option allows you to use older, but still compatible, versions of a mod that might not have yet updated to the latest version" - ))] - no_patch_check: bool, - }, + Upgrade, } #[derive(Subcommand)] diff --git a/src/main.rs b/src/main.rs index d744139..881d264 100644 --- a/src/main.rs +++ b/src/main.rs @@ -197,7 +197,7 @@ async fn actual_main() -> Result<()> { subcommands::switch(&mut config, profile_name)?; }, SubCommands::Sort => profile.mods.sort_by_cached_key(|mod_| mod_.name.clone()), - SubCommands::Upgrade { no_patch_check } => { + SubCommands::Upgrade => { check_empty_profile(profile)?; create_dir_all(&profile.output_dir).await?; let mut to_download = Vec::new(); @@ -207,21 +207,39 @@ async fn actual_main() -> Result<()> { for mod_ in &profile.mods { use libium::config::structs::ModIdentifier; let result: Result = match &mod_.identifier { - ModIdentifier::CurseForgeProject(project_id) => { - upgrade::curseforge(&curseforge, profile, *project_id, no_patch_check) - .await - .map(std::convert::Into::into) - }, - ModIdentifier::ModrinthProject(project_id) => { - upgrade::modrinth(&modrinth, profile, project_id, no_patch_check) - .await - .map(|ok| ok.files[0].clone().into()) - }, - ModIdentifier::GitHubRepository(full_name) => { - upgrade::github(&github.repos(&full_name.0, &full_name.1), profile) - .await - .map(std::convert::Into::into) - }, + ModIdentifier::CurseForgeProject(project_id) => upgrade::curseforge( + &curseforge, + profile, + *project_id, + mod_.check_game_version, + mod_.check_mod_loader, + ) + .await + .map(std::convert::Into::into), + ModIdentifier::ModrinthProject(project_id) => upgrade::modrinth( + &modrinth, + profile, + project_id, + mod_.check_game_version, + mod_.check_mod_loader, + ) + .await + .map(|version| { + for file in &version.files { + if file.primary { + return file.clone().into(); + } + } + version.files[0].clone().into() + }), + ModIdentifier::GitHubRepository(full_name) => upgrade::github( + &github.repos(&full_name.0, &full_name.1), + profile, + mod_.check_game_version, + mod_.check_mod_loader, + ) + .await + .map(std::convert::Into::into), }; match result { Ok(result) => { diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 656ab36..5463c1a 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -7,242 +7,237 @@ type Result = std::io::Result<()>; #[test] fn argparse() -> Result { - run_command(vec!["help"], None)?; - run_command(vec!["profile", "help"], None) + run_command(vec!["help"], None)?; + run_command(vec!["profile", "help"], None) } #[test] fn create_config_file_when_none() { - // This should create a config file and then fail because there are no profiles - assert!(run_command(vec!["profile", "list"], None).is_err()); + // This should create a config file and then fail because there are no profiles + assert!(run_command(vec!["profile", "list"], None).is_err()); } #[test] fn create_profile() -> Result { - run_command( - vec![ - "profile", - "create", - "--name", - "Test profile", - "--game-version", - "1.12.2", - "--mod-loader", - "forge", - "--output-dir", - "/mods", - ], - Some("empty"), - ) + run_command( + vec![ + "profile", + "create", + "--name", + "Test profile", + "--game-version", + "1.12.2", + "--mod-loader", + "forge", + "--output-dir", + "/mods", + ], + Some("empty"), + ) } #[test] fn create_profile_non_existent_game_version() { - assert!(run_command( - vec![ - "profile", - "create", - "--name", - "Test profile", - "--game-version", - "1.12.3", // oops does not exist - "--mod-loader", - "forge", - "--output-dir", - "/mods" - ], - Some("empty") - ) - .is_err()); + assert!(run_command( + vec![ + "profile", + "create", + "--name", + "Test profile", + "--game-version", + "1.12.3", // oops does not exist + "--mod-loader", + "forge", + "--output-dir", + "/mods" + ], + Some("empty") + ) + .is_err()); } #[test] fn create_profile_output_dir_not_absolute() { - assert!(run_command( - vec![ - "profile", - "create", - "--name", - "Test profile", - "--game-version", - "1.12.2", - "--mod-loader", - "forge", - "--output-dir", - "mods" // oops relative directory - ], - Some("empty") - ) - .is_err()); + assert!(run_command( + vec![ + "profile", + "create", + "--name", + "Test profile", + "--game-version", + "1.12.2", + "--mod-loader", + "forge", + "--output-dir", + "mods" // oops relative directory + ], + Some("empty") + ) + .is_err()); } #[test] fn create_profile_missing_args() { - assert!(run_command( - vec![ - "profile", - "create", - // oops no name - "--game-version", - "1.12.2", - "--mod-loader", - "forge", - "--output-dir", - "/mods" - ], - Some("empty") - ) - .is_err()); + assert!(run_command( + vec![ + "profile", + "create", + // oops no name + "--game-version", + "1.12.2", + "--mod-loader", + "forge", + "--output-dir", + "/mods" + ], + Some("empty") + ) + .is_err()); } #[test] fn create_profile_name_already_exists() { - assert!(run_command( - vec![ - "profile", - "create", - "--name", - "Test profile", // oops profile with same name already exists - "--game-version", - "1.12.2", - "--mod-loader", - "forge", - "--output-dir", - "/mods" - ], - Some("empty_profile") - ) - .is_err()); + assert!(run_command( + vec![ + "profile", + "create", + "--name", + "Test profile", // oops profile with same name already exists + "--game-version", + "1.12.2", + "--mod-loader", + "forge", + "--output-dir", + "/mods" + ], + Some("empty_profile") + ) + .is_err()); } #[test] fn add_modrinth() -> Result { - // Add Sodium to config - run_command(vec!["add-modrinth", "starlight"], Some("empty_profile")) + // Add Sodium to config + run_command(vec!["add-modrinth", "starlight"], Some("empty_profile")) } #[test] fn add_curseforge() -> Result { - // Add Terralith to the config - run_command(vec!["add-curseforge", "513688"], Some("empty_profile")) + // Add Terralith to the config + run_command(vec!["add-curseforge", "513688"], Some("empty_profile")) } #[test] fn add_github() -> Result { - // Add Sodium to config - run_command( - vec!["add-github", "CaffeineMC", "sodium-fabric"], - Some("empty_profile"), - ) + // Add Sodium to config + run_command( + vec!["add-github", "CaffeineMC", "sodium-fabric"], + Some("empty_profile"), + ) } #[test] fn already_added() { - assert!(run_command(vec!["add-modrinth", "StArLiGhT"], Some("one_profile_full")).is_err()); - assert!(run_command(vec!["add-curseforge", "513688"], Some("one_profile_full")).is_err()); - assert!(run_command( - vec!["add-github", "caffeinemc", "Sodium-Fabric"], - Some("one_profile_full") - ) - .is_err()); + assert!(run_command(vec!["add-modrinth", "StArLiGhT"], Some("one_profile_full")).is_err()); + assert!(run_command(vec!["add-curseforge", "513688"], Some("one_profile_full")).is_err()); + assert!(run_command( + vec!["add-github", "caffeinemc", "Sodium-Fabric"], + Some("one_profile_full") + ) + .is_err()); } #[test] fn list() -> Result { - run_command(vec!["list"], Some("one_profile_full"))?; - run_command(vec!["list", "--verbose"], Some("one_profile_full")) + run_command(vec!["list"], Some("one_profile_full"))?; + run_command(vec!["list", "--verbose"], Some("one_profile_full")) } #[test] fn profile_list() -> Result { - run_command(vec!["profile", "list"], Some("one_profile_full")) + run_command(vec!["profile", "list"], Some("one_profile_full")) } #[test] fn upgrade() -> Result { - let _ = remove_dir("./tests/mods"); - run_command(vec!["upgrade"], Some("one_profile_full"))?; - let _ = remove_dir("./tests/mods"); - run_command( - vec!["upgrade", "--no-patch-check"], - Some("one_profile_full"), - ) + let _ = remove_dir("./tests/mods"); + run_command(vec!["upgrade"], Some("one_profile_full")) } #[test] fn switch() -> Result { - // Switch to the fabric profile and check that it contains the mods added before - run_command( - vec!["switch", "--profile-name", "Profile Two"], - Some("two_profiles_one_empty"), - )?; - run_command(vec!["list"], Some("two_profiles_one_empty")) + // Switch to the fabric profile and check that it contains the mods added before + run_command( + vec!["switch", "--profile-name", "Profile Two"], + Some("two_profiles_one_empty"), + )?; + run_command(vec!["list"], Some("two_profiles_one_empty")) } #[test] fn remove_fail() { - // These should fail as one of the mod names provided does not exist - assert!(run_command( - vec![ - "remove", - "--mod-names", - "starlght", // Wrong - "--mod-names", - "terralith", - "--mod-names", - "sodium", - ], - Some("one_profile_full") - ) - .is_err()); - assert!(run_command( - vec![ - "remove", - "--mod-names", - "starlight (fabric)", - "--mod-names", - "terrlith", // Wrong - "--mod-names", - "sodium", - ], - Some("one_profile_full") - ) - .is_err()); - assert!(run_command( - vec![ - "remove", - "--mod-names", - "starlight (fabric)", - "--mod-names", - "terralith", - "--mod-names", - "sodum", // Wrong - ], - Some("one_profile_full") - ) - .is_err()); + // These should fail as one of the mod names provided does not exist + assert!(run_command( + vec![ + "remove", + "--mod-names", + "starlght", // Wrong + "--mod-names", + "terralith", + "--mod-names", + "sodium", + ], + Some("one_profile_full") + ) + .is_err()); + assert!(run_command( + vec![ + "remove", + "--mod-names", + "starlight (fabric)", + "--mod-names", + "terrlith", // Wrong + "--mod-names", + "sodium", + ], + Some("one_profile_full") + ) + .is_err()); + assert!(run_command( + vec![ + "remove", + "--mod-names", + "starlight (fabric)", + "--mod-names", + "terralith", + "--mod-names", + "sodum", // Wrong + ], + Some("one_profile_full") + ) + .is_err()); } #[test] fn remove_all() -> Result { - run_command( - vec![ - "remove", - "--mod-names", - "starlight (fabric)", - "--mod-names", - "terralith", - "--mod-names", - "sodium-fabric", - ], - Some("one_profile_full"), - ) + run_command( + vec![ + "remove", + "--mod-names", + "starlight (fabric)", + "--mod-names", + "terralith", + "--mod-names", + "sodium-fabric", + ], + Some("one_profile_full"), + ) } #[test] fn delete_profile() -> Result { - run_command( - vec!["profile", "delete", "--profile-name", "Profile Two"], - Some("two_profiles_one_empty"), - ) + run_command( + vec!["profile", "delete", "--profile-name", "Profile Two"], + Some("two_profiles_one_empty"), + ) } diff --git a/tests/util.rs b/tests/util.rs index 55256de..bb5a93f 100644 --- a/tests/util.rs +++ b/tests/util.rs @@ -4,31 +4,31 @@ use std::fs::{copy, create_dir}; use std::io::Result; pub fn run_command(args: Vec<&str>, config_file: Option<&str>) -> Result<()> { - let running = format!("./tests/configs/running/{}.json", rand::random::()); - if let Some(config_file) = config_file { - let _ = create_dir("./tests/configs/running"); - let template = format!("./tests/configs/{}.json", config_file); - copy(&template, &running)?; - } + let running = format!("./tests/configs/running/{}.json", rand::random::()); + if let Some(config_file) = config_file { + let _ = create_dir("./tests/configs/running"); + let template = format!("./tests/configs/{}.json", config_file); + copy(&template, &running)?; + } - let mut command = Command::new(env!("CARGO_BIN_EXE_ferium")); - command.args( - // Prepend the config file path to the arguments - // If none is given, provide a config file which doesn't exist - vec![vec!["--config-file", &running], args].concat(), - ); - let output = command.output()?; - if output.status.success() { - Ok(()) - } else { - Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!( - "Command returned with exit code {:?}, stdout:{}, stderr:{}", - output.status.code(), - std::str::from_utf8(&output.stdout).unwrap(), - std::str::from_utf8(&output.stderr).unwrap(), - ), - )) - } + let mut command = Command::new(env!("CARGO_BIN_EXE_ferium")); + command.args( + // Prepend the config file path to the arguments + // If none is given, provide a config file which doesn't exist + vec![vec!["--config-file", &running], args].concat(), + ); + let output = command.output()?; + if output.status.success() { + Ok(()) + } else { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!( + "Command returned with exit code {:?}, stdout:{}, stderr:{}", + output.status.code(), + std::str::from_utf8(&output.stdout).unwrap(), + std::str::from_utf8(&output.stderr).unwrap(), + ), + )) + } }