Update files
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use base64::{engine::general_purpose::STANDARD as BASE64_STANDARD, Engine as _};
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -14,11 +13,11 @@ use tauri_plugin_updater::UpdaterExt;
|
||||
|
||||
mod runtime_manager;
|
||||
use runtime_manager::{
|
||||
cli_shim_status, close_local_daemon_transport, install_cli_shim, managed_daemon_logs,
|
||||
cli_symlink_instructions, close_local_daemon_transport, managed_daemon_logs,
|
||||
managed_daemon_pairing, managed_daemon_status, managed_runtime_status,
|
||||
open_local_daemon_transport, restart_managed_daemon, send_local_daemon_transport_message,
|
||||
start_managed_daemon, stop_managed_daemon, uninstall_cli_shim,
|
||||
update_managed_daemon_tcp_settings, LocalTransportState, ManagedTcpSettings,
|
||||
open_local_daemon_transport, restart_managed_daemon, run_managed_cli_from_current_process,
|
||||
send_local_daemon_transport_message, start_managed_daemon, stop_managed_daemon,
|
||||
update_managed_daemon_tcp_settings, LocalTransportState,
|
||||
};
|
||||
|
||||
// Store zoom as u64 bits (f64 * 100 as integer for atomic ops)
|
||||
@@ -74,145 +73,32 @@ struct AttachmentFileResult {
|
||||
byte_size: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ManagedHeadlessCommand {
|
||||
RuntimeStatus,
|
||||
Bootstrap,
|
||||
DaemonStatus,
|
||||
StopDaemon,
|
||||
InstallCliShim,
|
||||
UninstallCliShim,
|
||||
UpdateTcp(ManagedTcpSettings),
|
||||
fn is_ignored_gui_launch_arg(arg: &str) -> bool {
|
||||
arg.starts_with("-psn_")
|
||||
}
|
||||
|
||||
fn parse_managed_headless_command() -> Result<Option<ManagedHeadlessCommand>, String> {
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let Some(flag_index) = args.iter().position(|value| value == "--managed-headless") else {
|
||||
return Ok(None);
|
||||
};
|
||||
let command = args
|
||||
.get(flag_index + 1)
|
||||
.ok_or_else(|| "Missing command after --managed-headless".to_string())?;
|
||||
let tail = args
|
||||
fn parse_cli_passthrough_args_from_argv(args: &[String]) -> Option<Vec<String>> {
|
||||
let effective = args
|
||||
.iter()
|
||||
.skip(flag_index + 2)
|
||||
.skip(1)
|
||||
.filter(|arg| !is_ignored_gui_launch_arg(arg))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
match command.as_str() {
|
||||
"runtime-status" => Ok(Some(ManagedHeadlessCommand::RuntimeStatus)),
|
||||
"bootstrap" => Ok(Some(ManagedHeadlessCommand::Bootstrap)),
|
||||
"daemon-status" => Ok(Some(ManagedHeadlessCommand::DaemonStatus)),
|
||||
"stop-daemon" => Ok(Some(ManagedHeadlessCommand::StopDaemon)),
|
||||
"install-cli-shim" => Ok(Some(ManagedHeadlessCommand::InstallCliShim)),
|
||||
"uninstall-cli-shim" => Ok(Some(ManagedHeadlessCommand::UninstallCliShim)),
|
||||
"update-tcp" => {
|
||||
let mut enabled = false;
|
||||
let mut host = "127.0.0.1".to_string();
|
||||
let mut port = 7771_u16;
|
||||
let mut index = 0_usize;
|
||||
while index < tail.len() {
|
||||
match tail[index].as_str() {
|
||||
"--enabled" => {
|
||||
enabled = tail
|
||||
.get(index + 1)
|
||||
.ok_or_else(|| "Missing value after --enabled".to_string())?
|
||||
.parse::<bool>()
|
||||
.map_err(|error| format!("Invalid --enabled value: {error}"))?;
|
||||
index += 2;
|
||||
}
|
||||
"--host" => {
|
||||
host = tail
|
||||
.get(index + 1)
|
||||
.ok_or_else(|| "Missing value after --host".to_string())?
|
||||
.to_string();
|
||||
index += 2;
|
||||
}
|
||||
"--port" => {
|
||||
port = tail
|
||||
.get(index + 1)
|
||||
.ok_or_else(|| "Missing value after --port".to_string())?
|
||||
.parse::<u16>()
|
||||
.map_err(|error| format!("Invalid --port value: {error}"))?;
|
||||
index += 2;
|
||||
}
|
||||
other => {
|
||||
return Err(format!(
|
||||
"Unknown --managed-headless update-tcp option: {other}"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Some(ManagedHeadlessCommand::UpdateTcp(
|
||||
ManagedTcpSettings {
|
||||
enabled,
|
||||
host,
|
||||
port,
|
||||
},
|
||||
)))
|
||||
}
|
||||
other => Err(format!("Unknown --managed-headless command: {other}")),
|
||||
}
|
||||
(!effective.is_empty()).then_some(effective)
|
||||
}
|
||||
|
||||
fn maybe_run_managed_headless_command(app: &AppHandle) -> Result<bool, String> {
|
||||
let Some(command) = parse_managed_headless_command()? else {
|
||||
return Ok(false);
|
||||
pub fn try_run_pre_tauri_mode() -> Option<i32> {
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let Some(cli_args) = parse_cli_passthrough_args_from_argv(&args) else {
|
||||
return None;
|
||||
};
|
||||
log::info!("[headless] running managed headless command: {:?}", command);
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.hide();
|
||||
}
|
||||
let app_handle = app.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let result = async {
|
||||
let payload = match command {
|
||||
ManagedHeadlessCommand::RuntimeStatus => {
|
||||
json!(managed_runtime_status(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::Bootstrap => {
|
||||
json!(start_managed_daemon(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::DaemonStatus => {
|
||||
json!(managed_daemon_status(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::StopDaemon => {
|
||||
json!(stop_managed_daemon(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::InstallCliShim => {
|
||||
json!(install_cli_shim(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::UninstallCliShim => {
|
||||
json!(uninstall_cli_shim(app_handle.clone()).await?)
|
||||
}
|
||||
ManagedHeadlessCommand::UpdateTcp(settings) => {
|
||||
json!(update_managed_daemon_tcp_settings(app_handle.clone(), settings).await?)
|
||||
}
|
||||
};
|
||||
Ok::<serde_json::Value, String>(payload)
|
||||
}
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(payload) => {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&payload)
|
||||
.unwrap_or_else(|error| format!(r#"{{"error":"{error}"}}"#))
|
||||
);
|
||||
app_handle.exit(0);
|
||||
}
|
||||
Err(error) => {
|
||||
eprintln!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({ "error": error })).unwrap_or_else(|_| {
|
||||
r#"{"error":"managed headless command failed"}"#.to_string()
|
||||
})
|
||||
);
|
||||
app_handle.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(true)
|
||||
Some(
|
||||
run_managed_cli_from_current_process(cli_args).unwrap_or_else(|error| {
|
||||
eprintln!("{error}");
|
||||
1
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn shell_command(script: &str) -> Command {
|
||||
@@ -622,14 +508,12 @@ pub fn run() {
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
managed_runtime_status,
|
||||
managed_daemon_status,
|
||||
cli_shim_status,
|
||||
cli_symlink_instructions,
|
||||
start_managed_daemon,
|
||||
stop_managed_daemon,
|
||||
restart_managed_daemon,
|
||||
managed_daemon_logs,
|
||||
managed_daemon_pairing,
|
||||
install_cli_shim,
|
||||
uninstall_cli_shim,
|
||||
update_managed_daemon_tcp_settings,
|
||||
open_local_daemon_transport,
|
||||
send_local_daemon_transport_message,
|
||||
@@ -650,10 +534,6 @@ pub fn run() {
|
||||
app.package_info().version
|
||||
);
|
||||
|
||||
if maybe_run_managed_headless_command(app.handle())? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
@@ -780,3 +660,38 @@ pub fn run() {
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_cli_passthrough_args_from_argv;
|
||||
|
||||
#[test]
|
||||
fn routes_meaningful_args_to_cli_mode() {
|
||||
let args = vec![
|
||||
"/Applications/Paseo.app/Contents/MacOS/Paseo".to_string(),
|
||||
"--version".to_string(),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
parse_cli_passthrough_args_from_argv(&args),
|
||||
Some(vec!["--version".to_string()])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignores_plain_gui_launch() {
|
||||
let args = vec!["/Applications/Paseo.app/Contents/MacOS/Paseo".to_string()];
|
||||
|
||||
assert_eq!(parse_cli_passthrough_args_from_argv(&args), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignores_macos_process_serial_number_argument() {
|
||||
let args = vec![
|
||||
"/Applications/Paseo.app/Contents/MacOS/Paseo".to_string(),
|
||||
"-psn_0_12345".to_string(),
|
||||
];
|
||||
|
||||
assert_eq!(parse_cli_passthrough_args_from_argv(&args), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user