Skip to content

Commit

Permalink
feat(strict): Add strict and non strict matching
Browse files Browse the repository at this point in the history
Signed-off-by: dark0dave <dark0dave@mykolab.com>
  • Loading branch information
dark0dave committed Aug 14, 2024
1 parent 8d806c7 commit a236755
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 80 deletions.
2 changes: 1 addition & 1 deletion 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 = "mod_installer"
version = "6.0.3"
version = "8.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Options:
Timeout time per mod in seconds, default is 1 hour [env: TIMEOUT=] [default: 3600]
-u, --weidu-log-mode <WEIDU_LOG_MODE>
Weidu log setting "--autolog" is default [env: WEIDU_LOG_MODE=] [default: --autolog]
-x, --strict-matching
Strict Version and Component/SubComponent matching, default is false [env: STRICT_MATCHING=]
-h, --help
Print help
-V, --version
Expand Down
4 changes: 4 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ pub struct Args {
/// Weidu log setting "--autolog" is default
#[clap(env, long, short='u', default_value = "autolog", value_parser = parse_weidu_log_mode, required = false)]
pub weidu_log_mode: String,

/// Strict Version and Component/SubComponent matching, default is false
#[clap(env, long, short = 'x', action=ArgAction::SetFalse, default_value = "false")]
pub strict_matching: bool,
}

fn parse_weidu_log_mode(arg: &str) -> Result<String, String> {
Expand Down
48 changes: 47 additions & 1 deletion src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::error::Error;

// This should mirror the weidu component
// https://github.com/WeiDUorg/weidu/blob/devel/src/tp.ml#L98
#[derive(Debug, PartialEq, PartialOrd, Clone)]
#[derive(Debug, PartialOrd, Clone)]
pub(crate) struct Component {
pub(crate) tp_file: String,
pub(crate) name: String,
Expand All @@ -13,6 +13,24 @@ pub(crate) struct Component {
pub(crate) version: String,
}

impl PartialEq for Component {
fn eq(&self, other: &Self) -> bool {
self.tp_file == other.tp_file
&& self.name == other.name
&& self.lang == other.lang
&& self.component == other.component
}
}

impl Component {
pub(crate) fn strict_matching(&self, other: &Self) -> bool {
self.eq(other)
&& self.component_name == other.component_name
&& self.sub_component == other.sub_component
&& self.version == other.version
}
}

impl TryFrom<String> for Component {
type Error = Box<dyn Error>;

Expand Down Expand Up @@ -139,4 +157,32 @@ mod tests {
};
assert_eq!(mod_component, expected)
}

#[test]
fn test_strict_match() {
let non_strict_match_1 = Component {
tp_file: "TOBEX.TP2".to_string(),
name: "tobex".to_string(),
lang: "0".to_string(),
component: "100".to_string(),
component_name: "TobEx - Core".to_string(),
sub_component: "".to_string(),
version: "v28".to_string(),
};

let non_strict_match_2 = Component {
tp_file: "TOBEX.TP2".to_string(),
name: "tobex".to_string(),
lang: "0".to_string(),
component: "100".to_string(),
component_name: "TobEx - Core Chicken".to_string(),
sub_component: "".to_string(),
version: "v28".to_string(),
};
assert_eq!(non_strict_match_1, non_strict_match_2);
assert_eq!(
non_strict_match_1.strict_matching(&non_strict_match_2),
false
)
}
}
79 changes: 3 additions & 76 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{collections::HashMap, error::Error, path::PathBuf, process::ExitCode};
use std::{collections::HashMap, process::ExitCode};

use args::Args;
use clap::Parser;
use env_logger::Env;
use log_file::LogFile;
use utils::find_mods;

use crate::{
utils::{copy_mod_folder, mod_folder_present_in_game_directory, search_mod_folders},
Expand All @@ -18,33 +18,6 @@ mod utils;
mod weidu;
mod weidu_parser;

fn find_mods(
log_file: PathBuf,
skip_installed: bool,
game_directory: PathBuf,
) -> Result<LogFile, Box<dyn Error>> {
let mut mods = LogFile::try_from(log_file)?;
let number_of_mods_found = mods.len();
let mods_to_be_installed = if skip_installed {
let existing_weidu_log_file_path = game_directory.join("weidu").with_extension("log");
if let Ok(installed_mods) = LogFile::try_from(existing_weidu_log_file_path) {
for installed_mod in &installed_mods {
mods.retain(|mod_to_install| installed_mod != mod_to_install);
}
}
mods
} else {
mods
};

log::info!(
"Number of mods found: {}, Number of mods to be installed: {}",
number_of_mods_found,
mods_to_be_installed.len()
);
Ok(mods_to_be_installed)
}

fn main() -> ExitCode {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
log::info!(
Expand All @@ -61,6 +34,7 @@ fn main() -> ExitCode {
args.log_file,
args.skip_installed,
args.game_directory.clone(),
args.strict_matching,
) {
Ok(mods) => mods,
Err(err) => {
Expand Down Expand Up @@ -117,50 +91,3 @@ fn main() -> ExitCode {
}
ExitCode::SUCCESS
}

#[cfg(test)]
mod tests {
use super::*;
use component::Component;
use pretty_assertions::assert_eq;
use std::path::PathBuf;

#[test]
fn test_find_mods() {
let log_file = PathBuf::from("./fixtures/test.log");
let skip_installed = false;
let game_directory = PathBuf::from("./fixtures");
let result = find_mods(log_file.clone(), skip_installed, game_directory);
let expected = LogFile::try_from(log_file);
assert_eq!(expected.ok(), result.ok())
}

#[test]
fn test_find_mods_skip_installed() {
let log_file = PathBuf::from("./fixtures/test.log");
let skip_installed = true;
let game_directory = PathBuf::from("./fixtures");
let result = find_mods(log_file, skip_installed, game_directory).unwrap();
let expected = LogFile(vec![
Component {
tp_file: "TEST.TP2".to_string(),
name: "test_mod_name_1".to_string(),
lang: "0".to_string(),
component: "1".to_string(),
component_name: "test mod two".to_string(),
sub_component: "".to_string(),
version: "".to_string(),
},
Component {
tp_file: "END.TP2".to_string(),
name: "test_mod_name_3".to_string(),
lang: "0".to_string(),
component: "0".to_string(),
component_name: "test mod with version".to_string(),
sub_component: "".to_string(),
version: "1.02".to_string(),
},
]);
assert_eq!(expected, result)
}
}
74 changes: 73 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use core::time;
use fs_extra::dir::{copy, CopyOptions};
use std::{
error::Error,
path::{Path, PathBuf},
thread,
};
use walkdir::WalkDir;

use crate::component::Component;
use crate::{component::Component, log_file::LogFile};

pub fn mod_folder_present_in_game_directory(game_directory: &Path, mod_name: &str) -> bool {
game_directory.join(mod_name).is_dir()
Expand Down Expand Up @@ -63,6 +64,38 @@ fn find_mod_folder(mod_component: &Component, mod_dir: &Path, depth: usize) -> O
})
}

pub(crate) fn find_mods(
log_file: PathBuf,
skip_installed: bool,
game_directory: PathBuf,
strict_matching: bool,
) -> Result<LogFile, Box<dyn Error>> {
let mut mods = LogFile::try_from(log_file)?;
let number_of_mods_found = mods.len();
let mods_to_be_installed = if skip_installed {
let existing_weidu_log_file_path = game_directory.join("weidu").with_extension("log");
if let Ok(installed_mods) = LogFile::try_from(existing_weidu_log_file_path) {
for installed_mod in &installed_mods {
if strict_matching {
mods.retain(|mod_to_install| installed_mod.strict_matching(mod_to_install));
} else {
mods.retain(|mod_to_install| installed_mod != mod_to_install);
}
}
}
mods
} else {
mods
};

log::info!(
"Number of mods found: {}, Number of mods to be installed: {}",
number_of_mods_found,
mods_to_be_installed.len()
);
Ok(mods_to_be_installed)
}

pub fn sleep(millis: u64) {
let duration = time::Duration::from_millis(millis);
thread::sleep(duration);
Expand Down Expand Up @@ -90,4 +123,43 @@ mod tests {
Path::new(&format!("fixtures/mods/mod_a/{}", mod_component.name)).to_path_buf();
assert_eq!(mod_folder, Some(expected))
}

#[test]
fn test_find_mods() {
let log_file = PathBuf::from("./fixtures/test.log");
let skip_installed = false;
let game_directory = PathBuf::from("./fixtures");
let result = find_mods(log_file.clone(), skip_installed, game_directory, false);
let expected = LogFile::try_from(log_file);
assert_eq!(expected.ok(), result.ok())
}

#[test]
fn test_find_mods_skip_installed() {
let log_file = PathBuf::from("./fixtures/test.log");
let skip_installed = true;
let game_directory = PathBuf::from("./fixtures");
let result = find_mods(log_file, skip_installed, game_directory, false).unwrap();
let expected = LogFile(vec![
Component {
tp_file: "TEST.TP2".to_string(),
name: "test_mod_name_1".to_string(),
lang: "0".to_string(),
component: "1".to_string(),
component_name: "test mod two".to_string(),
sub_component: "".to_string(),
version: "".to_string(),
},
Component {
tp_file: "END.TP2".to_string(),
name: "test_mod_name_3".to_string(),
lang: "0".to_string(),
component: "0".to_string(),
component_name: "test mod with version".to_string(),
sub_component: "".to_string(),
version: "1.02".to_string(),
},
]);
assert_eq!(expected, result)
}
}

0 comments on commit a236755

Please sign in to comment.