diff --git a/src-tauri/src/logger.rs b/src-tauri/src/logger.rs index 222ea40..c466c83 100644 --- a/src-tauri/src/logger.rs +++ b/src-tauri/src/logger.rs @@ -8,33 +8,35 @@ use tauri::{AppHandle, Manager}; static LOG_DIRECTORY: Mutex> = Mutex::new(None); pub fn setup_logger(app: &AppHandle) -> Result<(), fern::InitError> { - // 获取日志目录(可能是自定义的,也可能是默认的) + // 获取日志目录 let log_dir = get_effective_log_directory(app); // 创建日志目录 if let Err(e) = fs::create_dir_all(&log_dir) { eprintln!("Failed to create log directory: {}", e); - // 如果自定义目录创建失败,回退到默认目录 let default_dir = get_default_log_directory(app); fs::create_dir_all(&default_dir).expect("Failed to create default log directory"); - // 更新为默认目录 { let mut guard = LOG_DIRECTORY.lock().unwrap(); - *guard = None; // 清除自定义设置 + *guard = None; } warn!("日志目录创建失败,使用默认目录: {:?}", default_dir); - } else { - info!("日志目录: {:?}", log_dir); } // 生成当天的日志文件名 let today = Local::now().format("%Y-%m-%d").to_string(); - let log_file = log_dir.join(format!("codeforge-{}.log", today)); - // 配置日志 - fern::Dispatch::new() + // 不同级别的日志文件 + let all_log_file = log_dir.join(format!("codeforge-{}.log", today)); + let error_log_file = log_dir.join(format!("codeforge-error-{}.log", today)); + let warn_log_file = log_dir.join(format!("codeforge-warn-{}.log", today)); + let info_log_file = log_dir.join(format!("codeforge-info-{}.log", today)); + let debug_log_file = log_dir.join(format!("codeforge-debug-{}.log", today)); + + // 基础配置 + let base_config = fern::Dispatch::new() .format(|out, message, record| { out.finish(format_args!( "[{}] [{}] [{}:{}] {}", @@ -45,17 +47,40 @@ pub fn setup_logger(app: &AppHandle) -> Result<(), fern::InitError> { message )) }) - .level(LevelFilter::Debug) // 设置日志级别 - .level_for("hyper", LevelFilter::Warn) // 减少第三方库的日志 + .level(LevelFilter::Debug) + .level_for("hyper", LevelFilter::Warn) .level_for("reqwest", LevelFilter::Warn) - .level_for("tauri", LevelFilter::Info) // Tauri 框架日志 - .chain(std::io::stdout()) // 同时输出到控制台 - .chain(fern::log_file(&log_file)?) // 输出到文件 + .level_for("tauri", LevelFilter::Info); + + // 配置不同级别的日志输出 + base_config + .chain(std::io::stdout()) // 控制台输出 + .chain(fern::log_file(&all_log_file)?) // 所有级别写入总文件 + .chain( + fern::Dispatch::new() + .filter(|metadata| metadata.level() == log::Level::Error) + .chain(fern::log_file(&error_log_file)?), + ) + .chain( + fern::Dispatch::new() + .filter(|metadata| metadata.level() == log::Level::Warn) + .chain(fern::log_file(&warn_log_file)?), + ) + .chain( + fern::Dispatch::new() + .filter(|metadata| metadata.level() == log::Level::Info) + .chain(fern::log_file(&info_log_file)?), + ) + .chain( + fern::Dispatch::new() + .filter(|metadata| metadata.level() == log::Level::Debug) + .chain(fern::log_file(&debug_log_file)?), + ) .apply()?; info!("CodeForge 应用启动"); info!("应用版本: {}", env!("CARGO_PKG_VERSION")); - info!("日志文件: {:?}", log_file); + info!("日志文件目录 {}", log_dir.display()); Ok(()) } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 01a5c9d..6833c92 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -64,7 +64,7 @@ async fn execute_code( let start_time = std::time::Instant::now(); let mut _last_error: String = String::new(); - let cmd = plugin.get_command(); + let cmd = plugin.get_command(None); let args = plugin.get_execute_args(file_path.to_str().unwrap()); info!( "执行代码 -> 调用插件 [ {} ] 执行命令 {} 携带参数 {}", @@ -74,7 +74,7 @@ async fn execute_code( ); let output = Command::new(&cmd) - .args(&args) + .args(args) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .output(); @@ -142,7 +142,9 @@ async fn execute_code( request.language, request.language, _last_error, - plugin.get_command().to_string() + plugin + .get_command(Some(file_path.to_str().unwrap())) + .to_string() ), execution_time, timestamp, @@ -172,7 +174,7 @@ async fn get_info( format!("Pre-execution hook failed: {}", e) })?; - let cmd = plugin.get_command(); + let cmd = plugin.get_command(None); debug!("获取环境 -> 插件 [ {} ] 命令 {}", language, cmd); let version_output = Command::new(&cmd).args(plugin.get_version_args()).output(); @@ -211,7 +213,7 @@ async fn get_info( Ok(LanguageInfo { installed: false, version: "Not found".to_string(), - path: format!("Not found - tried: {:?}", plugin.get_command()), + path: format!("Not found - tried: {:?}", plugin.get_command(None)), language: plugin.get_language_name().to_string(), }) } diff --git a/src-tauri/src/plugins/manager.rs b/src-tauri/src/plugins/manager.rs index dca12c5..ad74146 100644 --- a/src-tauri/src/plugins/manager.rs +++ b/src-tauri/src/plugins/manager.rs @@ -54,7 +54,7 @@ impl PluginManager { self.get_plugin(language).map(|plugin| PluginInfo { name: plugin.get_language_name().to_string(), file_extension: plugin.get_file_extension(), - available_commands: vec![plugin.get_command().to_string()], + available_commands: vec![plugin.get_command(None).to_string()], }) } @@ -65,7 +65,7 @@ impl PluginManager { .map(|plugin| PluginInfo { name: plugin.get_language_name().to_string(), file_extension: plugin.get_file_extension(), - available_commands: vec![plugin.get_command().to_string()], + available_commands: vec![plugin.get_command(None).to_string()], }) .collect() } diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index 2b62f8e..062b759 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -63,18 +63,23 @@ pub trait LanguagePlugin: Send + Sync { fn get_execute_home(&self) -> Option { self.get_config() .and_then(|config| config.execute_home.clone()) + .filter(|path| !path.trim().is_empty()) // 过滤掉空字符串和只有空白字符的字符串 .map(PathBuf::from) } // 获取插件支持的命令 - fn get_command(&self) -> String { + fn get_command(&self, file_path: Option<&str>) -> String { if let Some(config) = self.get_config() { if let Some(run_cmd) = &config.run_command { - return run_cmd - .split_whitespace() - .next() - .unwrap_or(&config.language) - .to_string(); + if let Some(path) = file_path { + return run_cmd.replace("$filename", path); + } else { + return run_cmd + .split_whitespace() + .next() + .unwrap_or(&config.language) + .to_string(); + } } } self.get_default_command() @@ -120,7 +125,23 @@ pub trait LanguagePlugin: Send + Sync { } fn get_version_args(&self) -> Vec<&'static str>; - fn get_execute_args(&self, file_path: &str) -> Vec; + + fn get_execute_args(&self, file_path: &str) -> Vec { + if let Some(config) = self.get_config() { + if let Some(run_cmd) = &config.run_command { + // 替换 $filename 后分割,跳过第一个元素(命令本身) + let full_cmd = run_cmd.replace("$filename", file_path); + return full_cmd + .split_whitespace() + .skip(1) // 跳过命令部分,只返回参数 + .map(|s| s.to_string()) + .collect(); + } + } + // 默认情况下,文件路径就是唯一的参数 + vec![file_path.to_string()] + } + fn get_path_command(&self) -> String; // 构建默认配置 @@ -193,7 +214,11 @@ pub trait LanguagePlugin: Send + Sync { } // 后执行钩子 - fn post_execute_hook(&self, _result: &mut ExecutionResult) -> Result<(), String> { + fn post_execute_hook(&self, result: &mut ExecutionResult) -> Result<(), String> { + if result.success && result.stdout.is_empty() && result.stderr.is_empty() { + result.stdout = "代码执行成功 (无输出)".to_string(); + } + Ok(()) } } diff --git a/src-tauri/src/plugins/python2.rs b/src-tauri/src/plugins/python2.rs index 808d09e..2178021 100644 --- a/src-tauri/src/plugins/python2.rs +++ b/src-tauri/src/plugins/python2.rs @@ -20,10 +20,6 @@ impl LanguagePlugin for Python2Plugin { vec!["--version"] } - fn get_execute_args(&self, file_path: &str) -> Vec { - vec![file_path.to_string()] - } - fn get_path_command(&self) -> String { "import sys; print(sys.executable)".to_string() } diff --git a/src-tauri/src/plugins/python3.rs b/src-tauri/src/plugins/python3.rs index 2887bf0..557efe6 100644 --- a/src-tauri/src/plugins/python3.rs +++ b/src-tauri/src/plugins/python3.rs @@ -1,4 +1,4 @@ -use super::{ExecutionResult, LanguagePlugin, PluginConfig}; +use super::{LanguagePlugin, PluginConfig}; pub struct Python3Plugin; @@ -19,10 +19,6 @@ impl LanguagePlugin for Python3Plugin { vec!["--version"] } - fn get_execute_args(&self, file_path: &str) -> Vec { - vec![file_path.to_string()] - } - fn get_path_command(&self) -> String { "import sys; print(sys.executable)".to_string() } @@ -43,20 +39,4 @@ impl LanguagePlugin for Python3Plugin { fn get_default_command(&self) -> String { self.get_config().unwrap().run_command.unwrap() } - - fn post_execute_hook(&self, result: &mut ExecutionResult) -> Result<(), String> { - // Python 特定的后处理 - if result.success && result.stdout.is_empty() && result.stderr.is_empty() { - result.stdout = "代码执行成功 (无输出)".to_string(); - } - - // 清理 Python 特定的错误信息 - if !result.stderr.is_empty() { - result.stderr = result - .stderr - .replace("Traceback (most recent call last):", "Error:"); - } - - Ok(()) - } } diff --git a/src/components/Settings.vue b/src/components/Settings.vue index d288f20..ec139a0 100644 --- a/src/components/Settings.vue +++ b/src/components/Settings.vue @@ -8,7 +8,7 @@ diff --git a/src/components/setting/Language.vue b/src/components/setting/Language.vue index 4519032..e69fbed 100644 --- a/src/components/setting/Language.vue +++ b/src/components/setting/Language.vue @@ -1,6 +1,6 @@