diff --git a/src/config.rs b/src/config.rs index e6fcfb7..c42484a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -142,27 +142,46 @@ impl Default for AppConfig { impl AppConfig { /// 从文件加载配置,缺失字段回退到环境变量 + /// 尝试顺序:path → ~/.ias/config.json → 默认 pub fn from_file(path: impl AsRef) -> Self { let path = path.as_ref(); + + // 尝试指定路径 if path.exists() { - match std::fs::read_to_string(path) { - Ok(content) => { - // 先做环境变量替换 - let resolved = resolve_env_vars(&content); - match serde_json::from_str(&resolved) { - Ok(cfg) => return cfg, - Err(e) => { - tracing::warn!("解析配置文件失败 ({}): {},使用默认配置", path.display(), e); - } - } - } - Err(e) => { - tracing::warn!("读取配置文件失败 ({}): {},使用默认配置", path.display(), e); + match Self::try_load(path) { + Some(cfg) => return cfg, + None => tracing::warn!("解析配置文件失败: {},尝试回退", path.display()), + } + } + + // 回退到 ~/.ias/config.json + let home = dirs::home_dir(); + if let Some(home) = home { + let fallback = home.join(".ias").join("config.json"); + if fallback.exists() { + tracing::info!("使用全局配置: {}", fallback.display()); + match Self::try_load(&fallback) { + Some(cfg) => return cfg, + None => tracing::warn!("解析全局配置失败: {}", fallback.display()), } } } + + tracing::info!("使用默认配置"); Self::default() } + + fn try_load(path: &Path) -> Option { + let content = std::fs::read_to_string(path).ok()?; + let resolved = resolve_env_vars(&content); + match serde_json::from_str(&resolved) { + Ok(cfg) => Some(cfg), + Err(e) => { + tracing::warn!("解析配置文件失败 ({}): {}", path.display(), e); + None + } + } + } } /// 替换字符串中的 `${VAR_NAME}` 为环境变量值 diff --git a/src/main.rs b/src/main.rs index 50e443c..73d6807 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,16 @@ async fn main() { let is_service = matches!(cli.command, Commands::Service); logger::init_logger(Some(".data/logs"), is_service); - dotenvy::dotenv().ok(); + // .env 加载:先当前目录,再 ~/.ias/.env + if std::path::Path::new(".env").exists() { + dotenvy::dotenv().ok(); + } else if let Ok(home) = std::env::var("HOME") { + let fallback = std::path::PathBuf::from(&home).join(".ias").join(".env"); + if fallback.exists() { + dotenvy::from_path(&fallback).ok(); + tracing::info!("使用全局环境配置: {}", fallback.display()); + } + } let config = AppConfig::from_file("config.json");