From db3bba5a422b41f3abc8be90b0f39a1aed68291d Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Fri, 11 Aug 2023 23:13:17 +0200 Subject: [PATCH] feat: also allow run args to be passed from toml file --- CHANGELOG.md | 1 + Cargo.toml | 2 +- alex-example.toml | 20 ++++----- src/cli/mod.rs | 31 ++++++++----- src/cli/run/config.rs | 22 ++++++++++ src/cli/{run.rs => run/mod.rs} | 80 +++++++++++++++++++--------------- 6 files changed, 99 insertions(+), 57 deletions(-) create mode 100644 src/cli/run/config.rs rename src/cli/{run.rs => run/mod.rs} (58%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf8a14..553fd69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Extract command for working with the output of export * Arch packages are now published to my bur repo +* Allow passing configuration variables from TOML file ### Changed diff --git a/Cargo.toml b/Cargo.toml index 777407a..09a8b1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ flate2 = "1.0.26" chrono = { version = "0.4.26", features = ["serde"] } clap = { version = "4.3.1", features = ["derive", "env"] } signal-hook = "0.3.15" -serde = { version = "1.0.164", features = ["derive", "rc"] } +serde = { version = "1.0.164", features = ["derive"] } serde_json = "1.0.96" figment = { version = "0.10.10", features = ["env", "toml"] } diff --git a/alex-example.toml b/alex-example.toml index d4b4122..234a7bf 100644 --- a/alex-example.toml +++ b/alex-example.toml @@ -3,14 +3,14 @@ world = "data/worlds" backup = "data/backups" server = "Paper" -[[layers]] -name = "2min" -frequency = 2 -chains = 4 -chain_len = 4 +# [[layers]] +# name = "2min" +# frequency = 2 +# chains = 4 +# chain_len = 4 -[[layers]] -name = "3min" -frequency = 3 -chains = 2 -chain_len = 2 +# [[layers]] +# name = "3min" +# frequency = 3 +# chains = 2 +# chain_len = 2 diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 6ba3f94..7a76ea1 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -5,7 +5,7 @@ mod run; pub use crate::backup::MetaManager; pub use crate::server::Metadata; pub use backup::{BackupArgs, BackupCommands}; -pub use run::RunArgs; +pub use run::RunCli; use crate::backup::ManagerConfig; use crate::server::ServerType; @@ -16,13 +16,12 @@ use figment::{ Figment, }; use serde::{Deserialize, Serialize}; -use std::io; use std::path::PathBuf; #[derive(Subcommand)] pub enum Commands { /// Run the server - Run(RunArgs), + Run(RunCli), /// Interact with the backup system without starting a server Backup(BackupArgs), } @@ -78,20 +77,28 @@ pub struct Cli { impl Cli { pub fn run(&self) -> crate::Result<()> { + let config = self.config(&self.args)?; + + match &self.command { + Commands::Run(args) => args.run(self, &config), + Commands::Backup(args) => Ok(args.run(&config)?), + } + } + + pub fn config(&self, args: &U) -> Result + where + T: Default + Serialize + for<'de> Deserialize<'de>, + U: Serialize, + { let toml_file = self .config_file .clone() .unwrap_or(PathBuf::from(Env::var_or("ALEX_CONFIG_FILE", ""))); - let config: Config = Figment::new() - .merge(Serialized::defaults(Config::default())) + Figment::new() + .merge(Serialized::defaults(T::default())) .merge(Toml::file(toml_file)) .merge(Env::prefixed("ALEX_")) - .merge(Serialized::defaults(&self.args)) - .extract()?; - - match &self.command { - Commands::Run(args) => args.run(&config), - Commands::Backup(args) => Ok(args.run(&config)?), - } + .merge(Serialized::defaults(args)) + .extract() } } diff --git a/src/cli/run/config.rs b/src/cli/run/config.rs new file mode 100644 index 0000000..5783451 --- /dev/null +++ b/src/cli/run/config.rs @@ -0,0 +1,22 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Config { + pub jar: PathBuf, + pub java: String, + pub xms: u64, + pub xmx: u64, +} + +impl Default for Config { + fn default() -> Self { + Self { + jar: PathBuf::from("server.jar"), + java: String::from("java"), + xms: 1024, + xmx: 2048, + } + } +} diff --git a/src/cli/run.rs b/src/cli/run/mod.rs similarity index 58% rename from src/cli/run.rs rename to src/cli/run/mod.rs index 4e577b8..fb48491 100644 --- a/src/cli/run.rs +++ b/src/cli/run/mod.rs @@ -1,33 +1,19 @@ -use crate::cli::Cli; +mod config; + use crate::server; use crate::signals; use crate::stdin; use clap::Args; -use std::io; +use config::Config; use std::path::PathBuf; use std::sync::{Arc, Mutex}; +use serde::{Deserialize, Serialize}; + #[derive(Args)] -pub struct RunArgs { - /// Server jar to execute - #[arg( - long, - value_name = "JAR_PATH", - default_value = "server.jar", - env = "ALEX_JAR" - )] - pub jar: PathBuf, - - /// Java command to run the server jar with - #[arg(long, value_name = "JAVA_CMD", default_value_t = String::from("java"), env = "ALEX_JAVA")] - pub java: String, - - /// XMS value in megabytes for the server instance - #[arg(long, default_value_t = 1024, env = "ALEX_XMS")] - pub xms: u64, - /// XMX value in megabytes for the server instance - #[arg(long, default_value_t = 2048, env = "ALEX_XMX")] - pub xmx: u64, +pub struct RunCli { + #[command(flatten)] + pub args: RunArgs, /// Don't actually run the server, but simply output the server configuration that would have /// been ran @@ -35,6 +21,29 @@ pub struct RunArgs { pub dry: bool, } +#[derive(Args, Serialize, Deserialize, Clone)] +pub struct RunArgs { + /// Server jar to execute + #[arg(long, value_name = "JAR_PATH")] + #[serde(skip_serializing_if = "::std::option::Option::is_none")] + pub jar: Option, + + /// Java command to run the server jar with + #[arg(long, value_name = "JAVA_CMD")] + #[serde(skip_serializing_if = "::std::option::Option::is_none")] + pub java: Option, + + /// XMS value in megabytes for the server instance + #[arg(long)] + #[serde(skip_serializing_if = "::std::option::Option::is_none")] + pub xms: Option, + + /// XMX value in megabytes for the server instance + #[arg(long)] + #[serde(skip_serializing_if = "::std::option::Option::is_none")] + pub xmx: Option, +} + fn backups_thread(counter: Arc>) { loop { let next_scheduled_time = { @@ -56,19 +65,22 @@ fn backups_thread(counter: Arc>) { } } -impl RunArgs { - pub fn run(&self, config: &super::Config) -> crate::Result<()> { +impl RunCli { + pub fn run(&self, cli: &super::Cli, global: &super::Config) -> crate::Result<()> { + let config: Config = cli.config(&self.args)?; + println!("{:?}", config); + let (_, mut signals) = signals::install_signal_handlers()?; - let mut cmd = server::ServerCommand::new(config.server, &config.server_version) - .java(&self.java) - .jar(self.jar.clone()) - .config(config.config.clone()) - .world(config.world.clone()) - .backup(config.backup.clone()) - .managers(config.layers.clone()) - .xms(self.xms) - .xmx(self.xmx); + let mut cmd = server::ServerCommand::new(global.server, &global.server_version) + .java(&config.java) + .jar(config.jar.clone()) + .config(global.config.clone()) + .world(global.world.clone()) + .backup(global.backup.clone()) + .managers(global.layers.clone()) + .xms(config.xms) + .xmx(config.xmx); cmd.canonicalize()?; if self.dry { @@ -79,7 +91,7 @@ impl RunArgs { let counter = Arc::new(Mutex::new(cmd.spawn()?)); - if !config.layers.is_empty() { + if !global.layers.is_empty() { let clone = Arc::clone(&counter); std::thread::spawn(move || backups_thread(clone)); }