improved activator
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use anyhow::Context;
|
||||
use log::{debug, trace};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::types::{Game, Link, ModdedInstance, RootConfig};
|
||||
use std::collections::HashMap;
|
||||
@@ -11,17 +11,22 @@ pub fn activate_instance(
|
||||
root_config: &RootConfig,
|
||||
instance: &ModdedInstance,
|
||||
target: impl AsRef<Path>,
|
||||
) -> anyhow::Result<()> {
|
||||
let game = root_config.game_by_id(instance.game_id()).unwrap();
|
||||
) -> Result<(), ActivationError> {
|
||||
let game = root_config
|
||||
.game_by_id(instance.game_id())
|
||||
.ok_or(ActivationError::GameNotFound)?;
|
||||
|
||||
check_target_valid(&target)?;
|
||||
|
||||
let resolved_links = resolve_links(root_config, instance, game)?;
|
||||
|
||||
resolved_links
|
||||
.iter()
|
||||
.try_for_each(|link| apply_link(link, &target))
|
||||
.with_context(|| "Creating links")?;
|
||||
create_plugins_txt(instance, target.as_ref()).with_context(|| "Creating Pluginx.txt")?;
|
||||
.map_err(ActivationError::Linking)?;
|
||||
create_plugins_txt(instance, target.as_ref()).map_err(ActivationError::PluginsTXT)?;
|
||||
|
||||
debug!("Finished activating instance");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -29,8 +34,10 @@ fn resolve_links(
|
||||
root_config: &RootConfig,
|
||||
instance: &ModdedInstance,
|
||||
game: &Game,
|
||||
) -> anyhow::Result<Vec<Link>> {
|
||||
let game_links = game.export_links()?;
|
||||
) -> Result<Vec<Link>, ActivationError> {
|
||||
let game_links = game
|
||||
.export_links()
|
||||
.map_err(ActivationError::ExportGameLinks)?;
|
||||
let mod_links = resolve_link_for_instance(root_config, instance)?;
|
||||
let overrides: Vec<Link> = instance.game_file_overrides().to_owned();
|
||||
|
||||
@@ -51,11 +58,15 @@ fn resolve_links(
|
||||
fn resolve_link_for_instance(
|
||||
root_config: &RootConfig,
|
||||
instance: &ModdedInstance,
|
||||
) -> anyhow::Result<Vec<Link>> {
|
||||
) -> Result<Vec<Link>, ActivationError> {
|
||||
debug!("Resolving links for instance");
|
||||
|
||||
let mut links: Vec<Link> = Vec::new();
|
||||
|
||||
for installed_mod in instance.mods() {
|
||||
let mod_config = root_config.get_mod_by_id(installed_mod.mod_id()).unwrap();
|
||||
let mod_config = root_config
|
||||
.get_mod_by_id(installed_mod.mod_id())
|
||||
.ok_or(ActivationError::ModNotFound)?;
|
||||
let mod_source_root = root_config.mod_location().join(mod_config.path());
|
||||
|
||||
for link in installed_mod.files() {
|
||||
@@ -78,8 +89,8 @@ fn create_plugins_txt(
|
||||
instance: &ModdedInstance,
|
||||
target: impl AsRef<Path>,
|
||||
) -> Result<(), io::Error> {
|
||||
debug!("Generating plugins.txt");
|
||||
let mut file = fs::File::create(target.as_ref().join("plugins.txt"))?;
|
||||
debug!("Generating Plugins.txt");
|
||||
let mut file = fs::File::create(target.as_ref().join("Plugins.txt"))?;
|
||||
|
||||
writeln!(file, "# Auto generated. DO NOT EDIT MANUALLY!")?;
|
||||
|
||||
@@ -93,6 +104,7 @@ fn create_plugins_txt(
|
||||
fn link_file(target: &Path, link_name: &Path) -> Result<(), io::Error> {
|
||||
if let Some(parent) = link_name.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
trace!("Creating parent dir for {}", link_name.to_string_lossy());
|
||||
}
|
||||
|
||||
create_symlink_for_file(target, link_name)?;
|
||||
@@ -116,3 +128,44 @@ fn create_symlink_for_file(target: &Path, link_name: &Path) -> io::Result<()> {
|
||||
std::os::windows::fs::symlink_file(target, link_name)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_target_valid(target: impl AsRef<Path>) -> Result<(), ActivationError> {
|
||||
match fs::read_dir(&target) {
|
||||
Ok(entries) => {
|
||||
if entries.count() == 0 {
|
||||
debug!(
|
||||
"Target {} is a valid target",
|
||||
&target.as_ref().to_string_lossy()
|
||||
);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ActivationError::TargetNotEmpty)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(ActivationError::TargetNotValid(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ActivationError {
|
||||
#[error("Could not find game in instance config")]
|
||||
GameNotFound,
|
||||
|
||||
#[error("Could not find mod in instance config")]
|
||||
ModNotFound,
|
||||
|
||||
#[error("The target is not empty")]
|
||||
TargetNotEmpty,
|
||||
|
||||
#[error("The target is not valid")]
|
||||
TargetNotValid(io::Error),
|
||||
|
||||
#[error("Failed to create symlink")]
|
||||
Linking(io::Error),
|
||||
|
||||
#[error("Failed to create Plugins.txt")]
|
||||
PluginsTXT(io::Error),
|
||||
|
||||
#[error("Failed to export files in game installation")]
|
||||
ExportGameLinks(io::Error),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user