77import subprocess
88import sys
99import importlib
10- from typing import List , Dict , Tuple , Optional
11- from pathlib import Path
10+ from typing import List , Dict , Tuple
1211
1312from src .common .logger import get_logger
1413from src .plugin_system .base .component_types import PythonDependency
@@ -22,19 +21,21 @@ class DependencyManager:
2221 def __init__ (self ):
2322 self .install_log : List [str ] = []
2423 self .failed_installs : Dict [str , str ] = {}
25-
26- def check_dependencies (self , dependencies : List [PythonDependency ]) -> Tuple [List [PythonDependency ], List [PythonDependency ]]:
24+
25+ def check_dependencies (
26+ self , dependencies : List [PythonDependency ]
27+ ) -> Tuple [List [PythonDependency ], List [PythonDependency ]]:
2728 """检查依赖包状态
28-
29+
2930 Args:
3031 dependencies: 依赖包列表
31-
32+
3233 Returns:
3334 Tuple[List[PythonDependency], List[PythonDependency]]: (缺失的依赖, 可选缺失的依赖)
3435 """
3536 missing_required = []
3637 missing_optional = []
37-
38+
3839 for dep in dependencies :
3940 if not self ._is_package_available (dep .package_name ):
4041 if dep .optional :
@@ -45,71 +46,71 @@ def check_dependencies(self, dependencies: List[PythonDependency]) -> Tuple[List
4546 logger .error (f"必需依赖包缺失: { dep .package_name } - { dep .description } " )
4647 else :
4748 logger .debug (f"依赖包已存在: { dep .package_name } " )
48-
49+
4950 return missing_required , missing_optional
50-
51+
5152 def _is_package_available (self , package_name : str ) -> bool :
5253 """检查包是否可用"""
5354 try :
5455 importlib .import_module (package_name )
5556 return True
5657 except ImportError :
5758 return False
58-
59+
5960 def install_dependencies (self , dependencies : List [PythonDependency ], auto_install : bool = False ) -> bool :
6061 """安装依赖包
61-
62+
6263 Args:
6364 dependencies: 需要安装的依赖包列表
6465 auto_install: 是否自动安装(True时不询问用户)
65-
66+
6667 Returns:
6768 bool: 安装是否成功
6869 """
6970 if not dependencies :
7071 return True
71-
72+
7273 logger .info (f"需要安装 { len (dependencies )} 个依赖包" )
73-
74+
7475 # 显示将要安装的包
7576 for dep in dependencies :
7677 install_cmd = dep .get_pip_requirement ()
7778 logger .info (f" - { install_cmd } { '(可选)' if dep .optional else '(必需)' } " )
7879 if dep .description :
7980 logger .info (f" 说明: { dep .description } " )
80-
81+
8182 if not auto_install :
8283 # 这里可以添加用户确认逻辑
8384 logger .warning ("手动安装模式:请手动运行 pip install 命令安装依赖包" )
8485 return False
85-
86+
8687 # 执行安装
8788 success_count = 0
8889 for dep in dependencies :
8990 if self ._install_single_package (dep ):
9091 success_count += 1
9192 else :
9293 self .failed_installs [dep .package_name ] = f"安装失败: { dep .get_pip_requirement ()} "
93-
94+
9495 logger .info (f"依赖安装完成: { success_count } /{ len (dependencies )} 个成功" )
9596 return success_count == len (dependencies )
96-
97+
9798 def _install_single_package (self , dependency : PythonDependency ) -> bool :
9899 """安装单个包"""
99100 pip_requirement = dependency .get_pip_requirement ()
100-
101+
101102 try :
102103 logger .info (f"正在安装: { pip_requirement } " )
103-
104+
104105 # 使用subprocess安装包
105106 cmd = [sys .executable , "-m" , "pip" , "install" , pip_requirement ]
106107 result = subprocess .run (
107108 cmd ,
108109 capture_output = True ,
109110 text = True ,
110- timeout = 300 # 5分钟超时
111+ timeout = 300 , # 5分钟超时
111112 )
112-
113+
113114 if result .returncode == 0 :
114115 logger .info (f"✅ 成功安装: { pip_requirement } " )
115116 self .install_log .append (f"成功安装: { pip_requirement } " )
@@ -119,28 +120,29 @@ def _install_single_package(self, dependency: PythonDependency) -> bool:
119120 logger .error (f"错误输出: { result .stderr } " )
120121 self .install_log .append (f"安装失败: { pip_requirement } - { result .stderr } " )
121122 return False
122-
123+
123124 except subprocess .TimeoutExpired :
124125 logger .error (f"❌ 安装超时: { pip_requirement } " )
125126 return False
126127 except Exception as e :
127128 logger .error (f"❌ 安装异常: { pip_requirement } - { str (e )} " )
128129 return False
129-
130- def generate_requirements_file (self , plugins_dependencies : List [List [PythonDependency ]],
131- output_path : str = "plugin_requirements.txt" ) -> bool :
130+
131+ def generate_requirements_file (
132+ self , plugins_dependencies : List [List [PythonDependency ]], output_path : str = "plugin_requirements.txt"
133+ ) -> bool :
132134 """生成插件依赖的requirements文件
133-
135+
134136 Args:
135137 plugins_dependencies: 所有插件的依赖列表
136138 output_path: 输出文件路径
137-
139+
138140 Returns:
139141 bool: 生成是否成功
140142 """
141143 try :
142144 all_deps = {}
143-
145+
144146 # 合并所有插件的依赖
145147 for plugin_deps in plugins_dependencies :
146148 for dep in plugin_deps :
@@ -152,39 +154,39 @@ def generate_requirements_file(self, plugins_dependencies: List[List[PythonDepen
152154 logger .warning (f"依赖版本冲突: { key } ({ existing .version } vs { dep .version } )" )
153155 else :
154156 all_deps [key ] = dep
155-
157+
156158 # 写入requirements文件
157159 with open (output_path , "w" , encoding = "utf-8" ) as f :
158160 f .write ("# 插件依赖包自动生成\n " )
159161 f .write ("# Auto-generated plugin dependencies\n \n " )
160-
162+
161163 # 按包名排序
162164 sorted_deps = sorted (all_deps .values (), key = lambda x : x .install_name )
163-
165+
164166 for dep in sorted_deps :
165167 requirement = dep .get_pip_requirement ()
166168 if dep .description :
167169 f .write (f"# { dep .description } \n " )
168170 if dep .optional :
169- f .write (f "# Optional dependency\n " )
171+ f .write ("# Optional dependency\n " )
170172 f .write (f"{ requirement } \n \n " )
171-
173+
172174 logger .info (f"已生成插件依赖文件: { output_path } ({ len (all_deps )} 个包)" )
173175 return True
174-
176+
175177 except Exception as e :
176178 logger .error (f"生成requirements文件失败: { str (e )} " )
177179 return False
178-
180+
179181 def get_install_summary (self ) -> Dict [str , any ]:
180182 """获取安装摘要"""
181183 return {
182184 "install_log" : self .install_log .copy (),
183185 "failed_installs" : self .failed_installs .copy (),
184186 "total_attempts" : len (self .install_log ),
185- "failed_count" : len (self .failed_installs )
187+ "failed_count" : len (self .failed_installs ),
186188 }
187189
188190
189191# 全局依赖管理器实例
190- dependency_manager = DependencyManager ()
192+ dependency_manager = DependencyManager ()
0 commit comments