use eyre::Result;
use serde::Deserialize;
use std::path::PathBuf;
#[derive(Debug, Deserialize)]
pub struct Config {
pub github_token: Option<String>,
}
impl Config {
pub fn load() -> Result<Self> {
let config_path = config_path()?;
let config = if config_path.exists() {
let contents = std::fs::read_to_string(&config_path)?;
toml::from_str(&contents)?
} else {
Self { github_token: None }
};
Ok(config)
}
pub fn get_github_token(&self) -> Result<String> {
let token = self
.github_token
.clone()
.or_else(|| std::env::var("GITHUB_TOKEN").ok())
.ok_or_else(|| eyre::eyre!("GitHub token not found in config file or environment"))?;
Ok(token)
}
}
fn config_path() -> Result<PathBuf> {
let home = dirs::home_dir().ok_or_else(|| eyre::eyre!("Could not determine home directory"))?;
Ok(home.join(".config").join("bountybot").join("config.toml"))
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
use std::fs;
use tempfile::TempDir;
fn setup_test_config(content: Option<&str>) -> (TempDir, PathBuf) {
let temp_dir = TempDir::new().unwrap();
let config_dir = temp_dir.path().join(".config").join("bountybot");
fs::create_dir_all(&config_dir).unwrap();
let config_path = config_dir.join("config.toml");
if let Some(content) = content {
fs::write(&config_path, content).unwrap();
}
(temp_dir, config_path)
}
#[test]
fn test_load_nonexistent_config() {
let (temp_dir, _) = setup_test_config(None);
env::set_var("HOME", temp_dir.path());
let config = Config::load().unwrap();
assert!(config.github_token.is_none());
}
#[test]
fn test_load_existing_config() {
let (temp_dir, _) = setup_test_config(Some(
r#"
github_token = "test-token"
"#,
));
env::set_var("HOME", temp_dir.path());
let config = Config::load().unwrap();
assert_eq!(config.github_token, Some("test-token".to_string()));
}
#[test]
fn test_get_github_token_from_config() {
let config = Config {
github_token: Some("config-token".to_string()),
};
assert_eq!(config.get_github_token().unwrap(), "config-token");
}
#[test]
fn test_get_github_token_from_env() {
let config = Config { github_token: None };
env::set_var("GITHUB_TOKEN", "env-token");
assert_eq!(config.get_github_token().unwrap(), "env-token");
env::remove_var("GITHUB_TOKEN");
}
#[test]
fn test_get_github_token_missing() {
let config = Config { github_token: None };
env::remove_var("GITHUB_TOKEN");
assert!(config.get_github_token().is_err());
}
#[test]
fn test_invalid_config_format() {
let (temp_dir, _) = setup_test_config(Some("invalid toml content"));
env::set_var("HOME", temp_dir.path());
assert!(Config::load().is_err());
}
}