fix(plugin): preserve market package generation

This commit is contained in:
jxxghp
2026-08-27 22:46:03 +08:00
parent cb139ee20d
commit 988b425510
3 changed files with 48 additions and 6 deletions
@@ -86,6 +86,7 @@ class PluginMetadataMapper:
plugin.history = info.get("history") or {}
plugin.release = bool(info.get("release"))
plugin.repo_url = market
plugin.package_version = package_version
plugin.is_local = False
plugin.add_time = add_time
return plugin
+14 -2
View File
@@ -1,7 +1,7 @@
from enum import Enum as _Enum
from typing import Literal, Optional, List, Dict, Union
from typing import Dict, List, Literal, Optional, Union
from pydantic import BaseModel, Field, RootModel, field_validator
from pydantic import BaseModel, Field, PrivateAttr, RootModel, field_validator
from app.schemas.common import JsonData
@@ -62,6 +62,8 @@ class Plugin(BaseModel):
"""
插件信息
"""
_package_version: Optional[str] = PrivateAttr(default=None)
id: str = None
# 插件名称
plugin_name: Optional[str] = None
@@ -124,6 +126,16 @@ class Plugin(BaseModel):
# 实例实现模式;存量物理分身为空
instance_mode: Optional[str] = None
@property
def package_version(self) -> Optional[str]:
"""读取仅供宿主内部候选选择使用的插件包代际。"""
return self._package_version
@package_version.setter
def package_version(self, value: Optional[str]) -> None:
"""保存插件包代际,但不把它暴露到 API 响应模型。"""
self._package_version = value
class PluginRuntimeSummary(BaseModel):
"""插件后台收敛状态和前端刷新代次。"""
+33 -4
View File
@@ -1,11 +1,12 @@
import asyncio
from types import SimpleNamespace
from unittest.mock import Mock
import pytest
from packaging.version import Version
from app.application.plugin.catalog import PluginCatalogService
from app.runtime.extensions.plugin.metadata import PluginMetadataMapper
from app.schemas.plugin import Plugin
def _plugin(
@@ -13,14 +14,15 @@ def _plugin(
version: str,
repo_url: str,
package_version: str | None = "v3",
):
) -> Plugin:
"""构造目录合并测试使用的最小插件 DTO。"""
return SimpleNamespace(
plugin = Plugin(
id=plugin_id,
plugin_version=version,
repo_url=repo_url,
package_version=package_version,
)
plugin.package_version = package_version
return plugin
def _service(**overrides) -> PluginCatalogService:
@@ -132,6 +134,33 @@ def test_load_maps_market_entries_with_installed_snapshot():
assert mapper.call_args_list[1].args[3:] == (["Installed"], 1, "v3")
def test_metadata_mapper_preserves_package_generation_without_serializing_it():
"""市场映射必须保留候选代际,同时不能扩张插件 API 响应。"""
mapper = PluginMetadataMapper(
plugin_instance=lambda _plugin_id: None,
plugin_class=lambda _plugin_id: None,
annotate_system_version=lambda info: info,
is_package_compatible=lambda _info, _version: True,
auth_checker=lambda _plugin, _source: True,
version_compare=lambda _left, _operator, _right: False,
log=Mock(),
)
plugin = mapper.map(
plugin_id="Demo",
plugin_info={"name": "Demo", "version": "3.0.0"},
market="https://market-a",
installed_plugins=[],
add_time=1,
package_version="v3",
)
assert plugin is not None
assert plugin.package_version == "v3"
assert "package_version" not in plugin.model_dump()
assert "package_version" not in Plugin.model_json_schema()["properties"]
@pytest.mark.asyncio
async def test_async_collect_isolates_failure_and_completes_progress():
"""异步市场单任务失败时保留成功结果,并把进度推进到完成态。"""