mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
a2becf0917
重构 open_provider_terminal 相关代码,提升可维护性和可读性。 主要改进: - 将 launch_terminal_with_env 拆分为多个职责单一的小函数 * write_claude_config: 写入配置文件 * escape_shell_path: 转义 shell 路径 * generate_wrapper_script: 生成包装脚本 * launch_macos_terminal / launch_linux_terminal / launch_windows_terminal: 平台特定启动逻辑 - 使用 let Some else 提前返回模式,减少嵌套 - 修复 Gemini 环境变量名为 GEMINI_API_KEY(而非 GOOGLE_API_KEY) - 完善临时文件清理逻辑: * macOS/Linux: 使用 trap EXIT 自动清理 * Windows: 批处理文件自删除 - 代码格式化和 import 排序优化 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
3.9 KiB
Rust
117 lines
3.9 KiB
Rust
use crate::error::AppError;
|
|
use auto_launch::{AutoLaunch, AutoLaunchBuilder};
|
|
|
|
/// 获取 macOS 上的 .app bundle 路径
|
|
/// 将 `/path/to/CC Switch.app/Contents/MacOS/CC Switch` 转换为 `/path/to/CC Switch.app`
|
|
#[cfg(target_os = "macos")]
|
|
fn get_macos_app_bundle_path(exe_path: &std::path::Path) -> Option<std::path::PathBuf> {
|
|
let path_str = exe_path.to_string_lossy();
|
|
// 查找 .app/Contents/MacOS/ 模式
|
|
if let Some(app_pos) = path_str.find(".app/Contents/MacOS/") {
|
|
let app_bundle_end = app_pos + 4; // ".app" 的结束位置
|
|
Some(std::path::PathBuf::from(&path_str[..app_bundle_end]))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// 初始化 AutoLaunch 实例
|
|
fn get_auto_launch() -> Result<AutoLaunch, AppError> {
|
|
let app_name = "CC Switch";
|
|
let exe_path =
|
|
std::env::current_exe().map_err(|e| AppError::Message(format!("无法获取应用路径: {e}")))?;
|
|
|
|
// macOS 需要使用 .app bundle 路径,否则 AppleScript login item 会打开终端
|
|
#[cfg(target_os = "macos")]
|
|
let app_path = get_macos_app_bundle_path(&exe_path).unwrap_or(exe_path);
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
let app_path = exe_path;
|
|
|
|
// 使用 AutoLaunchBuilder 消除平台差异
|
|
// macOS: 使用 AppleScript 方式(默认),需要 .app bundle 路径
|
|
// Windows/Linux: 使用注册表/XDG autostart
|
|
let auto_launch = AutoLaunchBuilder::new()
|
|
.set_app_name(app_name)
|
|
.set_app_path(&app_path.to_string_lossy())
|
|
.build()
|
|
.map_err(|e| AppError::Message(format!("创建 AutoLaunch 失败: {e}")))?;
|
|
|
|
Ok(auto_launch)
|
|
}
|
|
|
|
/// 启用开机自启
|
|
pub fn enable_auto_launch() -> Result<(), AppError> {
|
|
let auto_launch = get_auto_launch()?;
|
|
auto_launch
|
|
.enable()
|
|
.map_err(|e| AppError::Message(format!("启用开机自启失败: {e}")))?;
|
|
log::info!("已启用开机自启");
|
|
Ok(())
|
|
}
|
|
|
|
/// 禁用开机自启
|
|
pub fn disable_auto_launch() -> Result<(), AppError> {
|
|
let auto_launch = get_auto_launch()?;
|
|
auto_launch
|
|
.disable()
|
|
.map_err(|e| AppError::Message(format!("禁用开机自启失败: {e}")))?;
|
|
log::info!("已禁用开机自启");
|
|
Ok(())
|
|
}
|
|
|
|
/// 检查是否已启用开机自启
|
|
pub fn is_auto_launch_enabled() -> Result<bool, AppError> {
|
|
let auto_launch = get_auto_launch()?;
|
|
auto_launch
|
|
.is_enabled()
|
|
.map_err(|e| AppError::Message(format!("检查开机自启状态失败: {e}")))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[cfg(target_os = "macos")]
|
|
#[test]
|
|
fn test_get_macos_app_bundle_path_valid() {
|
|
let exe_path = std::path::Path::new("/Applications/CC Switch.app/Contents/MacOS/CC Switch");
|
|
let result = get_macos_app_bundle_path(exe_path);
|
|
assert_eq!(
|
|
result,
|
|
Some(std::path::PathBuf::from("/Applications/CC Switch.app"))
|
|
);
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
#[test]
|
|
fn test_get_macos_app_bundle_path_with_spaces() {
|
|
let exe_path =
|
|
std::path::Path::new("/Users/test/My Apps/CC Switch.app/Contents/MacOS/CC Switch");
|
|
let result = get_macos_app_bundle_path(exe_path);
|
|
assert_eq!(
|
|
result,
|
|
Some(std::path::PathBuf::from(
|
|
"/Users/test/My Apps/CC Switch.app"
|
|
))
|
|
);
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
#[test]
|
|
fn test_get_macos_app_bundle_path_not_in_bundle() {
|
|
let exe_path = std::path::Path::new("/usr/local/bin/cc-switch");
|
|
let result = get_macos_app_bundle_path(exe_path);
|
|
assert_eq!(result, None);
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
#[test]
|
|
fn test_get_macos_app_bundle_path_dev_build() {
|
|
// 开发环境下的路径通常不在 .app bundle 内
|
|
let exe_path = std::path::Path::new("/Users/dev/project/target/debug/cc-switch");
|
|
let result = get_macos_app_bundle_path(exe_path);
|
|
assert_eq!(result, None);
|
|
}
|
|
}
|