Analytics + more bug fixes (#144)

* Analytics + more bug fixes

* debug deadlock

* Fix mostly everything

* merge fixes

* fix rest

* final fixeS
This commit is contained in:
Geometrically
2023-06-19 14:59:06 -07:00
committed by GitHub
parent 84d731b670
commit 1e78a7b6a8
51 changed files with 1285 additions and 491 deletions

View File

@@ -12,7 +12,6 @@ build = "build.rs"
[build-dependencies]
tauri-build = { version = "1.3", features = [] }
regex = "1.5"
[dependencies]
theseus = { path = "../../theseus", features = ["tauri"] }
@@ -37,6 +36,9 @@ tracing = "0.1.37"
tracing-subscriber = "0.2"
tracing-error = "0.1"
sentry = "0.30"
sentry-rust-minidump = "0.5"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.24.1"
objc = "0.2.7"

View File

@@ -1,111 +1,4 @@
use std::fs;
use regex::Regex;
fn main() {
// Build the Tauri app
tauri_build::build();
// Check that all JavaScript 'invoke' Tauri functions have a corresponding tagged Rust function
// This is to prevent the app from crashing if a JavaScript function is invoked but the corresponding Rust function is not tagged
// This only allows simple functions, but functions in theseus_gui should be kept simple
check_invoke_sanity();
}
fn check_invoke_sanity() {
let js_files = read_js_files("../src/helpers");
let rust_files = read_rust_files("src");
let js_function_names = extract_js_function_names(&js_files);
let rust_function_names = extract_rust_function_names(&rust_files);
let mut missing_functions = Vec::new();
for js_fn_name in js_function_names {
if !rust_function_names.contains(&js_fn_name) {
missing_functions.push(js_fn_name);
}
}
if !missing_functions.is_empty() {
panic!(
"The following invoked Tauri functions do not have corresponding Rust functions with #[tauri::command] attribute :\n{}",
missing_functions.join("\n")
);
}
}
fn read_js_files(directory: &str) -> Vec<String> {
let mut files = Vec::new();
read_files_recursively(directory, "js", &mut files);
files
}
fn read_rust_files(directory: &str) -> Vec<String> {
let mut files = Vec::new();
read_files_recursively(directory, "rs", &mut files);
files
}
// Recursive in case we make the helpers directory more complex
fn read_files_recursively(
directory: &str,
extension: &str,
files: &mut Vec<String>,
) {
for entry in fs::read_dir(directory).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.is_dir() {
read_files_recursively(&path.to_string_lossy(), extension, files);
} else if path.extension().map_or(false, |ext| ext == extension) {
let content = fs::read_to_string(path).unwrap();
files.push(content);
}
}
}
fn extract_rust_function_names(rust_files: &[String]) -> Vec<String> {
// Matches #[tauri::command] attribute
let re_tauri_command = Regex::new(r"(?m)#\[tauri::command\]").unwrap();
// Matches function name following the #[tauri::command] attribute
// Matches up to the first (, to allow for function arguments and comments in that area
let re_function_name =
Regex::new(r"fn\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(").unwrap();
let mut function_names = Vec::new();
for file in rust_files {
let mut start = 0;
while let Some(command_match) = re_tauri_command.find_at(file, start) {
if let Some(function_name_cap) =
re_function_name.captures(&file[command_match.end()..])
{
function_names.push(function_name_cap[1].to_string());
start = command_match.start() + 1;
} else {
break;
}
}
}
function_names
}
fn extract_js_function_names(js_files: &[String]) -> Vec<String> {
// Matches functions of the form: invoke('function_name', { ... }) (or invoke('function_name') )
let re_invoke = Regex::new(
r"(?m)invoke\(\s*'([a-zA-Z_][a-zA-Z0-9_]*)'\s*(?:,\s*\{.*?\})?\s*\)",
)
.unwrap();
let mut function_names = Vec::new();
for file in js_files {
let mut start = 0;
while let Some(invoke_match) = re_invoke.find_at(file, start) {
if let Some(captures) = re_invoke.captures(invoke_match.as_str()) {
function_names.push(captures[1].to_string());
}
start = invoke_match.start() + 1;
}
}
function_names
}

View File

@@ -34,20 +34,11 @@ pub async fn logs_get_logs_by_datetime(
/// Get the stdout for a profile by profile id and datetime string
#[tauri::command]
pub async fn logs_get_stdout_by_datetime(
pub async fn logs_get_output_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
) -> Result<String> {
Ok(logs::get_stdout_by_datetime(profile_uuid, &datetime_string).await?)
}
/// Get the stderr for a profile by profile id and datetime string
#[tauri::command]
pub async fn logs_get_stderr_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
) -> Result<String> {
Ok(logs::get_stderr_by_datetime(profile_uuid, &datetime_string).await?)
Ok(logs::get_output_by_datetime(profile_uuid, &datetime_string).await?)
}
/// Delete all logs for a profile by profile id

View File

@@ -52,14 +52,8 @@ pub async fn process_get_all_running_profiles() -> Result<Vec<Profile>> {
// Gets process stderr by process UUID
#[tauri::command]
pub async fn process_get_stderr_by_uuid(uuid: Uuid) -> Result<String> {
Ok(process::get_stderr_by_uuid(&uuid).await?)
}
// Gets process stdout by process UUID
#[tauri::command]
pub async fn process_get_stdout_by_uuid(uuid: Uuid) -> Result<String> {
Ok(process::get_stdout_by_uuid(&uuid).await?)
pub async fn process_get_output_by_uuid(uuid: Uuid) -> Result<String> {
Ok(process::get_output_by_uuid(&uuid).await?)
}
// Kill a process by process UUID

View File

@@ -233,6 +233,7 @@ pub async fn profile_edit(
async { Ok(()) }
})
.await?;
State::sync().await?;
Ok(())
}

View File

@@ -21,6 +21,15 @@ async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
Ok(())
}
#[tauri::command]
fn is_dev() -> bool {
if cfg!(debug_assertions) {
true
} else {
false
}
}
use tracing_subscriber::prelude::*;
#[derive(Clone, serde::Serialize)]
@@ -30,6 +39,9 @@ struct Payload {
}
fn main() {
let client = sentry::init("https://19a14416dafc4b4a858fa1a38db3b704@o485889.ingest.sentry.io/4505349067374592");
let _guard = sentry_rust_minidump::init(&client);
/*
tracing is set basd on the environment variable RUST_LOG=xxx, depending on the amount of logs to show
ERROR > WARN > INFO > DEBUG > TRACE
@@ -83,6 +95,7 @@ fn main() {
builder = builder.invoke_handler(tauri::generate_handler![
initialize_state,
is_dev,
api::progress_bars_list,
api::profile_create::profile_create_empty,
api::profile_create::profile_create,
@@ -138,8 +151,7 @@ fn main() {
api::process::process_get_all_running_profiles,
api::process::process_get_exit_status_by_uuid,
api::process::process_has_finished_by_uuid,
api::process::process_get_stderr_by_uuid,
api::process::process_get_stdout_by_uuid,
api::process::process_get_output_by_uuid,
api::process::process_kill_by_uuid,
api::process::process_wait_for_by_uuid,
api::metadata::metadata_get_game_versions,
@@ -148,8 +160,7 @@ fn main() {
api::metadata::metadata_get_quilt_versions,
api::logs::logs_get_logs,
api::logs::logs_get_logs_by_datetime,
api::logs::logs_get_stdout_by_datetime,
api::logs::logs_get_stderr_by_datetime,
api::logs::logs_get_output_by_datetime,
api::logs::logs_delete_logs,
api::logs::logs_delete_logs_by_datetime,
api::utils::show_in_folder,
@@ -159,4 +170,9 @@ fn main() {
builder
.run(tauri::generate_context!())
.expect("error while running tauri application");
#[allow(deref_nullptr)]
unsafe {
*std::ptr::null_mut() = true;
}
}