Files
lanyuanxiaoyao 229f17bfee feat: 添加自启动机制,移除 --advice 参数
- 创建 bootstrap.py 承载实际 CLI 逻辑
- 重写 lyxy_document_reader.py 为轻量入口,自动检测依赖并启动
- 使用 subprocess.run() 实现跨平台兼容的自启动
- 移除 --advice 参数及相关测试
- 更新文档和规范,简化使用方式
2026-03-11 23:49:39 +08:00

130 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Purpose
CLI 自启动机制,自动检测文件类型、平台和依赖,用正确的 uv 命令执行脚本。
## Requirements
### Requirement: 依赖配置结构
依赖配置必须同时包含 python 版本要求和依赖包列表,按文件类型和平台组织,供自启动逻辑内部使用。
#### Scenario: 配置结构包含 python 和 dependencies
- **WHEN** 访问 `config.DEPENDENCIES`
- **THEN** 每个文件类型配置包含多个平台配置
- **AND** 每个平台配置包含 `python` 字段(可为 None`dependencies` 列表字段
#### Scenario: default 平台配置
- **WHEN** 平台无特殊配置时
- **THEN** 使用 `default` 配置
- **AND** `python``None` 表示不需要指定 `--python` 参数
---
### Requirement: 轻量文件类型检测
自启动必须复用 Reader 实例的 supports 方法识别文件类型,不打开文件。
#### Scenario: 复用 Reader 实例
- **WHEN** 检测文件类型时
- **THEN** 使用已实例化的 readers 列表
- **AND** 调用每个 reader 的 supports() 方法
- **AND** 根据第一个支持的 reader 类名识别文件类型
#### Scenario: 检测 PDF 文件
- **WHEN** 输入路径以 `.pdf` 结尾(不区分大小写)
- **THEN** PdfReader.supports() 返回 True
- **AND** 识别为 PDF 类型
#### Scenario: 检测 DOCX 文件
- **WHEN** 输入路径以 `.docx` 结尾(不区分大小写)
- **THEN** DocxReader.supports() 返回 True
- **AND** 识别为 DOCX 类型
#### Scenario: 检测 XLSX 文件
- **WHEN** 输入路径以 `.xlsx` 结尾(不区分大小写)
- **THEN** XlsxReader.supports() 返回 True
- **AND** 识别为 XLSX 类型
#### Scenario: 检测 PPTX 文件
- **WHEN** 输入路径以 `.pptx` 结尾(不区分大小写)
- **THEN** PptxReader.supports() 返回 True
- **AND** 识别为 PPTX 类型
#### Scenario: 检测 HTML 文件
- **WHEN** 输入路径以 `.html``.htm` 结尾(不区分大小写)
- **THEN** HtmlReader.supports() 返回 True
- **AND** 识别为 HTML 类型
#### Scenario: 检测 URL
- **WHEN** 输入路径以 `http://``https://` 开头
- **THEN** HtmlReader.supports() 返回 True
- **AND** 识别为 HTML 类型
#### Scenario: 不验证文件存在
- **WHEN** 输入路径指向不存在的文件
- **THEN** 仍根据 reader.supports() 识别类型,不报错
---
### Requirement: 平台检测
必须检测当前平台并选择适配的依赖配置。
#### Scenario: 检测平台格式
- **WHEN** 工具执行时
- **THEN** 返回格式为 `{system}-{machine}`,例如 `Darwin-arm64``Linux-x86_64``Windows-AMD64`
#### Scenario: macOS x86_64 PDF 特殊配置
- **WHEN** 平台为 `Darwin-x86_64` 且文件类型为 PDF
- **THEN** 使用包含 `--python 3.12` 和特定版本依赖的配置
---
### Requirement: 自启动检测
脚本必须自动检测文件类型、当前平台和 uv 可用性,如 uv 可用则用正确的 uv 命令启动 bootstrap.py。
#### Scenario: 检测文件类型
- **WHEN** 脚本启动时
- **THEN** 复用 Reader 的 supports() 方法识别文件类型
- **AND** 不打开文件,仅做轻量检测
#### Scenario: 检测平台
- **WHEN** 脚本启动时
- **THEN** 检测当前平台,格式为 `{system}-{machine}`
- **AND** 根据平台选择正确的依赖配置
#### Scenario: 检测 uv 是否可用
- **WHEN** 准备自启动前
- **THEN** 使用 `shutil.which("uv")` 检测 uv 是否在 PATH 中
- **AND** 如果 uv 不可用,降级为直接执行 bootstrap.py
---
### Requirement: 自启动执行
脚本必须使用 `subprocess.run()` 启动子进程,用正确的 uv 命令启动 bootstrap.py。
#### Scenario: 生成 uv 命令
- **WHEN** 脚本确定需要自启动
- **THEN** 根据文件类型和平台获取依赖配置
- **AND** 生成 `uv run [--python X.Y] --with <dep1> --with <dep2> ... scripts/bootstrap.py <input_path>` 命令
- **AND** 目标脚本是 bootstrap.py不是 lyxy_document_reader.py
#### Scenario: 自启动设置环境变量
- **WHEN** 执行 `subprocess.run()` 自启动
- **THEN** 必须设置 `PYTHONPATH=.`
- **AND** 不需要设置 `LYXY_IN_UV`(自启动直接调用 bootstrap.py
- **AND** 必须传递退出码给父进程
#### Scenario: 静默自启动
- **WHEN** 脚本执行自启动
- **THEN** 不输出任何额外提示信息
- **AND** 不干扰正常的 Markdown 输出
---
### Requirement: 降级执行
当 uv 不可用时,脚本必须降级为直接导入并执行 bootstrap.py。
#### Scenario: uv 不可用时降级
- **WHEN** uv 不在 PATH 中
- **THEN** 脚本直接导入 bootstrap 模块
- **AND** 调用 bootstrap.run_normal() 执行
- **AND** 如果缺少依赖,输出正常的 `ModuleNotFoundError`