diff options
Diffstat (limited to 'src/cli/server.rs')
| -rw-r--r-- | src/cli/server.rs | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/cli/server.rs b/src/cli/server.rs index 311cc31a..0102b2d4 100644 --- a/src/cli/server.rs +++ b/src/cli/server.rs @@ -1,4 +1,4 @@ -use crate::api::schema::{EmptyParams, Method, Request}; +use crate::api::schema::{EmptyParams, Method, Request, ServerLiveHandoffParams}; pub(super) fn run_server_command(args: &[String]) -> std::io::Result<Option<i32>> { let Some(subcommand) = args.first().map(|arg| arg.as_str()) else { @@ -7,6 +7,8 @@ pub(super) fn run_server_command(args: &[String]) -> std::io::Result<Option<i32> match subcommand { "stop" => server_stop(&args[1..]).map(Some), + "live-handoff" => server_live_handoff(&args[1..]).map(Some), + "--handoff-import" => Ok(None), "reload-config" => server_reload_config(&args[1..]).map(Some), "help" | "--help" | "-h" => { print_server_help(); @@ -40,9 +42,92 @@ fn server_reload_config(args: &[String]) -> std::io::Result<i32> { })?) } +fn server_live_handoff(args: &[String]) -> std::io::Result<i32> { + let Some(params) = parse_live_handoff_params(args) else { + eprintln!( + "usage: herdr server live-handoff [--import-exe <path>] [--expected-protocol <n>] [--expected-version <version>]" + ); + return Ok(2); + }; + + let response = super::send_request(&Request { + id: "cli:server:live-handoff".into(), + method: Method::ServerLiveHandoff(params), + })?; + if response.get("error").is_some() { + let rendered = serde_json::to_string(&response).unwrap_or_else(|err| { + format!( + "{{\"error\":{{\"code\":\"render_failed\",\"message\":\"failed to render error response: {err}\"}}}}" + ) + }); + eprintln!("{rendered}"); + return Ok(1); + } + + eprintln!( + "live handoff complete; server log: {}", + crate::session::data_dir() + .join("herdr-server.log") + .display() + ); + Ok(0) +} + +fn parse_live_handoff_params(args: &[String]) -> Option<ServerLiveHandoffParams> { + let mut params = ServerLiveHandoffParams::default(); + let mut idx = 0; + while idx < args.len() { + let arg = &args[idx]; + let (flag, value) = if let Some((flag, value)) = arg.split_once('=') { + (flag, Some(value.to_string())) + } else { + let value = args.get(idx + 1).cloned(); + idx += 1; + (arg.as_str(), value) + }; + let value = value?; + match flag { + "--import-exe" => params.import_exe = Some(value), + "--expected-protocol" => { + params.expected_protocol = Some(value.parse().ok()?); + } + "--expected-version" => params.expected_version = Some(value), + _ => return None, + } + idx += 1; + } + Some(params) +} + fn print_server_help() { eprintln!("herdr server commands:"); eprintln!(" herdr server run as headless server"); eprintln!(" herdr server stop stop the running server via the API socket"); + eprintln!(" herdr server live-handoff hand off live panes to a new local server"); eprintln!(" herdr server reload-config reload config.toml in the running server"); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn live_handoff_params_parse_remote_update_fields() { + let args = vec![ + "--import-exe".to_string(), + "/home/me/.local/bin/herdr".to_string(), + "--expected-protocol=9".to_string(), + "--expected-version".to_string(), + "0.6.2".to_string(), + ]; + + let params = parse_live_handoff_params(&args).expect("params"); + + assert_eq!( + params.import_exe.as_deref(), + Some("/home/me/.local/bin/herdr") + ); + assert_eq!(params.expected_protocol, Some(9)); + assert_eq!(params.expected_version.as_deref(), Some("0.6.2")); + } +} |
