diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2026-02-15 21:27:00 +0100 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2026-02-15 21:27:00 +0100 |
| commit | ce0dbf6b249956700c6a1705bf4ad85a09d53e8c (patch) | |
| tree | d7c3236807cfbf75d7f3a355eb5df5a5e2cc4ad7 /src/config.rs | |
| parent | 064a1d01c5c14f5ecc032fa9b8346a4a88b893f6 (diff) | |
Switch, cleanup, and status CLI commands. Persistent build state via
state.json. Post-deploy hooks on success and failure with
WITRYNA_BUILD_STATUS. Dependency diet (axum→tiny_http, clap→argh,
tracing→log). Drop built-in rate limiting. Nix flake with NixOS module.
Arch Linux PKGBUILD. Centralized version management.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/config.rs')
| -rw-r--r-- | src/config.rs | 73 |
1 files changed, 17 insertions, 56 deletions
diff --git a/src/config.rs b/src/config.rs index 63f3447..d79e91c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,20 +1,16 @@ use crate::repo_config; use anyhow::{Context as _, Result, bail}; +use log::LevelFilter; use serde::{Deserialize, Deserializer}; use std::collections::{HashMap, HashSet}; use std::net::SocketAddr; use std::path::{Component, PathBuf}; use std::time::Duration; -use tracing::level_filters::LevelFilter; fn default_log_dir() -> PathBuf { PathBuf::from("/var/log/witryna") } -const fn default_rate_limit() -> u32 { - 10 -} - const fn default_max_builds_to_keep() -> u32 { 5 } @@ -50,8 +46,6 @@ pub struct Config { #[serde(default = "default_log_dir")] pub log_dir: PathBuf, pub log_level: String, - #[serde(default = "default_rate_limit")] - pub rate_limit_per_minute: u32, #[serde(default = "default_max_builds_to_keep")] pub max_builds_to_keep: u32, /// Optional global git operation timeout (e.g., "2m", "5m"). @@ -109,7 +103,7 @@ pub struct SiteConfig { #[serde(default)] pub cache_dirs: Option<Vec<String>>, /// Optional post-deploy hook command (array form, no shell). - /// Runs after successful symlink switch. Non-fatal on failure. + /// Runs after every build (success or failure). Non-fatal on failure. #[serde(default)] pub post_deploy: Option<Vec<String>>, /// Optional environment variables passed to container builds and post-deploy hooks. @@ -265,17 +259,14 @@ impl Config { ) })?; } else if let Some(path) = &site.webhook_token_file { - site.webhook_token = tokio::fs::read_to_string(path) - .await - .with_context(|| { - format!( - "site '{}': failed to read webhook_token_file '{}'", - site.name, - path.display() - ) - })? - .trim() - .to_owned(); + let token_content = tokio::fs::read_to_string(path).await.with_context(|| { + format!( + "site '{}': failed to read webhook_token_file '{}'", + site.name, + path.display() + ) + })?; + token_content.trim().clone_into(&mut site.webhook_token); } } Ok(()) @@ -284,7 +275,6 @@ impl Config { fn validate(&self) -> Result<()> { self.validate_listen_address()?; self.validate_log_level()?; - self.validate_rate_limit()?; self.validate_git_timeout()?; self.validate_container_runtime()?; self.validate_sites()?; @@ -295,13 +285,12 @@ impl Config { if let Some(timeout) = self.git_timeout { if timeout < MIN_GIT_TIMEOUT { bail!( - "git_timeout is too short ({:?}): minimum is {}s", - timeout, + "git_timeout is too short ({timeout:?}): minimum is {}s", MIN_GIT_TIMEOUT.as_secs() ); } if timeout > MAX_GIT_TIMEOUT { - bail!("git_timeout is too long ({:?}): maximum is 1h", timeout,); + bail!("git_timeout is too long ({timeout:?}): maximum is 1h"); } } Ok(()) @@ -333,13 +322,6 @@ impl Config { Ok(()) } - fn validate_rate_limit(&self) -> Result<()> { - if self.rate_limit_per_minute == 0 { - bail!("rate_limit_per_minute must be greater than 0"); - } - Ok(()) - } - fn validate_sites(&self) -> Result<()> { let mut seen_names = HashSet::new(); @@ -369,12 +351,12 @@ impl Config { #[must_use] pub fn log_level_filter(&self) -> LevelFilter { match self.log_level.to_lowercase().as_str() { - "trace" => LevelFilter::TRACE, - "debug" => LevelFilter::DEBUG, - "warn" => LevelFilter::WARN, - "error" => LevelFilter::ERROR, + "trace" => LevelFilter::Trace, + "debug" => LevelFilter::Debug, + "warn" => LevelFilter::Warn, + "error" => LevelFilter::Error, // Catch-all: covers "info" and the unreachable default after validation. - _ => LevelFilter::INFO, + _ => LevelFilter::Info, } } @@ -921,27 +903,6 @@ sites = [] } #[test] - fn zero_rate_limit_rejected() { - let toml = r#" -listen_address = "127.0.0.1:8080" -container_runtime = "podman" -base_dir = "/var/lib/witryna" -log_level = "info" -rate_limit_per_minute = 0 -sites = [] -"#; - let config: Config = toml::from_str(toml).unwrap(); - let result = config.validate(); - assert!(result.is_err()); - assert!( - result - .unwrap_err() - .to_string() - .contains("rate_limit_per_minute") - ); - } - - #[test] fn duplicate_site_names() { let toml = r#" listen_address = "127.0.0.1:8080" |
