From 30c4cb0e0cd3d9ac31199c4674aeb8253542ee5b Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 13 Mar 2026 11:10:55 -0700 Subject: [PATCH] add basic rayhunter_options endpoint --- Cargo.lock | 1 + installer-gui/src-tauri/Cargo.toml | 1 + installer-gui/src-tauri/src/introspect.rs | 54 +++++++++++++++++++++++ installer-gui/src-tauri/src/lib.rs | 13 ++++++ installer/src/lib.rs | 4 +- 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 installer-gui/src-tauri/src/introspect.rs diff --git a/Cargo.lock b/Cargo.lock index 9c829c3..655896a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2947,6 +2947,7 @@ name = "installer-gui" version = "0.11.2" dependencies = [ "anyhow", + "clap", "installer", "serde", "serde_json", diff --git a/installer-gui/src-tauri/Cargo.toml b/installer-gui/src-tauri/Cargo.toml index 26ce259..7742552 100644 --- a/installer-gui/src-tauri/Cargo.toml +++ b/installer-gui/src-tauri/Cargo.toml @@ -16,6 +16,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] +clap = { version = "4.5.37" } tauri = { version = "2", features = [] } tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } diff --git a/installer-gui/src-tauri/src/introspect.rs b/installer-gui/src-tauri/src/introspect.rs new file mode 100644 index 0000000..045d801 --- /dev/null +++ b/installer-gui/src-tauri/src/introspect.rs @@ -0,0 +1,54 @@ +use serde::Serialize; + +#[derive(Serialize, Debug)] +pub struct Command<'a> { + subcommands: Vec>, +} + +impl Command<'_> { + pub fn new(clap_command: &clap::Command) -> Command<'_> { + Command { + subcommands: clap_command + .get_subcommands() + // at least for now, we filter out subcommands that themselves have subcommands like + // "util" as supporting these would require additional changes to both the frontend + // and this module + .filter(|c| !c.has_subcommands()) + .map(|c| Subcommand::new(c)) + .collect(), + } + } +} + +#[derive(Serialize, Debug)] +struct Argument<'a> { + name: &'a str, + takes_values: bool, +} + +#[derive(Serialize, Debug)] +struct Subcommand<'a> { + arguments: Vec>, + name: &'a str, +} + +impl Argument<'_> { + fn new(clap_argument: &clap::Arg) -> Argument<'_> { + Argument { + name: clap_argument.get_id().as_str(), + takes_values: clap_argument.get_action().takes_values(), + } + } +} + +impl Subcommand<'_> { + fn new(clap_command: &clap::Command) -> Subcommand<'_> { + Subcommand { + arguments: clap_command + .get_arguments() + .map(|a| Argument::new(a)) + .collect(), + name: clap_command.get_name(), + } + } +} diff --git a/installer-gui/src-tauri/src/lib.rs b/installer-gui/src-tauri/src/lib.rs index da3da7b..355b45f 100644 --- a/installer-gui/src-tauri/src/lib.rs +++ b/installer-gui/src-tauri/src/lib.rs @@ -1,6 +1,13 @@ +use std::sync::LazyLock; + use anyhow::Context; +use clap::CommandFactory; use tauri::Emitter; +mod introspect; + +static INSTALLER_COMMAND: LazyLock = LazyLock::new(installer::Args::command); + async fn run_installer(app_handle: tauri::AppHandle, args: String) -> anyhow::Result<()> { let args_vec = shlex::split(&args).context("Failed to parse arguments: unclosed quote")?; tauri::async_runtime::spawn_blocking(move || { @@ -25,11 +32,17 @@ async fn install_rayhunter(app_handle: tauri::AppHandle, args: String) -> Result .map_err(|error| format!("{error:?}")) } +#[tauri::command] +fn rayhunter_options() -> introspect::Command<'static> { + introspect::Command::new(&INSTALLER_COMMAND) +} + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_opener::init()) .invoke_handler(tauri::generate_handler![install_rayhunter]) + .invoke_handler(tauri::generate_handler![rayhunter_options]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/installer/src/lib.rs b/installer/src/lib.rs index be64dcc..ce27db7 100644 --- a/installer/src/lib.rs +++ b/installer/src/lib.rs @@ -30,9 +30,11 @@ use crate::output::eprintln; static CONFIG_TOML: &str = include_str!("../../dist/config.toml.in"); static RAYHUNTER_DAEMON_INIT: &str = include_str!("../../dist/scripts/rayhunter_daemon"); +// We mark this as public so it can be used by installer-gui to programmatically introspect the +// installer's options. #[derive(Parser, Debug)] #[command(version, about)] -struct Args { +pub struct Args { #[command(subcommand)] command: Command, }