Files
RuoYi-Vue3-FastAPI/ruoyi-fastapi-backend/cli/groups/plugin/commands/developer.py
T
insistence 2a055ba648 feat: 新增插件系统 (#112)
* feat: 初始化插件系统

* refactor: 收口插件系统运行时重构

* perf: 优化插件系统类型提示

* fix&perf: 修复和优化插件系统

* fix: 修复gitignore规则误忽略插件文件的问题

* fix: 修复运行时插件根路径算错的问题

* fix: 加强插件发现和路由注册的防护措施

* revert: 回滚定时任务白名单

* fix: 移除未使用的应用路由注册探测

* revert: 恢复部分代码

* perf: 优化插件系统

* docs: 新增插件开发文档

* perf: 优化插件管理模块

* perf: 提升插件系统核心能力

* refactor: 重构生命周期 step runner

* fix: 修复lint错误

* test: 清理测试用例

* test: 调整测试目录名称

* fix: 修复前后端目录硬编码的问题

* fix: 修复插件系统安全性缺口

* refactor: 重新设计插件生命周期 Migration 事务与回滚

* perf: 优化插件系统边界问题

* refactor: 重构当前插件系统的依赖体系设计

* perf: 优化代码

* perf: 优化代码

* fix: 修复代码合并问题

* fix: 修复bug

* perf: 优化代码

* perf&fix: 优化代码和修复bug

* docs: 优化文档格式

* feat: 适配Vue2版本

* docs: 更新README文档

* fix: 修复ruff lint错误

* chore: 更新后端依赖文件
2026-07-28 20:35:18 +08:00

110 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from collections.abc import Callable
from typing import Annotated, Any, Literal
import typer
from cli.context import DryRunOption, EnvOption, OutputOption
from ..options import PluginCreateCommandOptions
def register_developer_commands(app: typer.Typer, get_controller: Callable[[], Any]) -> None:
"""
注册插件开发者命令。
:param app: Typer 命令组
:param get_controller: 插件命令控制器工厂
:return: None
"""
@app.command('test', help='执行插件测试')
def test_command(
plugin_id: Annotated[str, typer.Argument(help='插件ID')],
env: EnvOption = 'dev',
output: OutputOption = 'text',
keyword: Annotated[str, typer.Option('--keyword', '-k', help='pytest -k 过滤表达式')] = '',
maxfail: Annotated[int, typer.Option('--maxfail', min=0, help='最大失败数,0 表示不限制')] = 0,
quiet: Annotated[bool, typer.Option('--quiet', '-q', help='启用简洁输出')] = False,
frontend_build: Annotated[bool, typer.Option('--frontend-build', help='追加执行前端构建验收')] = False,
) -> None:
"""
执行插件测试。
:param plugin_id: 插件ID
:param env: 当前命令运行环境
:param output: 输出格式
:param keyword: pytest 关键字过滤表达式
:param maxfail: 最大失败数
:param quiet: 是否启用简洁输出
:param frontend_build: 是否追加执行前端构建验收
:return: None
"""
get_controller().test_plugin(
plugin_id,
env,
output,
keyword=keyword,
maxfail=maxfail,
quiet=quiet,
frontend_build=frontend_build,
)
@app.command('create', help='创建插件开发模板')
def create_command( # noqa: PLR0913
plugin_id: Annotated[str, typer.Argument(help='插件ID')],
*,
env: EnvOption = 'dev',
output: OutputOption = 'text',
template: Annotated[
str,
typer.Option('--template', help='插件模板:minimal、backend-only、full-stack、scheduled-job、crud-page'),
] = 'full-stack',
frontend_version: Annotated[
Literal['auto', 'vue2', 'vue3'],
typer.Option('--frontend-version', help='前端 Vue 版本:auto、vue2、vue3auto 读取 package.json'),
] = 'auto',
backend_only: Annotated[bool, typer.Option('--backend-only', help='只创建后端插件模板')] = False,
frontend_only: Annotated[bool, typer.Option('--frontend-only', help='只创建前端插件模板')] = False,
no_migration: Annotated[bool, typer.Option('--no-migration', help='不创建 migration 示例')] = False,
no_seed: Annotated[bool, typer.Option('--no-seed', help='不创建 seed 示例')] = False,
no_job: Annotated[bool, typer.Option('--no-job', help='不创建定时任务示例')] = False,
no_config: Annotated[bool, typer.Option('--no-config', help='不创建配置项示例')] = False,
no_test: Annotated[bool, typer.Option('--no-test', help='不创建测试样例')] = False,
dry_run: DryRunOption = False,
) -> None:
"""
创建插件开发模板。
:param plugin_id: 插件ID
:param env: 当前命令运行环境
:param output: 输出格式
:param template: 插件模板名称
:param frontend_version: 前端 Vue 版本
:param backend_only: 是否只创建后端插件模板
:param frontend_only: 是否只创建前端插件模板
:param no_migration: 是否不创建 migration 示例
:param no_seed: 是否不创建 seed 示例
:param no_job: 是否不创建定时任务示例
:param no_config: 是否不创建配置项示例
:param no_test: 是否不创建测试样例
:param dry_run: 是否仅预演
:return: None
"""
get_controller().create_plugin(
plugin_id,
env,
output,
PluginCreateCommandOptions(
backend_only=backend_only,
frontend_only=frontend_only,
template=template,
frontend_version=frontend_version,
no_migration=no_migration,
no_seed=no_seed,
no_job=no_job,
no_config=no_config,
no_test=no_test,
dry_run=dry_run,
),
)