zhenxun_bot/zhenxun/utils/repo_utils/submodule_setup.py
HibiKier a3142ad065
Some checks are pending
Sequential Lint and Type Check / ruff-call (push) Waiting to run
Sequential Lint and Type Check / pyright-call (push) Blocked by required conditions
feat(submodule): 添加子模块管理功能,支持子模块的初始化、更新和信息获取
2025-08-03 23:57:13 +08:00

211 lines
6.5 KiB
Python

#!/usr/bin/env python3
"""
GitHub子模块快速设置脚本
"""
import asyncio
from pathlib import Path
import sys
from zhenxun.services.log import logger
from zhenxun.utils.repo_utils import (
GithubRepoManager,
SubmoduleConfig,
)
def create_sample_configs():
"""创建示例子模块配置"""
return [
SubmoduleConfig(
name="frontend-ui",
path="frontend/ui",
repo_url="https://github.com/your-org/frontend-ui",
branch="main",
enabled=True,
include_patterns=["*.js", "*.css", "*.html", "*.vue", "*.ts"],
exclude_patterns=["node_modules/*", "*.log", "dist/*", "coverage/*"],
),
SubmoduleConfig(
name="backend-api",
path="backend/api",
repo_url="https://github.com/your-org/backend-api",
branch="develop",
enabled=True,
include_patterns=["*.py", "*.json", "requirements.txt", "*.yml"],
exclude_patterns=["__pycache__/*", "*.pyc", "venv/*", ".pytest_cache/*"],
),
SubmoduleConfig(
name="shared-lib",
path="libs/shared",
repo_url="https://github.com/your-org/shared-lib",
branch="main",
enabled=True,
include_patterns=["*.py", "*.js", "*.ts", "*.json"],
exclude_patterns=["tests/*", "docs/*", "examples/*"],
),
]
async def setup_submodules(project_path: str, configs: list[SubmoduleConfig]):
"""设置子模块"""
main_repo_path = Path(project_path)
logger.info(f"正在为项目 {project_path} 设置子模块...")
# 检查路径是否存在
if not main_repo_path.exists():
logger.info(f"错误: 项目路径 {project_path} 不存在")
return False
# 检查是否是Git仓库
git_dir = main_repo_path / ".git"
if not git_dir.exists():
logger.info(f"错误: {project_path} 不是Git仓库")
logger.info("请先执行: git init")
return False
# 初始化子模块
logger.info("正在初始化子模块...")
success = await GithubRepoManager.init_submodules(main_repo_path, configs)
if not success:
logger.info("子模块初始化失败!")
return False
# 保存配置
logger.info("正在保存子模块配置...")
await GithubRepoManager.save_submodule_configs(main_repo_path, configs)
logger.info("✓ 子模块设置完成!")
logger.info(f"配置文件已保存到: {main_repo_path / '.submodules.json'}")
return True
async def update_submodules(project_path: str):
"""更新子模块"""
main_repo_path = Path(project_path)
logger.info(f"正在更新项目 {project_path} 的子模块...")
# 加载配置
configs = await GithubRepoManager.load_submodule_configs(main_repo_path)
if not configs:
logger.info("未找到子模块配置")
return False
logger.info(f"找到 {len(configs)} 个子模块配置")
# 获取子模块信息
infos = await GithubRepoManager.get_submodule_info(main_repo_path, configs)
logger.info("\n子模块状态:")
for info in infos:
status_icon = (
""
if info.update_status == "up_to_date"
else ""
if info.update_status == "outdated"
else ""
)
logger.info(
f"{status_icon} {info.config.name}"
f"({info.config.path}) - {info.update_status}"
)
# 更新子模块
logger.info("\n正在更新子模块...")
results = await GithubRepoManager.update_submodules(main_repo_path, configs)
success_count = 0
for result in results:
if result.success:
success_count += 1
if result.old_version != result.new_version:
logger.info(f"{result.submodule_name} 已更新")
else:
logger.info(f"{result.submodule_name} 已是最新版本")
else:
logger.info(f"{result.submodule_name} 更新失败: {result.error_message}")
logger.info(f"\n更新完成: {success_count}/{len(results)} 个子模块更新成功")
return success_count == len(results)
async def show_submodule_info(project_path: str):
"""显示子模块信息"""
main_repo_path = Path(project_path)
logger.info(f"项目 {project_path} 的子模块信息:")
# 加载配置
configs = await GithubRepoManager.load_submodule_configs(main_repo_path)
if not configs:
logger.info("未找到子模块配置")
return
# 获取详细信息
infos = await GithubRepoManager.get_submodule_info(main_repo_path, configs)
for info in infos:
logger.info(f"\n子模块: {info.config.name}")
logger.info(f" 路径: {info.config.path}")
logger.info(f" 仓库: {info.config.repo_url}")
logger.info(f" 分支: {info.config.branch}")
logger.info(f" 状态: {info.update_status}")
logger.info(f" 启用: {info.config.enabled}")
if info.current_version:
logger.info(f" 当前版本: {info.current_version[:8]}")
if info.latest_version:
logger.info(f" 最新版本: {info.latest_version[:8]}")
if info.config.include_patterns:
logger.info(f" 包含文件: {', '.join(info.config.include_patterns)}")
if info.config.exclude_patterns:
logger.info(f" 排除文件: {', '.join(info.config.exclude_patterns)}")
def print_info_usage():
"""打印使用说明"""
logger.info("GitHub子模块管理工具")
logger.info("用法:")
logger.info(" python submodule_setup.py setup <项目路径>")
logger.info(" python submodule_setup.py update <项目路径>")
logger.info(" python submodule_setup.py info <项目路径>")
logger.info("示例:")
logger.info(" python submodule_setup.py setup ./my_project")
logger.info(" python submodule_setup.py update ./my_project")
logger.info(" python submodule_setup.py info ./my_project")
async def main():
"""主函数"""
if len(sys.argv) < 3:
print_info_usage()
return
command = sys.argv[1]
project_path = sys.argv[2]
if command == "setup":
configs = create_sample_configs()
await setup_submodules(project_path, configs)
elif command == "update":
await update_submodules(project_path)
elif command == "info":
await show_submodule_info(project_path)
else:
logger.info(f"未知命令: {command}")
print_info_usage()
if __name__ == "__main__":
asyncio.run(main())