backend: pipe game and extractor logs to a file

This commit is contained in:
Tyler Wilding 2023-03-01 20:30:02 -05:00
parent 2df3776aa8
commit 53ffa9c034
No known key found for this signature in database
GPG key ID: 77CB07796494137E
3 changed files with 68 additions and 25 deletions

View file

@ -1,9 +1,10 @@
use std::io::{BufRead, BufReader};
use std::{ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
process::Command, process::Command,
}; };
use crate::config::LauncherConfig; use crate::{config::LauncherConfig, util::file::create_dir};
use super::CommandError; use super::CommandError;
@ -101,9 +102,35 @@ fn get_exec_location(
}) })
} }
fn create_log_file(
app_handle: &tauri::AppHandle,
name: &str,
append: bool,
) -> Result<std::fs::File, CommandError> {
let log_path = &match app_handle.path_resolver().app_log_dir() {
None => {
return Err(CommandError::Installation(format!(
"Could not determine path to save installation logs"
)))
}
Some(path) => path.clone(),
};
create_dir(&log_path)?;
let mut file_options = std::fs::OpenOptions::new();
file_options.create(true);
if append {
file_options.append(true);
} else {
file_options.write(true).truncate(true);
}
let file = file_options.open(log_path.join(name))?;
Ok(file)
}
#[tauri::command] #[tauri::command]
pub async fn extract_and_validate_iso( pub async fn extract_and_validate_iso(
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>, config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
app_handle: tauri::AppHandle,
path_to_iso: String, path_to_iso: String,
game_name: String, game_name: String,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
@ -123,18 +150,24 @@ pub async fn extract_and_validate_iso(
if Path::new(&path_to_iso.clone()).is_dir() { if Path::new(&path_to_iso.clone()).is_dir() {
args.push("--folder".to_string()); args.push("--folder".to_string());
} }
// TODO - tee logs and handle error codes
// This is the first install step, reset the file
let log_file = create_log_file(&app_handle, "extractor.log", false)?;
// TODO - exit codes
let output = Command::new(exec_info.executable_path) let output = Command::new(exec_info.executable_path)
.args(args) .args(args)
.current_dir(exec_info.executable_dir) .current_dir(exec_info.executable_dir)
.output() .stdout(log_file.try_clone().unwrap())
.expect("failed to execute process"); .stderr(log_file)
.output()?;
Ok(()) Ok(())
} }
#[tauri::command] #[tauri::command]
pub async fn run_decompiler( pub async fn run_decompiler(
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>, config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
app_handle: tauri::AppHandle,
path_to_iso: String, path_to_iso: String,
game_name: String, game_name: String,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
@ -153,7 +186,8 @@ pub async fn run_decompiler(
.to_string(); .to_string();
} }
// TODO - tee logs and handle error codes // TODO - handle error codes
let log_file = create_log_file(&app_handle, "extractor.log", true)?;
let output = Command::new(&exec_info.executable_path) let output = Command::new(&exec_info.executable_path)
.args([ .args([
source_path, source_path,
@ -161,15 +195,17 @@ pub async fn run_decompiler(
"--proj-path".to_string(), "--proj-path".to_string(),
data_folder.to_string_lossy().into_owned(), data_folder.to_string_lossy().into_owned(),
]) ])
.stdout(log_file.try_clone().unwrap())
.stderr(log_file)
.current_dir(exec_info.executable_dir) .current_dir(exec_info.executable_dir)
.output() .output()?;
.expect("failed to execute process");
Ok(()) Ok(())
} }
#[tauri::command] #[tauri::command]
pub async fn run_compiler( pub async fn run_compiler(
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>, config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
app_handle: tauri::AppHandle,
path_to_iso: String, path_to_iso: String,
game_name: String, game_name: String,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
@ -188,7 +224,8 @@ pub async fn run_compiler(
.to_string(); .to_string();
} }
// TODO - tee logs and handle error codes // TODO - handle error codes
let log_file = create_log_file(&app_handle, "extractor.log", true)?;
let output = Command::new(&exec_info.executable_path) let output = Command::new(&exec_info.executable_path)
.args([ .args([
source_path, source_path,
@ -196,9 +233,10 @@ pub async fn run_compiler(
"--proj-path".to_string(), "--proj-path".to_string(),
data_folder.to_string_lossy().into_owned(), data_folder.to_string_lossy().into_owned(),
]) ])
.stdout(log_file.try_clone().unwrap())
.stderr(log_file)
.current_dir(exec_info.executable_dir) .current_dir(exec_info.executable_dir)
.output() .output()?;
.expect("failed to execute process");
Ok(()) Ok(())
} }
@ -216,7 +254,7 @@ pub async fn open_repl(
let data_folder = get_data_dir(&config_info, &game_name)?; let data_folder = get_data_dir(&config_info, &game_name)?;
let exec_info = get_exec_location(&config_info, "goalc")?; let exec_info = get_exec_location(&config_info, "goalc")?;
// TODO - handle error // TODO - handle error codes
let output = Command::new("cmd") let output = Command::new("cmd")
.args([ .args([
"/K", "/K",
@ -226,14 +264,14 @@ pub async fn open_repl(
&data_folder.to_string_lossy().into_owned(), &data_folder.to_string_lossy().into_owned(),
]) ])
.current_dir(exec_info.executable_dir) .current_dir(exec_info.executable_dir)
.spawn() .spawn()?;
.expect("failed to execute process");
Ok(()) Ok(())
} }
#[tauri::command] #[tauri::command]
pub async fn launch_game( pub async fn launch_game(
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>, config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
app_handle: tauri::AppHandle,
game_name: String, game_name: String,
in_debug: bool, in_debug: bool,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
@ -250,11 +288,13 @@ pub async fn launch_game(
} }
args.push("-proj-path".to_string()); args.push("-proj-path".to_string());
args.push(data_folder.to_string_lossy().into_owned()); args.push(data_folder.to_string_lossy().into_owned());
// TODO - tee logs for SURE // TODO - handle error codes
let log_file = create_log_file(&app_handle, "game.log", false)?;
let output = Command::new(exec_info.executable_path) let output = Command::new(exec_info.executable_path)
.args(args) .args(args)
.stdout(log_file.try_clone().unwrap())
.stderr(log_file)
.current_dir(exec_info.executable_dir) .current_dir(exec_info.executable_dir)
.spawn() .spawn()?;
.expect("failed to execute process");
Ok(()) Ok(())
} }

View file

@ -3,7 +3,7 @@ use std::path::Path;
use crate::{ use crate::{
config::LauncherConfig, config::LauncherConfig,
util::{ util::{
file::{create_dir, delete_dir_or_folder}, file::{create_dir, delete_dir},
network::download_file, network::download_file,
os::open_dir_in_os, os::open_dir_in_os,
zip::extract_and_delete_zip_file, zip::extract_and_delete_zip_file,
@ -83,7 +83,7 @@ pub async fn download_version(
.join(&version); .join(&version);
// Delete the directory if it exists, and create it from scratch // Delete the directory if it exists, and create it from scratch
delete_dir_or_folder(&dest_dir).map_err(|_| { delete_dir(&dest_dir).map_err(|_| {
CommandError::VersionManagement(format!( CommandError::VersionManagement(format!(
"Unable to prepare destination folder '{}' for download", "Unable to prepare destination folder '{}' for download",
dest_dir.display() dest_dir.display()

View file

@ -1,12 +1,8 @@
use std::path::PathBuf; use std::path::PathBuf;
pub fn delete_dir_or_folder(path: &PathBuf) -> Result<(), std::io::Error> { pub fn delete_dir(path: &PathBuf) -> Result<(), std::io::Error> {
if path.exists() { if path.exists() && path.is_dir() {
if path.is_dir() {
std::fs::remove_dir_all(path)?; std::fs::remove_dir_all(path)?;
} else {
std::fs::remove_file(path)?;
}
} }
Ok(()) Ok(())
} }
@ -18,3 +14,10 @@ pub fn create_dir(path: &PathBuf) -> Result<(), std::io::Error> {
std::fs::create_dir_all(path)?; std::fs::create_dir_all(path)?;
Ok(()) Ok(())
} }
pub fn delete_file(path: &PathBuf) -> Result<(), std::io::Error> {
if path.exists() && path.is_file() {
std::fs::remove_file(path)?;
}
Ok(())
}