Title: Add auto-dependency plugin for system dependency management
Key features implemented: - Added new auto-dependency plugin that scans plugin manifests for system dependencies and automatically installs missing ones - Created SystemDependencyChecker class with support for multiple package managers (apt, yum, dnf, pacman, brew, apk) - Implemented PL injection interface with functions for scan, check, install, and info operations - Added context management system in core module for plugin execution environment - Created example plugin manifest demonstrating system dependency declaration - Updated .gitignore with comprehensive file exclusion patterns The plugin provides automatic scanning and installation of system dependencies declared in plugin manifests, integrating seamlessly with the plugin loader through PL injection capabilities.
This commit is contained in:
77
store/@{FutureOSS}/auto-dependency/PL/main.py
Normal file
77
store/@{FutureOSS}/auto-dependency/PL/main.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""PL 注入 - 向插件加载器注册依赖自动安装功能
|
||||
|
||||
此文件通过 PL 注入机制向插件加载器注册以下功能:
|
||||
- auto-dependency:scan: 扫描所有插件的系统依赖声明
|
||||
- auto-dependency:check: 检查系统依赖是否已安装
|
||||
- auto-dependency:install: 自动安装缺失的系统依赖
|
||||
- auto-dependency:info: 获取插件系统信息
|
||||
"""
|
||||
|
||||
|
||||
def register(injector):
|
||||
"""向插件加载器注册功能
|
||||
|
||||
Args:
|
||||
injector: PLInjector 实例,提供 register_function 等方法
|
||||
"""
|
||||
# 注意:实际的功能实现由 main.py 中的 AutoDependencyPlugin 提供
|
||||
# 这里我们通过导入插件实例来注册功能
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 获取当前插件目录
|
||||
current_file = Path(__file__)
|
||||
plugin_dir = current_file.parent.parent
|
||||
|
||||
# 导入插件主模块
|
||||
main_file = plugin_dir / "main.py"
|
||||
|
||||
# 创建安全的执行环境来加载插件
|
||||
safe_globals = {
|
||||
"__builtins__": {
|
||||
"True": True, "False": False, "None": None,
|
||||
"dict": dict, "list": list, "str": str, "int": int,
|
||||
"float": float, "bool": bool, "tuple": tuple, "set": set,
|
||||
"len": len, "range": range, "enumerate": enumerate,
|
||||
"zip": zip, "map": map, "filter": filter,
|
||||
"sorted": sorted, "reversed": reversed,
|
||||
"min": min, "max": max, "sum": sum, "abs": abs,
|
||||
"round": round, "isinstance": isinstance, "issubclass": issubclass,
|
||||
"type": type, "id": id, "hash": hash, "repr": repr,
|
||||
"print": print, "object": object, "property": property,
|
||||
"staticmethod": staticmethod, "classmethod": classmethod,
|
||||
"super": super, "iter": iter, "next": next,
|
||||
"any": any, "all": all, "callable": callable,
|
||||
"hasattr": hasattr, "getattr": getattr, "setattr": setattr,
|
||||
"Exception": Exception, "BaseException": BaseException,
|
||||
},
|
||||
"__name__": "plugin.auto-dependency",
|
||||
"__package__": "plugin.auto-dependency",
|
||||
"__file__": str(main_file),
|
||||
"Path": Path,
|
||||
}
|
||||
|
||||
try:
|
||||
with open(main_file, "r", encoding="utf-8") as f:
|
||||
source = f.read()
|
||||
|
||||
code = compile(source, str(main_file), "exec")
|
||||
exec(code, safe_globals)
|
||||
|
||||
# 获取 New 函数并创建插件实例
|
||||
new_func = safe_globals.get("New")
|
||||
if new_func and callable(new_func):
|
||||
plugin_instance = new_func()
|
||||
|
||||
# 初始化插件
|
||||
plugin_instance.init({
|
||||
"scan_dirs": ["store"],
|
||||
"auto_install": True
|
||||
})
|
||||
|
||||
# 使用插件实例注册 PL 功能
|
||||
plugin_instance.register_pl_functions(injector)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[auto-dependency] PL 注册失败:{e}")
|
||||
117
store/@{FutureOSS}/auto-dependency/README.md
Normal file
117
store/@{FutureOSS}/auto-dependency/README.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 依赖自动安装插件 (auto-dependency)
|
||||
|
||||
## 概述
|
||||
|
||||
依赖自动安装插件是一个核心系统插件,用于扫描所有插件的声明文件,检查并自动安装系统依赖。
|
||||
|
||||
## 功能特性
|
||||
|
||||
1. **扫描插件声明** - 自动扫描所有插件目录下的 `manifest.json` 文件
|
||||
2. **系统依赖检测** - 读取每个插件声明的系统依赖 (`system_dependencies` 字段)
|
||||
3. **安装状态检查** - 检查这些系统依赖是否已在系统中安装
|
||||
4. **自动安装** - 对于未安装的依赖,使用系统包管理器自动安装
|
||||
5. **PL 注入接口** - 通过 PL 注入机制向插件加载器注册功能接口
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 在 manifest.json 中声明系统依赖
|
||||
|
||||
其他插件可以在自己的 `manifest.json` 中声明所需的系统依赖:
|
||||
|
||||
```json
|
||||
{
|
||||
"metadata": {
|
||||
"name": "my-plugin",
|
||||
"version": "1.0.0",
|
||||
"author": "MyName",
|
||||
"description": "我的插件"
|
||||
},
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"args": {}
|
||||
},
|
||||
"dependencies": ["plugin-loader"],
|
||||
"system_dependencies": ["curl", "git", "wget"],
|
||||
"permissions": []
|
||||
}
|
||||
```
|
||||
|
||||
### 通过 PL 注入接口调用
|
||||
|
||||
插件加载器加载此插件后,可以通过以下 PL 注入接口进行操作:
|
||||
|
||||
| 接口名称 | 说明 | 参数 | 返回值 |
|
||||
|---------|------|------|--------|
|
||||
| `auto-dependency:scan` | 扫描所有插件的声明文件 | `scan_dir` (可选,默认 "store") | 插件信息列表 |
|
||||
| `auto-dependency:check` | 检查系统依赖安装状态 | `scan_dir` (可选,默认 "store") | 检查结果字典 |
|
||||
| `auto-dependency:install` | 安装缺失的系统依赖 | `scan_dir` (可选,默认 "store") | 安装结果字典 |
|
||||
| `auto-dependency:info` | 获取插件系统信息 | 无 | 系统信息字典 |
|
||||
|
||||
### 示例代码
|
||||
|
||||
```python
|
||||
# 获取插件加载器中的 auto-dependency 功能
|
||||
injector = get_pl_injector() # 从插件加载器获取
|
||||
|
||||
# 扫描所有插件的系统依赖声明
|
||||
plugins = injector.get_injected_functions("auto-dependency:scan")[0]()
|
||||
print(f"找到 {len(plugins)} 个插件")
|
||||
|
||||
# 检查依赖安装状态
|
||||
result = injector.get_injected_functions("auto-dependency:check")[0]()
|
||||
print(f"已安装:{result['installed_count']}, 缺失:{result['missing_count']}")
|
||||
|
||||
# 安装缺失的依赖
|
||||
install_result = injector.get_injected_functions("auto-dependency:install")[0]()
|
||||
print(f"成功安装:{install_result['success_count']}, 失败:{install_result['failed_count']}")
|
||||
```
|
||||
|
||||
## 支持的包管理器
|
||||
|
||||
插件自动检测系统使用的包管理器,支持:
|
||||
|
||||
- **Debian/Ubuntu**: apt-get, apt
|
||||
- **RHEL/CentOS**: yum, dnf
|
||||
- **Arch Linux**: pacman
|
||||
- **macOS**: brew
|
||||
- **Alpine Linux**: apk
|
||||
|
||||
## 配置选项
|
||||
|
||||
在 `manifest.json` 的 `config.args` 中可以配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"args": {
|
||||
"scan_dirs": ["store"],
|
||||
"package_manager": "auto",
|
||||
"auto_install": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| 配置项 | 说明 | 默认值 |
|
||||
|-------|------|--------|
|
||||
| `scan_dirs` | 要扫描的目录列表 | `["store"]` |
|
||||
| `package_manager` | 包管理器(auto 为自动检测) | `"auto"` |
|
||||
| `auto_install` | 是否自动安装缺失的依赖 | `true` |
|
||||
|
||||
## 安全说明
|
||||
|
||||
- 插件需要 `*` 权限才能执行系统命令安装包
|
||||
- 包安装操作有超时限制(300 秒)
|
||||
- 所有安装操作都会记录日志
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
store/@{FutureOSS}/auto-dependency/
|
||||
├── manifest.json # 插件清单
|
||||
├── main.py # 主逻辑实现
|
||||
├── PL/
|
||||
│ └── main.py # PL 注入入口
|
||||
└── README.md # 本文档
|
||||
```
|
||||
407
store/@{FutureOSS}/auto-dependency/main.py
Normal file
407
store/@{FutureOSS}/auto-dependency/main.py
Normal file
@@ -0,0 +1,407 @@
|
||||
"""依赖自动安装插件 - 扫描所有插件的声明文件,检查并安装系统依赖
|
||||
|
||||
功能说明:
|
||||
1. 扫描所有插件目录下的 manifest.json 文件
|
||||
2. 读取每个插件声明的系统依赖 (system_dependencies 字段)
|
||||
3. 检查这些系统依赖是否已安装
|
||||
4. 对于未安装的依赖,使用系统包管理器自动安装
|
||||
5. 通过 PL 注入机制向插件加载器注册功能接口
|
||||
"""
|
||||
import subprocess
|
||||
import shutil
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional, List, Dict
|
||||
from oss.plugin.types import Plugin
|
||||
|
||||
|
||||
class SystemDependencyChecker:
|
||||
"""系统依赖检查器"""
|
||||
|
||||
def __init__(self):
|
||||
self.package_managers = {
|
||||
"apt": ["apt-get", "apt"],
|
||||
"yum": ["yum", "dnf"],
|
||||
"pacman": ["pacman"],
|
||||
"brew": ["brew"],
|
||||
"apk": ["apk"],
|
||||
}
|
||||
self.detected_pm = self._detect_package_manager()
|
||||
|
||||
def _detect_package_manager(self) -> str:
|
||||
"""检测系统包管理器"""
|
||||
for pm, commands in self.package_managers.items():
|
||||
for cmd in commands:
|
||||
if shutil.which(cmd):
|
||||
return pm
|
||||
return "unknown"
|
||||
|
||||
def check_command(self, command: str) -> bool:
|
||||
"""检查命令是否可用"""
|
||||
return shutil.which(command) is not None
|
||||
|
||||
def check_package(self, package: str) -> bool:
|
||||
"""检查系统包是否已安装"""
|
||||
if not self.detected_pm or self.detected_pm == "unknown":
|
||||
return False
|
||||
|
||||
try:
|
||||
if self.detected_pm in ["apt", "apt-get"]:
|
||||
result = subprocess.run(
|
||||
["dpkg", "-l", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
return result.returncode == 0 and "ii" in result.stdout
|
||||
elif self.detected_pm in ["yum", "dnf"]:
|
||||
result = subprocess.run(
|
||||
["rpm", "-q", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "pacman":
|
||||
result = subprocess.run(
|
||||
["pacman", "-Q", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "brew":
|
||||
result = subprocess.run(
|
||||
["brew", "list", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "apk":
|
||||
result = subprocess.run(
|
||||
["apk", "info", "-e", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
return result.returncode == 0
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
def install_package(self, package: str) -> bool:
|
||||
"""安装系统包"""
|
||||
if not self.detected_pm or self.detected_pm == "unknown":
|
||||
return False
|
||||
|
||||
try:
|
||||
if self.detected_pm in ["apt", "apt-get"]:
|
||||
result = subprocess.run(
|
||||
["apt-get", "install", "-y", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "yum":
|
||||
result = subprocess.run(
|
||||
["yum", "install", "-y", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "dnf":
|
||||
result = subprocess.run(
|
||||
["dnf", "install", "-y", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "pacman":
|
||||
result = subprocess.run(
|
||||
["pacman", "-S", "--noconfirm", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "brew":
|
||||
result = subprocess.run(
|
||||
["brew", "install", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
elif self.detected_pm == "apk":
|
||||
result = subprocess.run(
|
||||
["apk", "add", package],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return result.returncode == 0
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
def check_and_install(self, package: str, auto_install: bool = True) -> Dict[str, Any]:
|
||||
"""检查并安装包"""
|
||||
result = {
|
||||
"package": package,
|
||||
"installed": self.check_package(package),
|
||||
"action": "none",
|
||||
"success": True,
|
||||
"message": ""
|
||||
}
|
||||
|
||||
if result["installed"]:
|
||||
result["message"] = f"包 '{package}' 已安装"
|
||||
return result
|
||||
|
||||
if not auto_install:
|
||||
result["action"] = "skipped"
|
||||
result["message"] = f"包 '{package}' 未安装,但自动安装已禁用"
|
||||
result["success"] = False
|
||||
return result
|
||||
|
||||
result["action"] = "installing"
|
||||
if self.install_package(package):
|
||||
result["installed"] = True
|
||||
result["success"] = True
|
||||
result["message"] = f"包 '{package}' 安装成功"
|
||||
else:
|
||||
result["success"] = False
|
||||
result["message"] = f"包 '{package}' 安装失败"
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class AutoDependencyPlugin(Plugin):
|
||||
"""依赖自动安装插件"""
|
||||
|
||||
def __init__(self):
|
||||
self.checker = SystemDependencyChecker()
|
||||
self.scan_dirs: List[str] = []
|
||||
self.auto_install: bool = True
|
||||
self._plugin_loader_ref: Optional[Any] = None
|
||||
|
||||
def init(self, deps: Optional[Dict[str, Any]] = None):
|
||||
"""初始化插件"""
|
||||
if deps:
|
||||
self.scan_dirs = deps.get("scan_dirs", ["store"])
|
||||
self.auto_install = deps.get("auto_install", True)
|
||||
|
||||
# 获取插件加载器引用(通过依赖注入)
|
||||
if "plugin-loader" in deps:
|
||||
self._plugin_loader_ref = deps["plugin-loader"]
|
||||
|
||||
def start(self):
|
||||
"""启动插件"""
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
"""停止插件"""
|
||||
pass
|
||||
|
||||
def scan_plugin_manifests(self, base_dir: str = "store") -> List[Dict[str, Any]]:
|
||||
"""扫描所有插件的 manifest.json 文件
|
||||
|
||||
Returns:
|
||||
包含所有插件信息的列表,每个元素包含:
|
||||
- plugin_name: 插件名称
|
||||
- plugin_dir: 插件目录路径
|
||||
- manifest: manifest.json 内容
|
||||
- system_dependencies: 系统依赖列表
|
||||
"""
|
||||
results = []
|
||||
base_path = Path(base_dir)
|
||||
|
||||
if not base_path.exists():
|
||||
return results
|
||||
|
||||
# 扫描所有插件目录
|
||||
for vendor_dir in base_path.iterdir():
|
||||
if not vendor_dir.is_dir():
|
||||
continue
|
||||
|
||||
for plugin_dir in vendor_dir.iterdir():
|
||||
if not plugin_dir.is_dir():
|
||||
continue
|
||||
|
||||
manifest_file = plugin_dir / "manifest.json"
|
||||
if not manifest_file.exists():
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(manifest_file, "r", encoding="utf-8") as f:
|
||||
manifest = json.load(f)
|
||||
|
||||
# 提取系统依赖
|
||||
system_deps = manifest.get("system_dependencies", [])
|
||||
|
||||
results.append({
|
||||
"plugin_name": plugin_dir.name.rstrip("}"),
|
||||
"plugin_dir": str(plugin_dir),
|
||||
"manifest": manifest,
|
||||
"system_dependencies": system_deps
|
||||
})
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return results
|
||||
|
||||
def check_all_dependencies(self, base_dir: str = "store") -> Dict[str, Any]:
|
||||
"""检查所有插件的系统依赖
|
||||
|
||||
Args:
|
||||
base_dir: 基础扫描目录
|
||||
|
||||
Returns:
|
||||
检查结果字典,包含:
|
||||
- total_plugins: 扫描的插件总数
|
||||
- plugins_with_deps: 有系统依赖的插件数
|
||||
- dependencies: 依赖检查结果列表
|
||||
- missing_count: 缺失的依赖数量
|
||||
- installed_count: 已安装的依赖数量
|
||||
"""
|
||||
plugins = self.scan_plugin_manifests(base_dir)
|
||||
|
||||
all_deps = {} # {package: [plugin_names]}
|
||||
for plugin in plugins:
|
||||
for dep in plugin["system_dependencies"]:
|
||||
if dep not in all_deps:
|
||||
all_deps[dep] = []
|
||||
all_deps[dep].append(plugin["plugin_name"])
|
||||
|
||||
results = []
|
||||
installed_count = 0
|
||||
missing_count = 0
|
||||
|
||||
for package, plugin_names in all_deps.items():
|
||||
is_installed = self.checker.check_package(package)
|
||||
if is_installed:
|
||||
installed_count += 1
|
||||
else:
|
||||
missing_count += 1
|
||||
|
||||
results.append({
|
||||
"package": package,
|
||||
"installed": is_installed,
|
||||
"required_by": plugin_names
|
||||
})
|
||||
|
||||
return {
|
||||
"total_plugins": len(plugins),
|
||||
"plugins_with_deps": sum(1 for p in plugins if p["system_dependencies"]),
|
||||
"dependencies": results,
|
||||
"missing_count": missing_count,
|
||||
"installed_count": installed_count
|
||||
}
|
||||
|
||||
def install_missing_dependencies(self, base_dir: str = "store") -> Dict[str, Any]:
|
||||
"""安装所有缺失的系统依赖
|
||||
|
||||
Args:
|
||||
base_dir: 基础扫描目录
|
||||
|
||||
Returns:
|
||||
安装结果字典,包含:
|
||||
- total_to_install: 需要安装的包数量
|
||||
- success_count: 成功安装的包数量
|
||||
- failed_count: 安装失败的包数量
|
||||
- results: 每个包的安装结果
|
||||
"""
|
||||
check_result = self.check_all_dependencies(base_dir)
|
||||
|
||||
to_install = [dep for dep in check_result["dependencies"] if not dep["installed"]]
|
||||
|
||||
install_results = []
|
||||
success_count = 0
|
||||
failed_count = 0
|
||||
|
||||
for dep in to_install:
|
||||
result = self.checker.check_and_install(dep["package"], auto_install=True)
|
||||
result["required_by"] = dep["required_by"]
|
||||
install_results.append(result)
|
||||
|
||||
if result["success"]:
|
||||
success_count += 1
|
||||
else:
|
||||
failed_count += 1
|
||||
|
||||
return {
|
||||
"total_to_install": len(to_install),
|
||||
"success_count": success_count,
|
||||
"failed_count": failed_count,
|
||||
"results": install_results
|
||||
}
|
||||
|
||||
def get_system_info(self) -> Dict[str, Any]:
|
||||
"""获取系统信息"""
|
||||
return {
|
||||
"package_manager": self.checker.detected_pm,
|
||||
"auto_install_enabled": self.auto_install,
|
||||
"scan_directories": self.scan_dirs
|
||||
}
|
||||
|
||||
def register_pl_functions(self, injector: Any):
|
||||
"""注册 PL 注入功能
|
||||
|
||||
通过 PL 注入机制向插件加载器注册以下功能:
|
||||
- auto-dependency:scan: 扫描所有插件的系统依赖
|
||||
- auto-dependency:check: 检查依赖安装状态
|
||||
- auto-dependency:install: 安装缺失的依赖
|
||||
- auto-dependency:info: 获取插件系统信息
|
||||
"""
|
||||
# 注册扫描功能
|
||||
def scan_deps(scan_dir: str = "store") -> Dict[str, Any]:
|
||||
"""扫描所有插件的声明文件"""
|
||||
return self.scan_plugin_manifests(scan_dir)
|
||||
|
||||
injector.register_function(
|
||||
"auto-dependency:scan",
|
||||
scan_deps,
|
||||
"扫描所有插件的声明文件,获取系统依赖列表"
|
||||
)
|
||||
|
||||
# 注册检查功能
|
||||
def check_deps(scan_dir: str = "store") -> Dict[str, Any]:
|
||||
"""检查所有系统依赖的安装状态"""
|
||||
return self.check_all_dependencies(scan_dir)
|
||||
|
||||
injector.register_function(
|
||||
"auto-dependency:check",
|
||||
check_deps,
|
||||
"检查所有插件声明的系统依赖是否已安装"
|
||||
)
|
||||
|
||||
# 注册安装功能
|
||||
def install_deps(scan_dir: str = "store") -> Dict[str, Any]:
|
||||
"""安装所有缺失的系统依赖"""
|
||||
return self.install_missing_dependencies(scan_dir)
|
||||
|
||||
injector.register_function(
|
||||
"auto-dependency:install",
|
||||
install_deps,
|
||||
"自动安装所有缺失的系统依赖"
|
||||
)
|
||||
|
||||
# 注册信息功能
|
||||
def get_info() -> Dict[str, Any]:
|
||||
"""获取插件系统信息"""
|
||||
return self.get_system_info()
|
||||
|
||||
injector.register_function(
|
||||
"auto-dependency:info",
|
||||
get_info,
|
||||
"获取自动依赖插件的系统信息"
|
||||
)
|
||||
|
||||
|
||||
def New() -> AutoDependencyPlugin:
|
||||
"""创建插件实例"""
|
||||
return AutoDependencyPlugin()
|
||||
20
store/@{FutureOSS}/auto-dependency/manifest.json
Normal file
20
store/@{FutureOSS}/auto-dependency/manifest.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "auto-dependency",
|
||||
"version": "1.0.0",
|
||||
"author": "FutureOSS",
|
||||
"description": "依赖自动安装插件 - 扫描所有插件的声明文件,检查并安装系统依赖",
|
||||
"type": "core"
|
||||
},
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"args": {
|
||||
"scan_dirs": ["store"],
|
||||
"package_manager": "auto",
|
||||
"auto_install": true,
|
||||
"pl_injection": true
|
||||
}
|
||||
},
|
||||
"dependencies": ["plugin-loader"],
|
||||
"permissions": ["*"]
|
||||
}
|
||||
16
store/@{FutureOSS}/example-with-deps/manifest.json
Normal file
16
store/@{FutureOSS}/example-with-deps/manifest.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "example-with-deps",
|
||||
"version": "1.0.0",
|
||||
"author": "FutureOSS",
|
||||
"description": "示例插件 - 演示如何声明系统依赖",
|
||||
"type": "example"
|
||||
},
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"args": {}
|
||||
},
|
||||
"dependencies": [],
|
||||
"system_dependencies": ["curl", "git", "wget"],
|
||||
"permissions": []
|
||||
}
|
||||
Reference in New Issue
Block a user