Feature: 添加插件元信息定义 (#1046)

This commit is contained in:
Ju4tCode 2022-06-20 15:49:53 +08:00 committed by GitHub
parent a82ce00a4b
commit 06ee47edcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 4 deletions

View File

@ -129,6 +129,7 @@ from .on import on_startswith as on_startswith
from .load import load_from_json as load_from_json from .load import load_from_json as load_from_json
from .load import load_from_toml as load_from_toml from .load import load_from_toml as load_from_toml
from .on import on_shell_command as on_shell_command from .on import on_shell_command as on_shell_command
from .plugin import PluginMetadata as PluginMetadata
from .load import load_all_plugins as load_all_plugins from .load import load_all_plugins as load_all_plugins
from .load import load_builtin_plugin as load_builtin_plugin from .load import load_builtin_plugin as load_builtin_plugin
from .load import load_builtin_plugins as load_builtin_plugins from .load import load_builtin_plugins as load_builtin_plugins

View File

@ -19,7 +19,7 @@ from typing import Set, Dict, List, Union, Iterable, Optional, Sequence
from nonebot.log import logger from nonebot.log import logger
from nonebot.utils import escape_tag from nonebot.utils import escape_tag
from .plugin import Plugin from .plugin import Plugin, PluginMetadata
from . import ( from . import (
_managers, _managers,
_new_plugin, _new_plugin,
@ -242,6 +242,10 @@ class PluginLoader(SourceFileLoader):
# leave plugin context # leave plugin context
_current_plugin.reset(_plugin_token) _current_plugin.reset(_plugin_token)
# get plugin metadata
metadata: Optional[PluginMetadata] = getattr(module, "__plugin_meta__", None)
plugin.metadata = metadata
return return

View File

@ -6,7 +6,9 @@ FrontMatter:
""" """
from types import ModuleType from types import ModuleType
from dataclasses import field, dataclass from dataclasses import field, dataclass
from typing import TYPE_CHECKING, Set, Type, Optional from typing import TYPE_CHECKING, Any, Set, Dict, Type, Optional
from pydantic import BaseModel
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
@ -18,11 +20,26 @@ if TYPE_CHECKING:
@dataclass(eq=False) @dataclass(eq=False)
class Plugin(object): class PluginMetadata:
"""插件元信息,由插件编写者提供"""
name: str
"""插件可阅读名称"""
description: str
"""插件功能介绍"""
usage: str
"""插件使用方法"""
config: Optional[Type[BaseModel]] = None
"""插件配置项"""
extra: Dict[Any, Any] = field(default_factory=dict)
@dataclass(eq=False)
class Plugin:
"""存储插件信息""" """存储插件信息"""
name: str name: str
"""插件名称,使用 文件/文件夹 名称作为插件名""" """插件索引标识NoneBot 使用 文件/文件夹 名称作为标识符"""
module: ModuleType module: ModuleType
"""插件模块对象""" """插件模块对象"""
module_name: str module_name: str
@ -37,3 +54,4 @@ class Plugin(object):
"""父插件""" """父插件"""
sub_plugins: Set["Plugin"] = field(default_factory=set) sub_plugins: Set["Plugin"] = field(default_factory=set)
"""子插件集合""" """子插件集合"""
metadata: Optional[PluginMetadata] = None

16
tests/plugins/metadata.py Normal file
View File

@ -0,0 +1,16 @@
from pydantic import BaseModel
from nonebot.plugin import PluginMetadata
class Config(BaseModel):
custom: str = ""
__plugin_meta__ = PluginMetadata(
name="测试插件",
description="测试插件元信息",
usage="无法使用",
config=Config,
extra={"author": "NoneBot"},
)

View File

@ -1,4 +1,5 @@
import sys import sys
from dataclasses import asdict
from typing import TYPE_CHECKING, Set from typing import TYPE_CHECKING, Set
import pytest import pytest
@ -98,3 +99,20 @@ async def test_require_not_found(app: App):
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
nonebot.require("some_plugin_not_exist") nonebot.require("some_plugin_not_exist")
@pytest.mark.asyncio
async def test_plugin_metadata(app: App, load_plugin: Set["Plugin"]):
import nonebot
from plugins.metadata import Config
plugin = nonebot.get_plugin("metadata")
assert plugin
assert plugin.metadata
assert asdict(plugin.metadata) == {
"name": "测试插件",
"description": "测试插件元信息",
"usage": "无法使用",
"config": Config,
"extra": {"author": "NoneBot"},
}