1
0

refactor: restructure CLI with clear subcommand architecture

重构命令行接口,建立清晰的子命令架构,提升用户体验和代码可维护性。

主要变更:
- 移除传统模式,统一使用子命令架构(check/convert/preview)
- 将 preview 从 convert 的标志独立为子命令,职责分离
- 重命名参数:--no-check → --skip-validation
- 新增 --force/-f:convert 命令支持强制覆盖已存在文件
- 新增 --host:preview 命令支持配置主机地址(局域网预览)
- 新增 --no-browser:preview 命令支持不自动打开浏览器
- 优化 --port 默认值:从固定端口改为随机端口(30000-40000)

破坏性变更:
- 不再支持传统模式(yaml2pptx.py input.yaml output.pptx)
- convert 命令不再支持 --preview 参数,需使用 preview 子命令

文档更新:
- 更新 README.md 和 README_DEV.md 的所有使用示例
- 更新命令行选项说明表格
- 新增 CLI 接口规范文档

OpenSpec:
- 创建 cli-interface 规范(新能力)
- 更新 browser-preview-server 规范(修改的能力)
- 归档 refactor-cli-args change(45/45 任务完成)
This commit is contained in:
2026-03-02 18:47:50 +08:00
parent 83ff827ad1
commit 66472cbd86
13 changed files with 934 additions and 112 deletions

View File

@@ -186,8 +186,16 @@ def create_flask_app():
return flask_app
def start_preview_server(yaml_file, template_dir, port):
"""启动预览服务器"""
def start_preview_server(yaml_file, template_dir, port, host='127.0.0.1', open_browser=True):
"""启动预览服务器
Args:
yaml_file: YAML 文件路径
template_dir: 模板目录路径
port: 服务器端口
host: 主机地址默认127.0.0.1
open_browser: 是否自动打开浏览器默认True
"""
global app, change_queue, current_yaml_file, current_template_dir
if Flask is None:
@@ -195,10 +203,6 @@ def start_preview_server(yaml_file, template_dir, port):
log_error("请确保使用 uv 运行脚本,依赖会自动安装")
sys.exit(1)
# 如果没有指定端口,随机选择 20000-30000 之间的端口
if port is None:
port = random.randint(20000, 30000)
current_yaml_file = yaml_file
current_template_dir = template_dir
change_queue = queue.Queue()
@@ -221,15 +225,16 @@ def start_preview_server(yaml_file, template_dir, port):
# 输出日志
log_info(f"正在监听: {yaml_file}")
log_info(f"预览地址: http://localhost:{port}")
log_info(f"预览地址: http://{host}:{port}")
log_info("按 Ctrl+C 停止")
# 自动打开浏览器
Thread(target=lambda: webbrowser.open(f'http://localhost:{port}')).start()
# 自动打开浏览器(如果启用)
if open_browser:
Thread(target=lambda: webbrowser.open(f'http://localhost:{port}')).start()
# 启动 Flask
try:
app.run(host='0.0.0.0', port=port, debug=False, threaded=True)
app.run(host=host, port=port, debug=False, threaded=True)
except OSError as e:
if 'Address already in use' in str(e):
log_error(f"端口 {port} 已被占用")