build_local.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 本地文档构建脚本
  5. 用于快速构建和预览文档
  6. """
  7. import os
  8. import sys
  9. import subprocess
  10. import argparse
  11. from pathlib import Path
  12. def check_dependencies():
  13. """检查依赖是否安装"""
  14. try:
  15. import sphinx
  16. import yaml
  17. import myst_parser
  18. print("✓ 所有依赖已安装")
  19. return True
  20. except ImportError as e:
  21. print(f"✗ 缺少依赖: {e}")
  22. print("请运行: pip install -r requirements.txt")
  23. return False
  24. def build_docs(clean=False, serve=False, port=8000):
  25. """构建文档"""
  26. print("开始构建文档...")
  27. # 检查依赖
  28. if not check_dependencies():
  29. return False
  30. try:
  31. # 1. 生成文档结构
  32. print("1. 生成文档结构...")
  33. subprocess.run([
  34. sys.executable, 'doc_generator.py'
  35. ], cwd=".", check=True)
  36. # 2. 构建HTML文档
  37. print("2. 构建HTML文档...")
  38. build_dir = Path("_build/html")
  39. if clean and build_dir.exists():
  40. import shutil
  41. shutil.rmtree(build_dir)
  42. print("已清理构建目录")
  43. subprocess.run([
  44. sys.executable, '-m', 'sphinx.cmd.build',
  45. '-b', 'html',
  46. '.',
  47. str(build_dir)
  48. ], cwd=".", check=True)
  49. print(f"✓ 文档构建完成: {build_dir.absolute()}")
  50. # 创建根目录重定向页面(本地构建时重定向到当前文档)
  51. create_root_redirect_local(build_dir)
  52. # 3. 启动本地服务器(如果需要)
  53. if serve:
  54. print(f"3. 启动本地服务器 (http://localhost:{port})...")
  55. try:
  56. subprocess.run([
  57. sys.executable, '-m', 'http.server', str(port)
  58. ], cwd=str(build_dir))
  59. except KeyboardInterrupt:
  60. print("\n服务器已停止")
  61. return True
  62. except subprocess.CalledProcessError as e:
  63. print(f"✗ 构建失败: {e}")
  64. return False
  65. except Exception as e:
  66. print(f"✗ 未知错误: {e}")
  67. return False
  68. def create_root_redirect_local(build_dir):
  69. """为本地构建创建根目录重定向页面"""
  70. print("\n创建根目录重定向页面...")
  71. # 创建根目录的 index.html,重定向到当前文档
  72. root_index = build_dir / "index.html"
  73. redirect_html = """<!DOCTYPE html>
  74. <html lang="zh-CN">
  75. <head>
  76. <meta charset="UTF-8">
  77. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  78. <title>SDK 文档</title>
  79. <meta http-equiv="refresh" content="0; url=./basic/index.html">
  80. <style>
  81. body {
  82. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  83. display: flex;
  84. justify-content: center;
  85. align-items: center;
  86. height: 100vh;
  87. margin: 0;
  88. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  89. color: white;
  90. }
  91. .container {
  92. text-align: center;
  93. background: rgba(255, 255, 255, 0.1);
  94. padding: 40px;
  95. border-radius: 12px;
  96. backdrop-filter: blur(10px);
  97. }
  98. .spinner {
  99. border: 3px solid rgba(255, 255, 255, 0.3);
  100. border-top: 3px solid white;
  101. border-radius: 50%;
  102. width: 40px;
  103. height: 40px;
  104. animation: spin 1s linear infinite;
  105. margin: 0 auto 20px;
  106. }
  107. @keyframes spin {
  108. 0% { transform: rotate(0deg); }
  109. 100% { transform: rotate(360deg); }
  110. }
  111. h1 {
  112. margin: 0 0 10px 0;
  113. font-size: 24px;
  114. }
  115. p {
  116. margin: 0;
  117. opacity: 0.9;
  118. }
  119. a {
  120. color: white;
  121. text-decoration: underline;
  122. }
  123. </style>
  124. </head>
  125. <body>
  126. <div class="container">
  127. <div class="spinner"></div>
  128. <h1>SDK 文档</h1>
  129. <p>正在跳转到文档首页...</p>
  130. <p><a href="./basic/index.html">如果页面没有自动跳转,请点击这里</a></p>
  131. </div>
  132. </body>
  133. </html>"""
  134. with open(root_index, 'w', encoding='utf-8') as f:
  135. f.write(redirect_html)
  136. print(f"✓ 根目录重定向页面创建完成: {root_index}")
  137. return True
  138. def main():
  139. """主函数"""
  140. parser = argparse.ArgumentParser(description="本地文档构建工具")
  141. parser.add_argument('--clean', action='store_true', help='清理构建目录')
  142. parser.add_argument('--serve', action='store_true', help='启动本地服务器')
  143. parser.add_argument('--port', type=int, default=8000, help='服务器端口 (默认: 8000)')
  144. parser.add_argument('--check', action='store_true', help='仅检查依赖')
  145. parser.add_argument('--check-branch', action='store_true', help='检查分支版本映射')
  146. parser.add_argument('--all-versions', action='store_true', help='构建所有版本(需要 --all 参数)')
  147. args = parser.parse_args()
  148. if args.check:
  149. check_dependencies()
  150. return
  151. if args.check_branch:
  152. # 运行分支检查
  153. try:
  154. subprocess.run([sys.executable, 'check_branch_versions.py'], check=True)
  155. return
  156. except subprocess.CalledProcessError:
  157. sys.exit(1)
  158. if args.all_versions:
  159. # 构建所有版本
  160. print("构建所有版本...")
  161. try:
  162. subprocess.run([sys.executable, 'version_generator.py', '--all'], check=True)
  163. print("\n🎉 所有版本构建完成!")
  164. return
  165. except subprocess.CalledProcessError as e:
  166. print(f"\n❌ 多版本构建失败: {e}")
  167. sys.exit(1)
  168. success = build_docs(clean=args.clean, serve=args.serve, port=args.port)
  169. if success:
  170. print("\n🎉 构建成功!")
  171. if not args.serve:
  172. print(f"📁 文档位置: {Path('_build/html').absolute()}")
  173. print("💡 提示: 使用 --serve 参数启动本地服务器预览")
  174. else:
  175. print("\n❌ 构建失败!")
  176. sys.exit(1)
  177. if __name__ == "__main__":
  178. main()