diff --git a/src/error.rs b/src/error.rs index 12f2d6e..7a07642 100644 --- a/src/error.rs +++ b/src/error.rs @@ -175,12 +175,31 @@ pub enum BeansError old_location: String, old_content: String }, + #[error("Failed to serialize JSON {instance:?} to location {location} ({error:})")] + VersionFileSerializeFailure + { + error: serde_json::Error, + instance: AdastralVersionFile, + location: String + }, #[error("Failed to read version file at {location}. ({error:})")] VersionFileReadFailure { error: std::io::Error, location: String }, + #[error("Failed to open version file at {location}. ({error:})")] + VersionFileOpenFailure + { + error: std::io::Error, + location: String + }, + #[error("Failed to write version file at {location}. ({error:})")] + VersionFileWriteFailure + { + error: std::io::Error, + location: String + }, #[error("Failed to serialize provided AppVarData to JSON. ({error:})")] AppVarDataSerializeFailure diff --git a/src/version.rs b/src/version.rs index 9aae6e3..1c06981 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,7 +1,9 @@ use std::{backtrace::Backtrace, collections::HashMap, - fs::read_to_string, - io::Write}; + fs::{read_to_string, + File}, + io::{BufWriter, + Write}}; use log::{debug, error, @@ -42,6 +44,69 @@ pub fn get_current_version(sourcemods_location: Option) -> Option } } +/// set the version in the `.adastral` file in the sourcemod folder. +/// will silently fail when install_state is not InstallType::Adastral, or the +/// sourcemod isn't installed. +pub fn set_current_version( + sourcemods_location: Option, + new_version: usize +) -> Result<(), BeansError> +{ + let install_state = helper::install_state(sourcemods_location.clone()); + if install_state != InstallType::Adastral + { + return Ok(()); + } + match get_mod_location(sourcemods_location) + { + Some(smp_x) => + { + // TODO generate BeansError instead of using panic + let location = format!("{}.adastral", smp_x); + let file = match helper::file_exists(location.clone()) + { + false => match File::create(&location) + { + Ok(v) => v, + Err(e) => + { + return Err(BeansError::VersionFileWriteFailure { + location: location.clone(), + error: e + }); + } + }, + true => match File::open(&location) + { + Ok(v) => v, + Err(e) => + { + return Err(BeansError::VersionFileOpenFailure { + location: location.clone(), + error: e + }); + } + } + }; + let data = AdastralVersionFile { + version: format!("{new_version}") + }; + debug!("[set_current_version] location: {location:}, content: {data:?}"); + let mut writer = BufWriter::new(file); + match serde_json::to_writer(&mut writer, &data) + { + Ok(_) => Ok(()), + Err(e) => Err(BeansError::VersionFileSerializeFailure { + location: location.clone(), + instance: data.clone(), + error: e + }) + } + } + None => Ok(()) // silently fail + } +} + fn get_version_location(sourcemods_location: Option) -> Option { get_mod_location(sourcemods_location).map(|v| format!("{}.adastral", v)) diff --git a/src/workflows/update.rs b/src/workflows/update.rs index d22be92..2ed7c83 100644 --- a/src/workflows/update.rs +++ b/src/workflows/update.rs @@ -5,7 +5,8 @@ use crate::{BeansError, RunnerContext, appvar::AppVarData, butler, - helper}; + helper, + version}; pub struct UpdateWorkflow { @@ -30,6 +31,7 @@ impl UpdateWorkflow }; let remote_version = ctx.current_remote_version()?; + let (remote_version_ident, _) = ctx.latest_remote_version(); ctx.prepare_symlink()?; let patch = match ctx.has_patch_available() @@ -112,6 +114,9 @@ impl UpdateWorkflow return Err(e); } + info!("[UpdateWorkflow] Updating version file (.adastral)"); + version::set_current_version(Some(ctx.sourcemod_path.clone()), remote_version_ident)?; + ctx.gameinfo_perms()?; Self::post_update_msg();