| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #!/usr/bin/env python3
- """
- 版本配置嵌入脚本
- 在构建过程中将 .github/versions.json 的内容嵌入到 version_menu.js 中
- 完全基于 .github/versions.json,无硬编码版本信息
- 支持自动备份和还原 version_menu.js
- """
- import json
- import os
- import sys
- from pathlib import Path
- import shutil
- def load_versions_config():
- """加载 .github/versions.json 文件"""
- versions_file = Path(__file__).parent.parent.parent.parent / '.github' / 'versions.json'
- if not versions_file.exists():
- print(f"警告: 找不到版本配置文件 {versions_file}")
- return None
- try:
- with open(versions_file, 'r', encoding='utf-8') as f:
- config = json.load(f)
- if not isinstance(config, dict) or 'versions' not in config:
- print(f"错误: 版本配置文件格式不正确 {versions_file}")
- return None
- return config
- except Exception as e:
- print(f"错误: 无法读取版本配置文件: {e}")
- return None
- def embed_config_to_js(versions_config):
- if not versions_config:
- return """
- // 获取嵌入的版本配置(在构建时由脚本生成)
- function getEmbeddedVersionConfig() {
- return null; // 无可用版本配置
- }
- """
-
- # 确保配置格式正确
- config_js = json.dumps(versions_config, ensure_ascii=False, indent=2)
- embedded_config_js = f"""
- // 获取嵌入的版本配置(在构建时由脚本生成)
- function getEmbeddedVersionConfig() {{
- return {config_js};
- }}
- """
- return embedded_config_js
- def backup_js(js_file):
- bak_file = js_file.with_suffix('.js.bak')
- if js_file.exists():
- shutil.copy2(js_file, bak_file)
- print(f"已备份 {js_file} -> {bak_file}")
- return bak_file
- def restore_js(js_file):
- bak_file = js_file.with_suffix('.js.bak')
- if bak_file.exists():
- shutil.copy2(bak_file, js_file)
- print(f"已还原 {bak_file} -> {js_file}")
- return True
- else:
- print(f"未找到备份文件 {bak_file}")
- return False
- def update_version_menu_js(restore_after=False):
- versions_config = load_versions_config()
- embedded_config_js = embed_config_to_js(versions_config)
- js_file = Path(__file__).parent.parent / '_static' / 'version_menu.js'
-
- # 备份
- bak_file = backup_js(js_file)
- try:
- with open(js_file, 'r', encoding='utf-8') as f:
- content = f.read()
- except Exception as e:
- print(f"错误: 无法读取 {js_file}: {e}")
- return False
-
- # 使用括号深度匹配方式安全替换函数体,避免 JSON 中的 '}' 提前终止
- start_marker = '// 获取嵌入的版本配置(在构建时由脚本生成)'
- func_sig = 'function getEmbeddedVersionConfig()'
- start_idx = content.find(start_marker)
- replaced = False
- if start_idx != -1:
- sig_idx = content.find(func_sig, start_idx)
- if sig_idx != -1:
- brace_start = content.find('{', sig_idx)
- if brace_start != -1:
- depth = 0
- i = brace_start
- while i < len(content):
- ch = content[i]
- if ch == '{':
- depth += 1
- elif ch == '}':
- depth -= 1
- if depth == 0:
- # 包含右大括号本身
- end_idx = i + 1
- # 用嵌入代码整体替换这段函数定义
- content = content[:start_idx] + embedded_config_js.strip() + content[end_idx:]
- replaced = True
- print("替换现有嵌入配置函数(括号深度)")
- break
- i += 1
- if not replaced:
- # 查找插入位置 - 在 fetchVersionInfo 函数之前插入
- fetch_marker = 'async function fetchVersionInfo()'
- fetch_idx = content.find(fetch_marker)
- if fetch_idx != -1:
- content = content[:fetch_idx] + embedded_config_js.strip() + '\n\n ' + content[fetch_idx:]
- print("在 fetchVersionInfo 函数前插入嵌入配置函数")
- else:
- # 如果找不到 fetchVersionInfo,在文件开头插入
- content = embedded_config_js.strip() + '\n\n' + content
- print("在文件开头插入嵌入配置函数")
-
- try:
- with open(js_file, 'w', encoding='utf-8') as f:
- f.write(content)
- print(f"成功更新 {js_file}")
- if versions_config:
- print(f"嵌入版本配置: {len(versions_config.get('versions', []))} 个版本")
- for version in versions_config.get('versions', []):
- print(f" - {version['name']}: {version['display_name']} -> {version['url_path']}")
- else:
- print("嵌入兜底配置: 无可用版本")
- except Exception as e:
- print(f"错误: 无法写入 {js_file}: {e}")
- return False
-
- # 可选还原
- if restore_after:
- restore_js(js_file)
- return True
- def main():
- restore_after = False
- if len(sys.argv) > 1 and sys.argv[1] == '--restore-after':
- restore_after = True
-
- print("开始嵌入版本配置...")
- if update_version_menu_js(restore_after=restore_after):
- print("版本配置嵌入完成")
-
- # 如果不是立即恢复,则在构建完成后自动恢复
- if not restore_after:
- print("注意: 构建完成后请手动运行 'python utils/embed_version_config.py --restore-after' 来恢复备份文件")
-
- return 0
- else:
- print("版本配置嵌入失败")
- return 1
- if __name__ == '__main__':
- sys.exit(main())
|