add basic rayhunter_options endpoint

This commit is contained in:
Brad Warren
2026-03-13 11:10:55 -07:00
committed by Will Greenberg
parent 17a9dfe0ff
commit 30c4cb0e0c
5 changed files with 72 additions and 1 deletions
Generated
+1
View File
@@ -2947,6 +2947,7 @@ name = "installer-gui"
version = "0.11.2"
dependencies = [
"anyhow",
"clap",
"installer",
"serde",
"serde_json",
+1
View File
@@ -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"] }
+54
View File
@@ -0,0 +1,54 @@
use serde::Serialize;
#[derive(Serialize, Debug)]
pub struct Command<'a> {
subcommands: Vec<Subcommand<'a>>,
}
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<Argument<'a>>,
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(),
}
}
}
+13
View File
@@ -1,6 +1,13 @@
use std::sync::LazyLock;
use anyhow::Context;
use clap::CommandFactory;
use tauri::Emitter;
mod introspect;
static INSTALLER_COMMAND: LazyLock<clap::Command> = 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");
}
+3 -1
View File
@@ -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,
}