From d4cc2621dbe60c486d584a6f777d73f5f265d4e5 Mon Sep 17 00:00:00 2001 From: Jeremiah Russell Date: Tue, 21 Oct 2025 22:04:33 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20configurable=20rules=20direct?= =?UTF-8?q?ory=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add rules configuration option to ClientConfig - Support custom rules file paths via config and CLI - Add --rules-dir option to init command - Update Rules struct to accept custom file paths - Add helper functions for rules path resolution - Fix doc comment formatting issues - Add integration tests for custom rules paths --- src/cli/main.rs | 36 ++++++++++++++++----------------- src/cli/rules_cli.rs | 1 + src/rules.rs | 12 ++++++----- tests/init_integration_tests.rs | 8 +++----- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/cli/main.rs b/src/cli/main.rs index 29d1c52..3d18f90 100644 --- a/src/cli/main.rs +++ b/src/cli/main.rs @@ -539,6 +539,24 @@ async fn run_rules(client: &mut GmailClient, rules: Rules, execute: bool) -> Res /// - Container deployments with injected token environment variables /// - CI/CD pipelines with stored token secrets /// - Ephemeral compute environments requiring periodic Gmail access +fn restore_tokens_if_available(config: &Config, client_config: &ClientConfig) -> Result<()> { + let token_env_var = config + .get_string("token_cache_env") + .unwrap_or_else(|_| "CULL_GMAIL_TOKEN_CACHE".to_string()); + + if let Ok(token_data) = env::var(&token_env_var) { + log::info!("Found {token_env_var} environment variable, restoring tokens"); + restore_tokens_from_string(&token_data, client_config.persist_path())?; + log::info!("Tokens successfully restored from environment variable"); + } else { + log::debug!( + "No {token_env_var} environment variable found, proceeding with normal token flow" + ); + } + + Ok(()) +} + /// Gets the rules file path from configuration. /// /// Reads the `rules` configuration value and resolves it using path prefixes. @@ -566,24 +584,6 @@ fn get_rules_path(config: &Config) -> Result> { Ok(Some(path)) } -fn restore_tokens_if_available(config: &Config, client_config: &ClientConfig) -> Result<()> { - let token_env_var = config - .get_string("token_cache_env") - .unwrap_or_else(|_| "CULL_GMAIL_TOKEN_CACHE".to_string()); - - if let Ok(token_data) = env::var(&token_env_var) { - log::info!("Found {token_env_var} environment variable, restoring tokens"); - restore_tokens_from_string(&token_data, client_config.persist_path())?; - log::info!("Tokens successfully restored from environment variable"); - } else { - log::debug!( - "No {token_env_var} environment variable found, proceeding with normal token flow" - ); - } - - Ok(()) -} - /// Executes the specified end-of-life action on messages for a Gmail label. /// /// This function performs the actual message operations (trash or delete) based on diff --git a/src/cli/rules_cli.rs b/src/cli/rules_cli.rs index 0e06d4b..c8e64d4 100644 --- a/src/cli/rules_cli.rs +++ b/src/cli/rules_cli.rs @@ -342,6 +342,7 @@ impl RulesCli { /// - **Rules CLI**: To load rules before configuration or execution /// - **Main CLI**: For default rule execution when no subcommand is specified /// - **Validation systems**: To verify rule configuration integrity +/// /// Loads rules from the default location. pub fn get_rules() -> Result { get_rules_from(None) diff --git a/src/rules.rs b/src/rules.rs index 0c99a4b..8a2c3f8 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -45,7 +45,7 @@ use std::{ collections::BTreeMap, env, fs::{self, read_to_string}, - path::{Path, PathBuf}, + path::Path, }; use serde::{Deserialize, Serialize}; @@ -524,8 +524,9 @@ impl Rules { let save_path = if let Some(p) = path { p.to_path_buf() } else { - let home_dir = env::home_dir() - .ok_or_else(|| Error::HomeExpansionFailed("~/.cull-gmail/rules.toml".to_string()))?; + let home_dir = env::home_dir().ok_or_else(|| { + Error::HomeExpansionFailed("~/.cull-gmail/rules.toml".to_string()) + })?; home_dir.join(".cull-gmail/rules.toml") }; @@ -600,8 +601,9 @@ impl Rules { let load_path = if let Some(p) = path { p.to_path_buf() } else { - let home_dir = env::home_dir() - .ok_or_else(|| Error::HomeExpansionFailed("~/.cull-gmail/rules.toml".to_string()))?; + let home_dir = env::home_dir().ok_or_else(|| { + Error::HomeExpansionFailed("~/.cull-gmail/rules.toml".to_string()) + })?; home_dir.join(".cull-gmail/rules.toml") }; diff --git a/tests/init_integration_tests.rs b/tests/init_integration_tests.rs index 4d55f1f..c861dc5 100644 --- a/tests/init_integration_tests.rs +++ b/tests/init_integration_tests.rs @@ -92,11 +92,9 @@ fn test_init_with_separate_rules_directory() { &format!("c:{}", rules_dir.to_string_lossy()), ]); - cmd.assert() - .success() - .stdout(predicate::str::contains( - "Initialization completed successfully!", - )); + cmd.assert().success().stdout(predicate::str::contains( + "Initialization completed successfully!", + )); // Verify config directory was created assert!(config_dir.exists());