更改项目名为NebulaShell

This commit is contained in:
Falck
2026-05-02 08:30:31 +08:00
parent d16e28ab17
commit 2c2ec60a2b
233 changed files with 298 additions and 276 deletions

View File

@@ -0,0 +1,39 @@
# dependency 依赖解析
插件依赖关系管理,使用拓扑排序确定加载顺序。
## 功能
- 拓扑排序Kahn 算法)
- 循环依赖检测DFS
- 缺失依赖检测
- 自动按依赖顺序加载插件
## 使用
```python
dep = dependency_plugin
# 添加插件及其依赖
dep.add_plugin("plugin-a", ["plugin-b", "plugin-c"])
dep.add_plugin("plugin-b", [])
dep.add_plugin("plugin-c", ["plugin-b"])
# 解析依赖顺序
order = dep.resolve() # 返回 ["plugin-b", "plugin-c", "plugin-a"]
# 检查缺失依赖
missing = dep.get_missing_deps()
# 获取加载顺序
order = dep.get_order()
```
## manifest.json 声明
```json
{
"metadata": {...},
"dependencies": ["lifecycle", "circuit-breaker"]
}
```

View File

@@ -0,0 +1,8 @@
{
"signature": "JQaw//g6588907vGYH6SyqeXj9qHU5Azb7S/bjYm7rUrVsHqqIsIOEPB7IVsdf/wCnCdCa0LzTrEjmS6lKlEwXVjCCebhzyi64OJIXVOVckd2TJbREH0ZizO4KcEWgOqu56Ln3g8yMPHw5GylLABD5UN0q4F48PwUhram+cECu0SOY/bAHxYwi+nzJ0TcuES/J5cK480xv+NvxnylBhx1Udkkoiz9Y7b3pgglx+h57BuPEeHpJFbXQkXtty5Cf3sXzib0FEhicyIW1u5wmYSLz5yyLd/Pefavjfs6JrDG9J8gfPuestQzazQGsIMiQTy13DL8IDGAZ7AP2/mFQYrXuYLaBTxyhhMAkpfjIANzy+2pobeTZz2Cu4Sr6XMzXS4BkeCRDcHHBnttWVpp1+t5HpRgp3W8eiPcCzmUq6jo1cbd5zWGiR1gDEHePivmJaUi/bxlN0vyc7LjW7T+HuLUYhdSktbxv5BexMwcA7+2UHJzEnTVIc+xqoIT+ApPqqF2hLJFiAUdEJe8FRc/Bwihzh8tfM0xgYoqn8RQQ3eWVwVrK9vx0OZ8INumNZOyKPz8ZlGf3XAJv9UGUQ6Y42raYcDOFrgT+MS82tjAxf2nonm0/c3dhgNFZSy5Cfbvuqd9SYaxXejIcVni3MarVHZX3iKytOdv83cBtwPXRcfloc=",
"signer": "NebulaShell",
"algorithm": "RSA-SHA256",
"timestamp": 1775969851.9656692,
"plugin_hash": "aebef3fd9252245553bc458e4652b094839a5e64bde7cec13435ba1930a8dc0d",
"author": "NebulaShell"
}

View File

@@ -0,0 +1,138 @@
"""依赖解析插件 - 拓扑排序 + 循环依赖检测"""
from typing import Any, Optional
from oss.plugin.types import Plugin, register_plugin_type
class DependencyError(Exception):
"""依赖错误"""
pass
class DependencyResolver:
"""依赖解析器"""
def __init__(self):
self.graph: dict[str, list[str]] = {} # 插件名 -> 依赖列表
def add_plugin(self, name: str, dependencies: list[str]):
"""添加插件及其依赖"""
self.graph[name] = dependencies
def resolve(self) -> list[str]:
"""解析依赖,返回拓扑排序后的插件列表
例如A 依赖 BB 依赖 C
图: A -> [B], B -> [C], C -> []
结果: [C, B, A] (先启动没有依赖的,再启动依赖它们的)
"""
# 检测循环依赖
self._detect_cycles()
# 拓扑排序 (Kahn 算法 - 反向)
# in_degree[name] = name 依赖的插件数量
in_degree: dict[str, int] = {name: 0 for name in self.graph}
# 反向图: who_depends_on[dep] = [name1, name2, ...] (谁依赖 dep)
who_depends_on: dict[str, list[str]] = {name: [] for name in self.graph}
for name, deps in self.graph.items():
for dep in deps:
if dep in in_degree:
in_degree[name] += 1 # name 依赖 dep所以 name 的入度 +1
who_depends_on[dep].append(name) # dep 被 name 依赖
# 从没有依赖的插件开始
queue = [name for name, degree in in_degree.items() if degree == 0]
result = []
while queue:
node = queue.pop(0)
result.append(node)
# node 已启动,减少依赖它的插件的入度
for dependent in who_depends_on.get(node, []):
in_degree[dependent] -= 1
if in_degree[dependent] == 0:
queue.append(dependent)
if len(result) != len(self.graph):
raise DependencyError("无法解析依赖,可能存在循环依赖")
return result
def _detect_cycles(self):
"""检测循环依赖"""
visited = set()
rec_stack = set()
def dfs(node: str) -> bool:
visited.add(node)
rec_stack.add(node)
for dep in self.graph.get(node, []):
if dep not in visited:
if dfs(dep):
return True
elif dep in rec_stack:
raise DependencyError(f"检测到循环依赖: {node} -> {dep}")
rec_stack.remove(node)
return False
for node in self.graph:
if node not in visited:
if dfs(node):
raise DependencyError(f"检测到循环依赖涉及: {node}")
def get_missing(self) -> list[str]:
"""获取缺失的依赖"""
all_deps = set()
for deps in self.graph.values():
all_deps.update(deps)
all_plugins = set(self.graph.keys())
return list(all_deps - all_plugins)
class DependencyPlugin(Plugin):
"""依赖解析插件"""
def __init__(self):
self.resolver = DependencyResolver()
self.plugin_deps: dict[str, list[str]] = {}
def init(self, deps: dict = None):
"""初始化"""
pass
def start(self):
"""启动"""
pass
def stop(self):
"""停止"""
pass
def add_plugin(self, name: str, dependencies: list[str]):
"""添加插件及其依赖"""
self.plugin_deps[name] = dependencies
self.resolver.add_plugin(name, dependencies)
def resolve(self) -> list[str]:
"""解析依赖顺序"""
return self.resolver.resolve()
def get_missing_deps(self) -> list[str]:
"""获取缺失的依赖"""
return self.resolver.get_missing()
def get_order(self) -> list[str]:
"""获取插件加载顺序"""
return self.resolve()
# 注册类型
register_plugin_type("DependencyResolver", DependencyResolver)
register_plugin_type("DependencyError", DependencyError)
def New():
return DependencyPlugin()

View File

@@ -0,0 +1,15 @@
{
"metadata": {
"name": "dependency",
"version": "1.0.0",
"author": "NebulaShell",
"description": "依赖解析 - 拓扑排序 + 循环依赖检测",
"type": "core"
},
"config": {
"enabled": true,
"args": {}
},
"dependencies": [],
"permissions": []
}