diff --git a/lib/crates/fabro-cli/src/args.rs b/lib/crates/fabro-cli/src/args.rs index 32754b235..bd7a31606 100644 --- a/lib/crates/fabro-cli/src/args.rs +++ b/lib/crates/fabro-cli/src/args.rs @@ -1076,6 +1076,7 @@ impl Commands { Self::Server(ns) => match &ns.command { ServerCommand::Start(_) => "server start", ServerCommand::Stop(_) => "server stop", + ServerCommand::Restart(_) => "server restart", ServerCommand::Status(_) => "server status", ServerCommand::Serve(_) => "server __serve", }, @@ -1239,6 +1240,23 @@ pub(crate) struct ServerStatusArgs { pub(crate) json: bool, } +#[derive(Args)] +pub(crate) struct ServerRestartArgs { + #[command(flatten)] + pub(crate) storage_dir: StorageDirArgs, + + /// Seconds to wait for graceful shutdown before SIGKILL + #[arg(long, default_value = "10")] + pub(crate) timeout: u64, + + /// Run in the foreground instead of daemonizing + #[arg(long)] + pub(crate) foreground: bool, + + #[command(flatten)] + pub(crate) serve_args: ServeArgs, +} + #[derive(Args)] pub(crate) struct ServerServeArgs { #[command(flatten)] @@ -1258,6 +1276,8 @@ pub(crate) enum ServerCommand { Start(ServerStartArgs), /// Stop the HTTP API server Stop(ServerStopArgs), + /// Stop and restart the HTTP API server + Restart(ServerRestartArgs), /// Show server status Status(ServerStatusArgs), /// Internal: run the server process (spawned by `start`) diff --git a/lib/crates/fabro-cli/src/commands/server/mod.rs b/lib/crates/fabro-cli/src/commands/server/mod.rs index 7cece95ea..99ff7f04b 100644 --- a/lib/crates/fabro-cli/src/commands/server/mod.rs +++ b/lib/crates/fabro-cli/src/commands/server/mod.rs @@ -12,7 +12,8 @@ use fabro_util::printer::Printer; use fabro_util::terminal::Styles; use crate::args::{ - GlobalArgs, ServerCommand, ServerServeArgs, ServerStartArgs, ServerStatusArgs, ServerStopArgs, + GlobalArgs, ServerCommand, ServerRestartArgs, ServerServeArgs, ServerStartArgs, + ServerStatusArgs, ServerStopArgs, }; use crate::user_config; @@ -54,6 +55,31 @@ pub(crate) async fn dispatch( stop::execute(&storage_dir, Duration::from_secs(timeout), printer).await; Ok(()) } + ServerCommand::Restart(ServerRestartArgs { + storage_dir, + timeout, + foreground, + serve_args, + }) => { + let settings = user_config::load_settings_with_config_and_storage_dir( + serve_args.config.as_deref(), + storage_dir.as_deref(), + )?; + let storage_dir = user_config::storage_dir(&settings)?; + stop::stop_server(&storage_dir, Duration::from_secs(timeout)).await; + let bind_addr = + serve::resolve_bind_request_from_settings(&settings, serve_args.bind.as_deref())?; + let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr())); + Box::pin(start::execute( + bind_addr, + foreground, + serve_args, + storage_dir, + styles, + printer, + )) + .await + } ServerCommand::Status(ServerStatusArgs { storage_dir, json }) => { let settings = user_config::load_settings_with_storage_dir(storage_dir.as_deref())?; let storage_dir = user_config::storage_dir(&settings)?;