From 29a0643d74d0cd2ee35c77ee09dd0bc4ec3a7abc Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 26 Jan 2026 11:24:28 +0800 Subject: [PATCH] refactor(config): consolidate get_home_dir into single public function Follow-up to #644: Extract duplicate get_home_dir() implementations into a single pub fn in config.rs, reducing code duplication across codex_config.rs, gemini_config.rs, and settings.rs. Also adds documentation comments to build.rs explaining the Windows manifest workaround for test binaries. --- src-tauri/build.rs | 10 ++++++++++ src-tauri/src/codex_config.rs | 18 ++---------------- src-tauri/src/config.rs | 5 ++++- src-tauri/src/gemini_config.rs | 17 +---------------- src-tauri/src/settings.rs | 17 +++++------------ 5 files changed, 22 insertions(+), 45 deletions(-) diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 12b5797b..7aaeff60 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,6 +1,16 @@ fn main() { tauri_build::build(); + // Windows: Embed Common Controls v6 manifest for test binaries + // + // When running `cargo test`, the generated test executables don't include + // the standard Tauri application manifest. Without Common Controls v6, + // `tauri::test` calls fail with STATUS_ENTRYPOINT_NOT_FOUND. + // + // This workaround: + // 1. Embeds the manifest into test binaries via /MANIFEST:EMBED + // 2. Uses /MANIFEST:NO for the main binary to avoid duplicate resources + // (Tauri already handles manifest embedding for the app binary) #[cfg(target_os = "windows")] { let manifest_path = std::path::PathBuf::from( diff --git a/src-tauri/src/codex_config.rs b/src-tauri/src/codex_config.rs index e57d7902..642e4886 100644 --- a/src-tauri/src/codex_config.rs +++ b/src-tauri/src/codex_config.rs @@ -2,28 +2,14 @@ use std::path::PathBuf; use crate::config::{ - atomic_write, delete_file, sanitize_provider_name, write_json_file, write_text_file, + atomic_write, delete_file, get_home_dir, sanitize_provider_name, write_json_file, + write_text_file, }; use crate::error::AppError; use serde_json::Value; use std::fs; use std::path::Path; -/// 获取用户主目录,带回退和日志 -fn get_home_dir() -> PathBuf { - #[cfg(windows)] - if let Ok(home) = std::env::var("HOME") { - let trimmed = home.trim(); - if !trimmed.is_empty() { - return PathBuf::from(trimmed); - } - } - dirs::home_dir().unwrap_or_else(|| { - log::warn!("无法获取用户主目录,回退到当前目录"); - PathBuf::from(".") - }) -} - /// 获取 Codex 配置目录路径 pub fn get_codex_config_dir() -> PathBuf { if let Some(custom) = crate::settings::get_codex_override_dir() { diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index cabc0e87..aea9c4c8 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -6,7 +6,10 @@ use std::path::{Path, PathBuf}; use crate::error::AppError; /// 获取用户主目录,带回退和日志 -fn get_home_dir() -> PathBuf { +/// +/// On Windows, respects the `HOME` environment variable (if set) to support +/// test isolation. Falls back to `dirs::home_dir()` otherwise. +pub fn get_home_dir() -> PathBuf { #[cfg(windows)] if let Ok(home) = std::env::var("HOME") { let trimmed = home.trim(); diff --git a/src-tauri/src/gemini_config.rs b/src-tauri/src/gemini_config.rs index c652d61d..94774f2d 100644 --- a/src-tauri/src/gemini_config.rs +++ b/src-tauri/src/gemini_config.rs @@ -1,25 +1,10 @@ -use crate::config::write_text_file; +use crate::config::{get_home_dir, write_text_file}; use crate::error::AppError; use serde_json::Value; use std::collections::HashMap; use std::fs; use std::path::PathBuf; -/// 获取用户主目录,带回退和日志 -fn get_home_dir() -> PathBuf { - #[cfg(windows)] - if let Ok(home) = std::env::var("HOME") { - let trimmed = home.trim(); - if !trimmed.is_empty() { - return PathBuf::from(trimmed); - } - } - dirs::home_dir().unwrap_or_else(|| { - log::warn!("无法获取用户主目录,回退到当前目录"); - PathBuf::from(".") - }) -} - /// 获取 Gemini 配置目录路径(支持设置覆盖) pub fn get_gemini_dir() -> PathBuf { if let Some(custom) = crate::settings::get_gemini_override_dir() { diff --git a/src-tauri/src/settings.rs b/src-tauri/src/settings.rs index f82aa4c4..f0e2ab8f 100644 --- a/src-tauri/src/settings.rs +++ b/src-tauri/src/settings.rs @@ -163,18 +163,11 @@ impl Default for AppSettings { impl AppSettings { fn settings_path() -> Option { // settings.json 保留用于旧版本迁移和无数据库场景 - #[cfg(windows)] - if let Ok(home) = std::env::var("HOME") { - let trimmed = home.trim(); - if !trimmed.is_empty() { - return Some( - PathBuf::from(trimmed) - .join(".cc-switch") - .join("settings.json"), - ); - } - } - dirs::home_dir().map(|h| h.join(".cc-switch").join("settings.json")) + Some( + crate::config::get_home_dir() + .join(".cc-switch") + .join("settings.json"), + ) } fn normalize_paths(&mut self) {