diff --git a/src/actions.rs b/src/actions.rs index c8cb2ea..7b089a2 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -7,5 +7,5 @@ mod load_order; pub use activate::{ActivationError, activate_instance}; pub use download::handle_nxm; pub use include::insert_mod_to_instance; -pub use install::resolve_files_for_install; +pub use install::{resolve_files_for_install, ResolveFileResult}; pub use load_order::{LoadOrderError, create_loadorder}; diff --git a/src/actions/install.rs b/src/actions/install.rs index ede7586..223fdac 100644 --- a/src/actions/install.rs +++ b/src/actions/install.rs @@ -4,30 +4,34 @@ use std::{ }; use globset::{Glob, GlobSet, GlobSetBuilder}; -use log::{debug, trace}; use crate::{ - fomod, install_prompt, - mod_config_installer::FomodInstaller, - types::{ModConfig, ModFile, ModdedInstance, RootConfig}, + fomod, + types::{ModConfig, ModFile, RootConfig}, utils::{resolve_case_insensitive, walk_all_files}, }; pub fn resolve_files_for_install( root_config: &RootConfig, - instance: &ModdedInstance, mod_to_install: &ModConfig, -) -> anyhow::Result> { +) -> anyhow::Result { let mod_location = root_config.mod_location().join(mod_to_install.path()); - let files = match determain_mod_kind(mod_to_install, &mod_location)? { - ModKind::Fomod(xml_path) => install_fomod(instance, xml_path, &mod_location)?, - ModKind::EmbeddedData(_data_path) => install_from_dir(mod_to_install, mod_location)?, - ModKind::Root => install_root(mod_to_install, mod_location)?, - ModKind::Unkown => install_from_dir_to_data(mod_to_install, mod_location)?, + let result = match determain_mod_kind(mod_to_install, &mod_location)? { + ModKind::Fomod(xml_path) => { + let module_config = fomod::Config::load_from_file(xml_path)?; + ResolveFileResult::Fomod(module_config) + } + ModKind::EmbeddedData(_data_path) => { + ResolveFileResult::Files(install_from_dir(mod_to_install, mod_location)?) + } + ModKind::Root => ResolveFileResult::Files(install_root(mod_to_install, mod_location)?), + ModKind::Unkown => { + ResolveFileResult::Files(install_from_dir_to_data(mod_to_install, mod_location)?) + } }; - Ok(files) + Ok(result) } fn determain_mod_kind( @@ -51,38 +55,38 @@ fn determain_mod_kind( } } -fn install_fomod( - instance: &ModdedInstance, - module_config_path: impl AsRef, - mod_root: impl AsRef, -) -> anyhow::Result> { - debug!("Running FOmod installer"); - let module_config = fomod::Config::load_from_file(module_config_path)?; - - let active_plugins: Vec<_> = instance - .active_plugins() - .map(|e| e.to_string_lossy()) - .map(|e| e.to_string()) - .collect(); - - trace!("Current loded plugins: {:?}", active_plugins); - - let mut installer = FomodInstaller::new(&module_config, &active_plugins); - let mut selection: Option> = None; - while let Some(prompt) = installer.run_step(selection.as_deref()) { - selection = Some(install_prompt::prompt(prompt)); - } - let files = installer.finalize(); - - let mod_files: Vec<_> = files - .iter() - .map(|f| ModFile::from_installer(f.clone(), &mod_root)) - .collect::, _>>()? - .into_iter() - .flatten() - .collect(); - Ok(mod_files) -} +// fn install_fomod( +// instance: &ModdedInstance, +// module_config_path: impl AsRef, +// mod_root: impl AsRef, +// ) -> anyhow::Result> { +// debug!("Running FOmod installer"); +// let module_config = fomod::Config::load_from_file(module_config_path)?; +// +// let active_plugins: Vec<_> = instance +// .active_plugins() +// .map(|e| e.to_string_lossy()) +// .map(|e| e.to_string()) +// .collect(); +// +// trace!("Current loded plugins: {:?}", active_plugins); +// +// let mut installer = FomodInstaller::new(&module_config, &active_plugins); +// let mut selection: Option> = None; +// while let Some(prompt) = installer.run_step(selection.as_deref()) { +// selection = Some(install_prompt::prompt(prompt)); +// } +// let files = installer.finalize(); +// +// let mod_files: Vec<_> = files +// .iter() +// .map(|f| ModFile::from_installer(f.clone(), &mod_root)) +// .collect::, _>>()? +// .into_iter() +// .flatten() +// .collect(); +// Ok(mod_files) +// } fn install_from_dir( mod_config: &ModConfig, @@ -149,6 +153,11 @@ enum ModKind { Unkown, } +pub enum ResolveFileResult { + Files(Vec), + Fomod(fomod::Config), +} + fn should_be_included(path: impl AsRef) -> bool { matches!( path.as_ref().extension().and_then(|e| e.to_str()), diff --git a/src/main.rs b/src/main.rs index 8c3dff1..6c32022 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,14 @@ use std::{error::Error, path::Path}; use fomod_manager::{ actions::{ - activate_instance, create_loadorder, handle_nxm, insert_mod_to_instance, + ResolveFileResult, activate_instance, create_loadorder, handle_nxm, insert_mod_to_instance, resolve_files_for_install, - }, cli::{self, Args}, nexus::NexusAPI, tui, types::RootConfig + }, + cli::{self, Args}, + mod_config_installer::FomodInstaller, + nexus::NexusAPI, + tui, + types::RootConfig, }; fn command_activate( @@ -26,7 +31,19 @@ fn command_add(root_config: &RootConfig, instance_id: &str, mod_id: &str) -> any .mod_by_id(mod_id) .ok_or(anyhow!("Can't find mod in config"))?; - let files = resolve_files_for_install(root_config, &instance, &mod_to_install)?; + let files = match resolve_files_for_install(root_config, &mod_to_install)? { + ResolveFileResult::Files(mod_files) => mod_files, + ResolveFileResult::Fomod(module_config) => { + let mod_location = root_config.mod_location().join(mod_to_install.path()); + let active_plugins: Vec = instance.active_plugins().collect(); + let mut installer = FomodInstaller::new(&module_config, &active_plugins); + let mut selection: Option> = None; + while let Some(prompt) = installer.run_step(selection.as_deref()) { + selection = Some(fomod_manager::install_prompt::prompt(prompt)); + } + installer.finalize(mod_location)? + } + }; match insert_mod_to_instance(&mut instance, &mod_to_install, &files, 0) { None => { @@ -101,7 +118,7 @@ fn main() -> Result<(), Box> { } cli::Commands::Tui => { tui::run(&mut root_config)?; - }, + } } Ok(()) diff --git a/src/mod_config_installer.rs b/src/mod_config_installer.rs index ec1af4f..f0bd99e 100644 --- a/src/mod_config_installer.rs +++ b/src/mod_config_installer.rs @@ -1,10 +1,13 @@ -use std::{collections::HashMap, fmt::Display}; +use std::{collections::HashMap, fmt::Display, io, path::Path}; use log::{debug, warn}; -use crate::fomod::{ - CompositeDependency, Config, DependencyOperator, DependencyState, FileList, FileTypeEnum, - Group, GroupType, ModuleDependency, Plugin, PluginTypeDescriptorEnum, PluginTypeEnum, +use crate::{ + fomod::{ + CompositeDependency, Config, DependencyOperator, DependencyState, FileList, FileTypeEnum, + Group, GroupType, ModuleDependency, Plugin, PluginTypeDescriptorEnum, PluginTypeEnum, + }, + types::ModFile, }; #[derive(Debug)] @@ -117,6 +120,7 @@ fn evaluate_module_depbendecy( } } +#[derive(Debug)] pub struct GroupPrompt { pub name: String, pub select_type: GroupType, @@ -146,6 +150,7 @@ impl GroupPrompt { } } +#[derive(Debug)] pub struct InstallOption { pub name: String, pub option_type: PluginTypeEnum, @@ -264,7 +269,17 @@ impl<'a> FomodInstaller<'a> { } } - pub fn finalize(self) -> Vec { - self.state.into_file_list() + pub fn finalize(self, mod_root: impl AsRef) -> Result, io::Error> { + let files: Vec<_> = self + .state + .into_file_list() + .iter() + .map(|f| ModFile::from_installer(f.clone(), &mod_root)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); + + Ok(files) } } diff --git a/src/types/modded_instance.rs b/src/types/modded_instance.rs index 7207c11..5566aed 100644 --- a/src/types/modded_instance.rs +++ b/src/types/modded_instance.rs @@ -1,5 +1,4 @@ use std::{ - ffi::OsStr, fs::{self, read_to_string}, io::Write, path::{Path, PathBuf}, @@ -106,8 +105,12 @@ impl ModdedInstance { &self.mods } - pub fn active_plugins(&self) -> impl Iterator { - self.mods.iter().flat_map(|e| e.active_plugins()) + pub fn active_plugins(&self) -> impl Iterator { + self.mods + .iter() + .flat_map(|e| e.active_plugins()) + .map(|e| e.to_string_lossy()) + .map(|e| e.to_string()) } } @@ -156,6 +159,5 @@ mod tests { let new_mod = InstalledMod::new("mod1", 1); cfg.update_or_create_mod(&new_mod); - } } diff --git a/tests/add_mod_test.rs b/tests/add_mod_test.rs index c380dbb..f10f809 100644 --- a/tests/add_mod_test.rs +++ b/tests/add_mod_test.rs @@ -20,7 +20,12 @@ fn add_plain() -> Result<(), Box> { let mod_to_install = root_config .mod_by_id("add_test_plain") .expect("Mod not found"); - let files_to_add = resolve_files_for_install(&root_config, &instance, &mod_to_install)?; + let files_to_add = match resolve_files_for_install(&root_config, &mod_to_install)? { + fomod_manager::actions::ResolveFileResult::Files(mod_files) => mod_files, + _ => { + panic!("Resolved files have wrong type"); + } + }; insert_mod_to_instance(&mut instance, &mod_to_install, &files_to_add, 0); @@ -53,7 +58,12 @@ fn add_nested() -> Result<(), Box> { let mod_to_install = root_config .mod_by_id("add_test_nested") .expect("Mod not found"); - let files_to_add = resolve_files_for_install(&root_config, &instance, &mod_to_install)?; + let files_to_add = match resolve_files_for_install(&root_config, &mod_to_install)? { + fomod_manager::actions::ResolveFileResult::Files(mod_files) => mod_files, + _ => { + panic!("Resolved files have wrong type"); + } + }; insert_mod_to_instance(&mut instance, &mod_to_install, &files_to_add, 0); @@ -86,7 +96,12 @@ fn add_root() -> Result<(), Box> { let mod_to_install = root_config .mod_by_id("add_test_root") .expect("Mod not found"); - let files_to_add = resolve_files_for_install(&root_config, &instance, &mod_to_install)?; + let files_to_add = match resolve_files_for_install(&root_config, &mod_to_install)? { + fomod_manager::actions::ResolveFileResult::Files(mod_files) => mod_files, + _ => { + panic!("Resolved files have wrong type"); + } + }; insert_mod_to_instance(&mut instance, &mod_to_install, &files_to_add, 0); @@ -117,7 +132,12 @@ fn add_filter() -> Result<(), Box> { let mod_to_install = root_config .mod_by_id("add_test_filter") .expect("Mod not found"); - let files_to_add = resolve_files_for_install(&root_config, &instance, &mod_to_install)?; + let files_to_add = match resolve_files_for_install(&root_config, &mod_to_install)? { + fomod_manager::actions::ResolveFileResult::Files(mod_files) => mod_files, + _ => { + panic!("Resolved files have wrong type"); + } + }; insert_mod_to_instance(&mut instance, &mod_to_install, &files_to_add, 0);