mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-15 21:35:31 +00:00
* feat: 支持 v2 插件、原生扩展与签名发布 * fix: 修复测试 * feat: 增强宿主 SDK、运行观测与制品维护能力 * feat: 增强文件传输、配置观测与本地开发能力 * feat: 支持 SSE 实时事件流并完善开发脚手架 * feat: 完善长连接鉴权复核与关闭回收 * feat: 增强生命周期与任务关闭可靠性 * feat: 收紧健康检查契约并补齐前端与真实网络验收 * feat: 增加SDK溯源与离线更新工具并验证跨版本兼容 * feat: 增加持久化业务示例与受控 Python 交付 * feat: 增加统一运行诊断与多worker状态观测 * feat: 增加固定目标发布等待与自动验收 * fix: 修复多环境插件部署前缀与代理配置不一致 * fix: 修复测试
134 lines
4.8 KiB
Python
134 lines
4.8 KiB
Python
import importlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Annotated, Any
|
|
|
|
import typer
|
|
|
|
from cli.context import CliContext, DryRunOption, OutputOption
|
|
from cli.core import DEFAULT_CORE_SERVICES
|
|
from cli.exit_codes import ARGUMENT_ERROR, DEPENDENCY_ERROR, RUNTIME_ERROR, SUCCESS
|
|
|
|
FrontendRootOption = Annotated[
|
|
Path | None,
|
|
typer.Option('--frontend-root', help='作为 SDK 来源的宿主前端目录,默认相邻前端或 RUOYI_PLUGIN_FRONTEND_ROOT'),
|
|
]
|
|
|
|
|
|
def _format_sdk_result(payload: dict[str, Any]) -> str:
|
|
"""
|
|
展示来源版本、检查状态和备份位置,方便人工核对更新结果。
|
|
|
|
:param payload: SDK 操作结果
|
|
:return: 文本输出
|
|
"""
|
|
lines = [f'ok: {str(payload.get("ok", False)).lower()}']
|
|
lines.extend(
|
|
f'{key}: {payload[key]}'
|
|
for key in (
|
|
'status',
|
|
'message',
|
|
'sdkVersion',
|
|
'currentSdkVersion',
|
|
'protocolCompatible',
|
|
'updateAvailable',
|
|
'backupDir',
|
|
)
|
|
if key in payload
|
|
)
|
|
if payload.get('files'):
|
|
lines.append('files: ' + json.dumps(payload['files'], ensure_ascii=False))
|
|
return '\n'.join(lines)
|
|
|
|
|
|
def _execute_sdk(
|
|
operation: str,
|
|
project: Path,
|
|
frontend_root: Path | None,
|
|
output: str,
|
|
*,
|
|
dry_run: bool = False,
|
|
force: bool = False,
|
|
) -> None:
|
|
"""
|
|
仅加载离线 SDK 文件服务,使用统一 CLI 输出和非零失败退出码。
|
|
|
|
:param operation: check 或 update
|
|
:param project: 独立 bundle 源码工程目录
|
|
:param frontend_root: 可选宿主前端源码目录
|
|
:param output: text 或 json
|
|
:param dry_run: 是否只预演更新
|
|
:param force: 是否备份后替换改动过或未跟踪的 SDK
|
|
:return: None
|
|
"""
|
|
try:
|
|
root = frontend_root or Path(
|
|
os.environ.get('RUOYI_PLUGIN_FRONTEND_ROOT')
|
|
or Path(__file__).resolve().parents[5] / 'ruoyi-fastapi-frontend'
|
|
)
|
|
service = importlib.import_module('cli.runtime.plugin.sdk').PluginBridgeSdk(root)
|
|
payload = (
|
|
service.check(project) if operation == 'check' else service.update(project, dry_run=dry_run, force=force)
|
|
)
|
|
code = SUCCESS if payload['ok'] else DEPENDENCY_ERROR
|
|
except ValueError as exc:
|
|
payload = {'ok': False, 'status': 'invalid', 'message': str(exc), 'error': str(exc)}
|
|
code = ARGUMENT_ERROR
|
|
except OSError as exc:
|
|
payload = {'ok': False, 'status': 'error', 'message': str(exc), 'error': str(exc)}
|
|
code = RUNTIME_ERROR
|
|
DEFAULT_CORE_SERVICES.execution_service.complete_payload_with_text(
|
|
CliContext(output=output, dry_run=dry_run),
|
|
payload,
|
|
text_builder=_format_sdk_result,
|
|
default_exit_code=code,
|
|
)
|
|
|
|
|
|
def register_sdk_commands(app: typer.Typer) -> None:
|
|
"""
|
|
注册纯离线 SDK 子命令,帮助查询不加载工程或宿主配置。
|
|
|
|
:param app: 插件命令组
|
|
:return: None
|
|
"""
|
|
sdk_app = typer.Typer(help='检查和显式更新独立 bundle 工程中的桥接 SDK', no_args_is_help=True)
|
|
app.add_typer(sdk_app, name='sdk')
|
|
|
|
@sdk_app.command('check', help='比较 SDK 版本、摘要和当前宿主副本,非 current 状态返回非零退出码')
|
|
def check_sdk(
|
|
project: Annotated[Path, typer.Argument(help='含 plugin.yaml 的独立 bundle 源码工程目录')],
|
|
frontend_root: FrontendRootOption = None,
|
|
output: OutputOption = 'text',
|
|
) -> None:
|
|
"""
|
|
检查源码工程的 SDK 来源与本地修改,不写文件或连接外部服务。
|
|
|
|
:param project: 独立 bundle 源码工程目录
|
|
:param frontend_root: 可选宿主前端源码目录
|
|
:param output: 输出格式
|
|
:return: None
|
|
"""
|
|
_execute_sdk('check', project, frontend_root, output)
|
|
|
|
@sdk_app.command('update', help='备份后更新 SDK 的三个文件;不会构建、安装或重启插件')
|
|
def update_sdk(
|
|
project: Annotated[Path, typer.Argument(help='含 plugin.yaml 的独立 bundle 源码工程目录')],
|
|
frontend_root: FrontendRootOption = None,
|
|
output: OutputOption = 'text',
|
|
dry_run: DryRunOption = False,
|
|
force: Annotated[bool, typer.Option('--force', help='备份后纳管旧副本或替换本地 SDK 修改')] = False,
|
|
) -> None:
|
|
"""
|
|
显式更新源码工程的 SDK;默认拒绝覆盖用户改动或来源不明的副本。
|
|
|
|
:param project: 独立 bundle 源码工程目录
|
|
:param frontend_root: 可选宿主前端源码目录
|
|
:param output: 输出格式
|
|
:param dry_run: 是否仅预演而不写入文件
|
|
:param force: 是否备份后替换改动或未跟踪副本
|
|
:return: None
|
|
"""
|
|
_execute_sdk('update', project, frontend_root, output, dry_run=dry_run, force=force)
|