From a7a19a30241613727decf081a081fb2cde71d4f9 Mon Sep 17 00:00:00 2001 From: KimigaiiWuyi <444835641@qq.com> Date: Sat, 28 Sep 2024 05:26:30 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20=E5=A4=A7=E5=B9=85=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=90=AF=E5=8A=A8=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?/=E5=AE=89=E8=A3=85=E4=BE=9D=E8=B5=96=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E5=BC=8F,=20=E5=85=81=E8=AE=B8=E6=8F=92=E4=BB=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0`gscore=5Fauto=5Fupdate=5Fdep`=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game_record.json | 1 + .../core_command/core_update/__init__.py | 4 +- gsuid_core/server.py | 113 ++++++++++-------- .../utils/plugins_config/config_default.py | 9 +- gsuid_core/utils/plugins_update/_plugins.py | 51 ++++++-- 5 files changed, 117 insertions(+), 61 deletions(-) create mode 100644 game_record.json diff --git a/game_record.json b/game_record.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/game_record.json @@ -0,0 +1 @@ +{} diff --git a/gsuid_core/plugins/core_command/core_update/__init__.py b/gsuid_core/plugins/core_command/core_update/__init__.py index ec75e6e..6799f3f 100644 --- a/gsuid_core/plugins/core_command/core_update/__init__.py +++ b/gsuid_core/plugins/core_command/core_update/__init__.py @@ -4,9 +4,9 @@ from gsuid_core.models import Event from gsuid_core.logger import logger from gsuid_core.utils.plugins_config.gs_config import core_plugins_config from gsuid_core.utils.plugins_update._plugins import ( + run_install, check_retcode, update_from_git, - run_poetry_install, update_all_plugins, set_proxy_all_plugins, ) @@ -54,7 +54,7 @@ async def send_core_update_proxy(bot: Bot, ev: Event): @sv_core_config.on_fullmatch(('core更新依赖')) async def send_core_poetry_install(bot: Bot, ev: Event): logger.info('开始执行[更新] 早柚核心依赖') - retcode = await run_poetry_install() + retcode = await run_install() im = check_retcode(retcode) await bot.send(im) diff --git a/gsuid_core/server.py b/gsuid_core/server.py index bf72971..703621c 100644 --- a/gsuid_core/server.py +++ b/gsuid_core/server.py @@ -14,12 +14,14 @@ from gsuid_core.bot import _Bot from gsuid_core.logger import logger from gsuid_core.utils.plugins_config.gs_config import core_plugins_config from gsuid_core.utils.plugins_update._plugins import ( + check_start_tool, sync_get_plugin_url, sync_change_plugin_url, ) auto_install_dep: bool = core_plugins_config.get_config('AutoInstallDep').data -start_venv: str = core_plugins_config.get_config('StartVENV').data +auto_update_dep: bool = core_plugins_config.get_config('AutoUpdateDep').data + core_start_def = set() core_shutdown_def = set() installed_dependencies = [] @@ -38,39 +40,6 @@ def on_core_shutdown(func: Callable): return func -def check_start_tool(is_pip: bool = False): - PDM = 'pdm' - POETRY = 'poetry' - OTHER = start_venv.strip() - - if is_pip: - PIP = ' run python -m pip' - PDM += PIP - POETRY += PIP - - if OTHER == 'python': - OTHER = 'python -m pip' - else: - OTHER += PIP - - path = Path(__file__).parent.parent - pdm_python_path = path / '.pdm-python' - - if start_venv == 'auto': - if pdm_python_path.exists(): - command = PDM - else: - command = POETRY - elif start_venv == 'pdm': - command = PDM - elif start_venv == 'poetry': - command = POETRY - else: - command = start_venv.strip() - - return command - - class GsServer: _instance = None is_initialized = False @@ -115,7 +84,7 @@ class GsServer: elif nest_path.exists() or src_path.exists(): path = nest_path.parent / plugin.name pyproject = plugin / 'pyproject.toml' - if auto_install_dep and pyproject.exists: + if pyproject.exists: check_pyproject(pyproject) if path.exists(): self.load_dir_plugins(path, True) @@ -213,23 +182,42 @@ def check_pyproject(pyproject: Path): "extend-exclude = '''", '' ).replace("'''", '', 1) toml_data = toml.loads(file_content) - if 'project' in toml_data: - dependencies = toml_data['project'].get('dependencies') - elif 'tool' in toml_data and 'poetry' in toml_data['tool']: - dependencies = toml_data['tool']['poetry'].get('dependencies') - else: - dependencies = None + + if auto_install_dep or auto_update_dep: + if 'project' in toml_data: + dependencies = toml_data['project'].get('dependencies') + elif 'tool' in toml_data and 'poetry' in toml_data['tool']: + dependencies = toml_data['tool']['poetry'].get('dependencies') + else: + dependencies = None if isinstance(dependencies, List): dependencies = parse_dependency(dependencies) + else: + dependencies = {} + + if 'project' in toml_data: + sp_dep = toml_data['project'].get('gscore_auto_update_dep') + if sp_dep: + sp_dep = parse_dependency(sp_dep) + logger.debug('[安装/更新依赖] 特殊依赖列表如下:') + logger.debug(sp_dep) + logger.debug('========') + install_dependencies(sp_dep, True) if dependencies: - install_dependencies(dependencies) + if auto_update_dep: + install_dependencies(dependencies, True) + else: + install_dependencies(dependencies, False) -def install_dependencies(dependencies: Dict): +def install_dependencies(dependencies: Dict, need_update: bool = False): global installed_dependencies start_tool = check_start_tool(True) + + logger.debug(f'[安装/更新依赖] 当前启动工具:{start_tool}') + if start_tool == 'pdm': result = subprocess.run( 'pdm run python -m ensurepip', @@ -241,19 +229,44 @@ def install_dependencies(dependencies: Dict): logger.warning("PDM中pip环境检查失败。错误信息:") logger.warning(result.stderr) return + + logger.trace( + f'[安装/更新依赖] 开始安装/更新依赖...模式是否为更新:{need_update}' + ) + + if need_update: + extra = '-U' + else: + extra = '' + + logger.trace('[安装/更新依赖] 需检查依赖列表如下:') + logger.trace(dependencies) + logger.trace('========') + # 解析依赖项 for ( dependency, version, ) in dependencies.items(): - if ( - installed_dependencies - and dependency not in installed_dependencies - and dependency not in ignore_dep - ): - logger.info(f'安装依赖 {dependency} 中...') + if need_update: + condi = dependency not in ignore_dep + else: + condi = ( + installed_dependencies + and dependency not in installed_dependencies + and dependency not in ignore_dep + ) + logger.trace( + f'[安装/更新依赖] 检测到依赖 {dependency}, 是否满足条件 {condi}' + ) + + if condi: + logger.info(f'[安装/更新依赖] {dependency} 中...') + CMD = f'{start_tool} install "{dependency}{version}" {extra}' + + logger.info(f'[安装/更新依赖] 开始执行:{CMD}') result = subprocess.run( - f'{start_tool} install {dependency}', + CMD, capture_output=True, text=True, ) diff --git a/gsuid_core/utils/plugins_config/config_default.py b/gsuid_core/utils/plugins_config/config_default.py index 4b24ff9..d7a779e 100644 --- a/gsuid_core/utils/plugins_config/config_default.py +++ b/gsuid_core/utils/plugins_config/config_default.py @@ -74,10 +74,15 @@ CONIFG_DEFAULT: Dict[str, GSC] = { '自动重启Core时间设置', '每晚自动重启Core时间设置(时, 分)', ['4', '40'] ), 'AutoInstallDep': GsBoolConfig( - '自动安装/更新依赖', - '更新/安装插件时将会自动更新/安装依赖', + '自动安装依赖', + '安装插件时将会自动安装依赖', True, ), + 'AutoUpdateDep': GsBoolConfig( + '自动更新依赖', + '启动Core时将会自动更新插件依赖', + False, + ), 'EnablePicSrv': GsBoolConfig( '启用将图片转链接发送(需公网)', '发送图片转链接', diff --git a/gsuid_core/utils/plugins_update/_plugins.py b/gsuid_core/utils/plugins_update/_plugins.py index 7dd0fcf..ba02674 100644 --- a/gsuid_core/utils/plugins_update/_plugins.py +++ b/gsuid_core/utils/plugins_update/_plugins.py @@ -17,9 +17,43 @@ from .api import CORE_PATH, PLUGINS_PATH, plugins_lib plugins_list: Dict[str, Dict[str, str]] = {} +start_venv: str = core_plugins_config.get_config('StartVENV').data is_install_dep = core_plugins_config.get_config('AutoInstallDep').data +def check_start_tool(is_pip: bool = False): + PDM = 'pdm' + POETRY = 'poetry' + OTHER = start_venv.strip() + + if is_pip: + PIP = ' run python -m pip' + PDM += PIP + POETRY += ' run pip' + + if OTHER == 'python': + OTHER = 'python -m pip' + else: + OTHER += PIP + + path = Path(__file__).parent.parent.parent.parent + pdm_python_path = path / '.pdm-python' + + if start_venv == 'auto': + if pdm_python_path.exists(): + command = PDM + else: + command = POETRY + elif start_venv == 'pdm': + command = PDM + elif start_venv == 'poetry': + command = POETRY + else: + command = start_venv.strip() + + return command + + async def check_plugin_exist(name: str): name = name.lower() if name in ['core_command', 'gs_test']: @@ -37,22 +71,25 @@ async def uninstall_plugin(path: Path): # 传入一个path对象 -async def run_poetry_install(path: Optional[Path] = None) -> int: +async def run_install(path: Optional[Path] = None) -> int: + tools = check_start_tool() + if tools == 'pip': + logger.warning('你使用的是PIP环境, 无需进行 PDM/Poetry install!') + return -200 + if path is None: path = CORE_PATH + # 检测path是否是一个目录 if not path.is_dir(): raise ValueError(f"{path} is not a directory") - # 检测path下是否存在poetry.lock文件 - lock_file = path / "poetry.lock" - if not lock_file.is_file(): - raise FileNotFoundError(f"{lock_file} does not exist") + # 异步执行poetry install命令,并返回返回码 env = os.environ.copy() env["PYTHONIOENCODING"] = "utf8" proc = await asyncio.create_subprocess_shell( - 'poetry install', + f'{tools} install', cwd=path, stdout=asyncio.subprocess.PIPE, shell=True, @@ -356,7 +393,7 @@ def update_from_git( repo = Repo(CORE_PATH) plugin_name = '早柚核心' if is_install_dep: - asyncio.create_task(run_poetry_install(CORE_PATH)) + asyncio.create_task(run_install(CORE_PATH)) elif isinstance(repo_like, Path): repo = Repo(repo_like) plugin_name = repo_like.name