Add configurable rules directory support

- 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
This commit is contained in:
Jeremiah Russell
2025-10-21 22:04:33 +01:00
committed by Jeremiah Russell
parent e914e492e8
commit d4cc2621db
4 changed files with 29 additions and 28 deletions

View File

@@ -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<Option<PathBuf>> {
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

View File

@@ -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<Rules> {
get_rules_from(None)

View File

@@ -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")
};

View File

@@ -92,9 +92,7 @@ fn test_init_with_separate_rules_directory() {
&format!("c:{}", rules_dir.to_string_lossy()),
]);
cmd.assert()
.success()
.stdout(predicate::str::contains(
cmd.assert().success().stdout(predicate::str::contains(
"Initialization completed successfully!",
));