Skip to content

Commit b0e463c

Browse files
committed
feat (core): 适配插件定制配置
1 parent 5d291f4 commit b0e463c

6 files changed

Lines changed: 310 additions & 164 deletions

File tree

src-tauri/src/config.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
1+
use crate::plugins::PluginConfig;
12
use log::{info, warn};
23
use serde::{Deserialize, Serialize};
34
use std::fs;
45
use std::path::PathBuf;
5-
6-
#[derive(Debug, Clone, Serialize, Deserialize)]
7-
pub struct PluginConfig {
8-
pub enabled: bool, // 插件是否启用
9-
pub execute_home: String, // 插件的执行路径
10-
pub extensions: Vec<String>, // 插件支持的文件扩展名
11-
pub language: String, // 插件所属语言
12-
pub before_compile: String, // 插件在编译前执行的命令
13-
pub after_compile: String, // 插件在编译完成后执行的命令
14-
pub run_command: String, // 插件执行的命令
15-
pub template: String, // 插件的模板
16-
}
6+
// 全局配置管理器
7+
use std::sync::Mutex;
8+
use tauri::command;
9+
static CONFIG_MANAGER: Mutex<Option<ConfigManager>> = Mutex::new(None);
1710

1811
#[derive(Debug, Clone, Serialize, Deserialize)]
1912
pub struct AppConfig {
@@ -114,10 +107,6 @@ impl ConfigManager {
114107
}
115108
}
116109

117-
// 全局配置管理器
118-
use std::sync::Mutex;
119-
static CONFIG_MANAGER: Mutex<Option<ConfigManager>> = Mutex::new(None);
120-
121110
// 初始化配置
122111
pub fn init_config() -> Result<(), String> {
123112
let config_manager = ConfigManager::new()?;
@@ -144,9 +133,6 @@ pub fn get_config_manager() -> Result<std::sync::MutexGuard<'static, Option<Conf
144133
.map_err(|e| format!("获取配置管理器失败: {}", e))
145134
}
146135

147-
// Tauri 命令
148-
use tauri::command;
149-
150136
#[command]
151137
pub async fn get_app_config() -> Result<AppConfig, String> {
152138
let guard = get_config_manager()?;
@@ -157,6 +143,15 @@ pub async fn get_app_config() -> Result<AppConfig, String> {
157143
}
158144
}
159145

146+
pub fn get_app_config_internal() -> Result<AppConfig, String> {
147+
let guard = get_config_manager()?;
148+
if let Some(config_manager) = guard.as_ref() {
149+
Ok(config_manager.get_config().clone())
150+
} else {
151+
Err("配置管理器未初始化".to_string())
152+
}
153+
}
154+
160155
#[command]
161156
pub async fn update_app_config(config: AppConfig) -> Result<(), String> {
162157
let mut guard = get_config_manager()?;

src-tauri/src/main.rs

Lines changed: 101 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::utils::logger::{
1515
};
1616
use config::{get_app_config, get_config_path, init_config, update_app_config};
1717

18-
use log::{debug, info};
18+
use log::{debug, error, info};
1919
use plugins::{CodeExecutionRequest, ExecutionResult, LanguageInfo, PluginManager};
2020
use std::fs;
2121
use std::process::{Command, Stdio};
@@ -34,6 +34,7 @@ async fn execute_code(
3434
history: State<'_, ExecutionHistory>,
3535
plugin_manager: State<'_, PluginManagerState>,
3636
) -> Result<ExecutionResult, String> {
37+
info!("执行代码 -> 调用插件 [ {} ] 开始", request.language);
3738
let manager = plugin_manager.lock().await;
3839
let plugin = manager
3940
.get_plugin(&request.language)
@@ -45,13 +46,16 @@ async fn execute_code(
4546
"codeforge_{}_{}.{}",
4647
request.language,
4748
execution_id,
48-
plugin.get_file_extension()
49+
plugin.get_file_extension().first().unwrap().to_string()
4950
));
5051

51-
// 预处理代码
52-
let processed_code = plugin
53-
.pre_execute_hook(&request.code)
54-
.map_err(|e| format!("Pre-execution hook failed: {}", e))?;
52+
let processed_code = plugin.pre_execute_hook(&request.code).map_err(|e| {
53+
error!(
54+
"执行代码 -> 调用插件 [ {} ] pre_execute_hook 出现错误 {:?}",
55+
request.language, e
56+
);
57+
format!("Pre-execution hook failed: {}", e)
58+
})?;
5559

5660
// 写入代码到临时文件
5761
fs::write(&file_path, &processed_code)
@@ -60,62 +64,62 @@ async fn execute_code(
6064
let start_time = std::time::Instant::now();
6165
let mut last_error = String::new();
6266

63-
// 尝试不同的命令
64-
for cmd in plugin.get_commands() {
65-
let args = plugin.get_execute_args(file_path.to_str().unwrap());
66-
debug!(
67-
"执行 {:?} 代码 -> 执行命令: {:?} 携带参数: {:?}",
68-
request.language, cmd, args
69-
);
70-
71-
let output = Command::new(cmd)
72-
.args(&args)
73-
.stdout(Stdio::piped())
74-
.stderr(Stdio::piped())
75-
.output();
76-
77-
match output {
78-
Ok(output) => {
79-
let execution_time = start_time.elapsed().as_millis();
80-
let timestamp = SystemTime::now()
81-
.duration_since(UNIX_EPOCH)
82-
.unwrap()
83-
.as_secs();
84-
85-
// 清理临时文件
86-
let _ = fs::remove_file(&file_path);
87-
88-
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
89-
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
90-
91-
let mut result = ExecutionResult {
92-
success: output.status.success(),
93-
stdout,
94-
stderr,
95-
execution_time,
96-
timestamp,
97-
language: request.language.clone(),
98-
};
99-
100-
// 后处理
101-
let _ = plugin.post_execute_hook(&mut result);
102-
103-
// 添加到执行历史
104-
drop(manager); // 释放插件管理器锁
105-
let mut history_guard = history.lock().await;
106-
history_guard.push(result.clone());
107-
108-
// 保持历史记录不超过100条
109-
if history_guard.len() > 100 {
110-
history_guard.remove(0);
111-
}
112-
113-
return Ok(result);
114-
}
115-
Err(e) => {
116-
last_error = format!("Failed to execute {} - {}", cmd, e);
117-
continue;
67+
let cmd = plugin.get_command();
68+
let args = plugin.get_execute_args(file_path.to_str().unwrap());
69+
info!(
70+
"执行代码 -> 调用插件 [ {} ] 执行命令 {} 携带参数 {}",
71+
request.language,
72+
cmd,
73+
args.join(" ")
74+
);
75+
76+
let output = Command::new(&cmd)
77+
.args(&args)
78+
.stdout(Stdio::piped())
79+
.stderr(Stdio::piped())
80+
.output();
81+
82+
match output {
83+
Ok(output) => {
84+
let execution_time = start_time.elapsed().as_millis();
85+
let timestamp = SystemTime::now()
86+
.duration_since(UNIX_EPOCH)
87+
.unwrap()
88+
.as_secs();
89+
90+
// 清理临时文件
91+
let _ = fs::remove_file(&file_path);
92+
93+
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
94+
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
95+
96+
let mut result = ExecutionResult {
97+
success: output.status.success(),
98+
stdout,
99+
stderr,
100+
execution_time,
101+
timestamp,
102+
language: request.language.clone(),
103+
};
104+
105+
// 后处理
106+
let _ = plugin.post_execute_hook(&mut result);
107+
108+
// 添加到执行历史
109+
drop(manager); // 释放插件管理器锁
110+
let mut history_guard = history.lock().await;
111+
history_guard.push(result.clone());
112+
113+
// 保持历史记录不超过100条
114+
if history_guard.len() > 100 {
115+
history_guard.remove(0);
118116
}
117+
118+
info!("执行代码 -> 调用插件 [ {} ] 完成", request.language);
119+
return Ok(result);
120+
}
121+
Err(e) => {
122+
last_error = format!("Failed to execute {} - {}", cmd, e);
119123
}
120124
}
121125

@@ -129,6 +133,7 @@ async fn execute_code(
129133
// 清理临时文件
130134
let _ = fs::remove_file(&file_path);
131135

136+
error!("执行代码 -> 调用插件 [ {} ] 失败", request.language);
132137
Ok(ExecutionResult {
133138
success: false,
134139
stdout: String::new(),
@@ -137,7 +142,7 @@ async fn execute_code(
137142
request.language,
138143
request.language,
139144
last_error,
140-
plugin.get_commands()
145+
plugin.get_command().to_string()
141146
),
142147
execution_time,
143148
timestamp,
@@ -151,51 +156,52 @@ async fn get_info(
151156
language: String,
152157
plugin_manager: State<'_, PluginManagerState>,
153158
) -> Result<LanguageInfo, String> {
159+
info!("获取环境 -> 调用插件 [ {} ] 开始", language);
154160
let manager = plugin_manager.lock().await;
155161
let plugin = manager
156162
.get_plugin(&language)
157163
.ok_or_else(|| format!("Unsupported language: {}", language))?;
158164

159-
// 尝试不同的命令
160-
for cmd in plugin.get_commands() {
161-
debug!("获取插件信息 -> 执行命令: {} 语言: {}", cmd, language);
162-
let version_output = Command::new(cmd).args(plugin.get_version_args()).output();
163-
164-
if let Ok(version_out) = version_output {
165-
if version_out.status.success() {
166-
let path_result = Command::new(cmd)
167-
.arg("-c")
168-
.arg(plugin.get_path_command())
169-
.output();
170-
171-
let version = String::from_utf8_lossy(&version_out.stdout)
172-
.trim()
173-
.to_string();
174-
175-
let path = if let Ok(path_out) = path_result {
176-
if path_out.status.success() {
177-
String::from_utf8_lossy(&path_out.stdout).trim().to_string()
178-
} else {
179-
"Command found but path unavailable".to_string()
180-
}
165+
let cmd = plugin.get_command();
166+
debug!("获取环境 -> 插件 [ {} ] 命令 {}", language, cmd);
167+
168+
let version_output = Command::new(&cmd).args(plugin.get_version_args()).output();
169+
if let Ok(version_out) = version_output {
170+
if version_out.status.success() {
171+
let path_result = Command::new(&cmd)
172+
.arg("-c")
173+
.arg(plugin.get_path_command())
174+
.output();
175+
176+
let version = String::from_utf8_lossy(&version_out.stdout)
177+
.trim()
178+
.to_string();
179+
180+
let path = if let Ok(path_out) = path_result {
181+
if path_out.status.success() {
182+
String::from_utf8_lossy(&path_out.stdout).trim().to_string()
181183
} else {
182-
"Path detection failed".to_string()
183-
};
184-
185-
return Ok(LanguageInfo {
186-
installed: true,
187-
version,
188-
path,
189-
language: plugin.get_language_name().to_string(),
190-
});
191-
}
184+
"Command found but path unavailable".to_string()
185+
}
186+
} else {
187+
"Path detection failed".to_string()
188+
};
189+
190+
info!("获取环境 -> 调用插件 [ {} ] 完成", language);
191+
return Ok(LanguageInfo {
192+
installed: true,
193+
version,
194+
path,
195+
language: plugin.get_language_name().to_string(),
196+
});
192197
}
193198
}
194199

200+
error!("获取环境 -> 调用插件 [ {} ] 失败", language);
195201
Ok(LanguageInfo {
196202
installed: false,
197203
version: "Not found".to_string(),
198-
path: format!("Not found - tried: {:?}", plugin.get_commands()),
204+
path: format!("Not found - tried: {:?}", plugin.get_command()),
199205
language: plugin.get_language_name().to_string(),
200206
})
201207
}

src-tauri/src/plugins/manager.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,8 @@ impl PluginManager {
5353
pub fn get_plugin_info(&self, language: &str) -> Option<PluginInfo> {
5454
self.get_plugin(language).map(|plugin| PluginInfo {
5555
name: plugin.get_language_name().to_string(),
56-
file_extension: plugin.get_file_extension().to_string(),
57-
available_commands: plugin
58-
.get_commands()
59-
.iter()
60-
.map(|s| s.to_string())
61-
.collect(),
56+
file_extension: plugin.get_file_extension().first().unwrap().to_string(),
57+
available_commands: vec![plugin.get_command().to_string()],
6258
})
6359
}
6460

@@ -68,12 +64,8 @@ impl PluginManager {
6864
.values()
6965
.map(|plugin| PluginInfo {
7066
name: plugin.get_language_name().to_string(),
71-
file_extension: plugin.get_file_extension().to_string(),
72-
available_commands: plugin
73-
.get_commands()
74-
.iter()
75-
.map(|s| s.to_string())
76-
.collect(),
67+
file_extension: plugin.get_file_extension().first().unwrap().to_string(),
68+
available_commands: vec![plugin.get_command().to_string()]
7769
})
7870
.collect()
7971
}

0 commit comments

Comments
 (0)