From be87774a3b24fbac0dbd3c697dbe0fa7e117400c Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Sat, 31 Aug 2024 20:51:26 -0700 Subject: [PATCH] set up structure for multiple cli commands The previous cli is now behind the 'serve' subcommand. --- nix/modules/default/default.nix | 2 +- src/args.rs | 35 ---------------------- src/cli.rs | 51 +++++++++++++++++++++++++++++++++ src/main.rs | 11 +++++-- 4 files changed, 60 insertions(+), 39 deletions(-) delete mode 100644 src/args.rs create mode 100644 src/cli.rs diff --git a/nix/modules/default/default.nix b/nix/modules/default/default.nix index d6d8ac65..3bc86c56 100644 --- a/nix/modules/default/default.nix +++ b/nix/modules/default/default.nix @@ -79,7 +79,7 @@ in # Keep sorted serviceConfig = { DynamicUser = true; - ExecStart = "${lib.getExe cfg.package} --config ${configFile}"; + ExecStart = "${lib.getExe cfg.package} serve --config ${configFile}"; LockPersonality = true; MemoryDenyWriteExecute = true; PrivateDevices = true; diff --git a/src/args.rs b/src/args.rs deleted file mode 100644 index 33862de2..00000000 --- a/src/args.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Integration with `clap` - -use std::path::PathBuf; - -use clap::{CommandFactory as _, FromArgMatches as _, Parser}; - -/// Command line arguments -#[derive(Parser)] -#[clap(about, version = crate::version())] -pub(crate) struct Args { - /// Path to the configuration file - #[clap(long, short)] - pub(crate) config: Option, -} - -/// Parse command line arguments into structured data -pub(crate) fn parse() -> Args { - let mut command = Args::command().mut_arg("config", |x| { - let help = "Set the path to the configuration file"; - x.help(help).long_help(format!( - "{}\n\nIf this option is specified, the provided value is used \ - as-is.\n\nIf this option is not specified, then the XDG Base \ - Directory Specification is followed, searching for the path `{}` \ - in the configuration directories. - ", - help, - crate::config::DEFAULT_PATH.display(), - )) - }); - - match Args::from_arg_matches(&command.get_matches_mut()) { - Ok(x) => x, - Err(e) => e.format(&mut command).exit(), - } -} diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 00000000..cb6f91bb --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,51 @@ +//! Integration with `clap` + +use std::path::PathBuf; + +use clap::{Parser, Subcommand}; + +/// Command line arguments +#[derive(Parser)] +#[clap( + about, + version = crate::version(), +)] +pub(crate) struct Args { + #[clap(subcommand)] + pub(crate) command: Command, +} + +#[derive(Subcommand)] +pub(crate) enum Command { + /// Run the server. + Serve(ServeArgs), +} + +/// Wrapper for the `--config` arg. +/// +/// This exists to centralize the `mut_arg` code that sets the help value based +/// on runtime information. +#[derive(clap::Args)] +#[clap(mut_arg("config", |x| { + let help = "Set the path to the configuration file"; + x.help(help).long_help(format!( + "{}\n\nIf this option is specified, the provided value is used \ + as-is.\n\nIf this option is not specified, then the XDG Base \ + Directory Specification is followed, searching for the path `{}` \ + in the configuration directories. + ", + help, + crate::config::DEFAULT_PATH.display(), + )) +}))] +pub(crate) struct ConfigArg { + /// Path to the configuration file + #[clap(long, short)] + pub(crate) config: Option, +} + +#[derive(clap::Args)] +pub(crate) struct ServeArgs { + #[clap(flatten)] + pub(crate) config: ConfigArg, +} diff --git a/src/main.rs b/src/main.rs index 049fd10c..e90e9f7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ use axum::{ use axum_server::{ bind, bind_rustls, tls_rustls::RustlsConfig, Handle as ServerHandle, }; +use clap::Parser; use futures_util::FutureExt; use http::{ header::{self, HeaderName}, @@ -41,7 +42,7 @@ use tower_http::{ use tracing::{debug, error, info, info_span, warn, Instrument}; mod api; -mod args; +mod cli; mod config; mod database; mod error; @@ -51,6 +52,7 @@ mod utils; pub(crate) use api::ruma_wrapper::{Ar, Ra}; use api::{client_server, server_server, well_known}; +use cli::{Args, Command}; pub(crate) use config::{Config, ListenConfig}; pub(crate) use database::KeyValueDatabase; pub(crate) use service::{pdu::PduEvent, Services}; @@ -108,9 +110,12 @@ async fn main() -> ExitCode { async fn try_main() -> Result<(), error::Main> { use error::Main as Error; - let args = args::parse(); + let args = Args::parse(); + // This is a placeholder, the logic specific to the 'serve' command will be + // moved to another file in a later commit + let Command::Serve(args) = args.command; - let config = config::load(args.config.as_ref()).await?; + let config = config::load(args.config.config.as_ref()).await?; let (_guard, reload_handles) = observability::init(&config)?;