Files
tree-generator/Releases/v1.0.0/source/t023-architecture-design.md
2026-05-16 17:34:32 +08:00

18 KiB
Raw Permalink Blame History

目录树生成脚本 — 技术方案设计Windows 平台)

任务 ID: T023 | 项目 ID: PROJ-20260509011
功能清单: F013-F0208 个功能,全部审批通过)
运行平台: Windows
设计日期: 2026-05-16
设计者: 脚本架构师


1. 技术选型评估

1.1 功能级可行性分析BAT vs Python

功能编号 功能名称 BAT 可行性 Python 可行性 关键问题
F013 接收路径输入 完全可行 完全可行 BAT: %~1 即可Python: argparse
F014 加载忽略配置 ⚠️ 勉强可行 完全可行 BAT 读取配置文件需逐行 for /f,无结构化解析能力
F015 递归遍历目录 ⚠️ 勉强可行 完全可行 BAT for /r 可递归但无法灵活控制跳过逻辑
F016 生成目录树(├── 字符) 不可行 完全可行 Windows CMD 默认代码页 936 (GBK) 无法正确显示 等 Unicode 制表符;需 chcp 65001 且仍有渲染问题。BAT 字符串拼接缩进极其困难
F017 生成文件树 ⚠️ 勉强可行 完全可行 BAT dir /s/b 可列出文件,但格式化输出困难
F018 终端输出 ⚠️ 有条件可行 完全可行 BAT 需处理 chcp 65001 编码切换,输出重定向时易乱码
F019 Markdown 保存 ⚠️ 勉强可行 完全可行 BAT 可 echo > file.md,但 Markdown 结构化内容拼接繁琐
F020 统计信息(目录数/文件数/总大小) 困难 完全可行 BAT 无原生文件大小累加能力,%%~zIfor 循环中可用但累加大文件时易溢出BAT 整数仅支持 32 位)

1.2 BAT 核心缺陷总结

  1. Unicode 制表符渲染F016 要求输出 ├── └── 等字符Windows CMD 默认代码页下这些字符会显示为乱码。虽然 chcp 65001 可以切换 UTF-8但在 Windows 10 之前的系统上存在严重兼容性问题,且输出重定向到文件时编码转换不可靠。
  2. 字符串处理BAT 的字符串拼接、缩进管理极其笨拙,无法优雅实现树形缩进逻辑。
  3. 大文件统计BAT 的整数运算限制在 32 位有符号范围(约 ±21 亿),总大小超过 2GB 时会溢出。
  4. 错误处理BAT 缺乏结构化异常处理机制try/catch错误恢复困难。
  5. 配置解析BAT 无法优雅解析结构化配置文件JSON/INI只能逐行文本处理。

1.3 评估结论

BAT 无法胜任 F016目录树 Unicode 渲染)和 F020大文件统计其余功能也均存在明显缺陷。


2. 技术选型结论

最终选择Python 3.8+(标准库,无第三方依赖)

理由:

维度 说明
功能覆盖 8 个功能全部可完美实现,无妥协
Unicode 支持 Python 原生 UTF-8 支持,├── 等字符渲染无问题
标准库 pathlibosargparsedatetime 覆盖所有需求
文件大小 Python 整数自动扩展,无溢出问题
跨版本兼容 Python 3.8+ 覆盖 Windows 7 SP1 及以上所有版本
可维护性 代码结构清晰,模块化设计,易于扩展
部署 单文件 .py,用户只需安装 PythonWindows 10/11 可通过 Microsoft Store 一键安装)

3. 项目结构

tree_generator/
├── tree_gen.py              # 主程序(单文件,包含所有模块)
├── .treeignore              # 忽略配置文件(可选,放在目标目录下)
├── tree_output.md           # 默认输出文件(运行后生成)
└── README.md                # 使用文档(由 Web 文档生成 Agent 创建)

设计原则:

  • 主程序 tree_gen.py 为单文件,不拆分为多模块,便于分发和使用
  • 忽略配置文件 .treeignore 放在目标目录下,遵循 .gitignore 惯例
  • 输出文件默认在当前工作目录生成

4. 模块说明表

模块名 负责功能 输入 输出 依赖
ArgParser F013 路径输入 命令行参数 sys.argv 解析后的配置对象(目标路径、输出路径、深度限制等) argparse 标准库
IgnoreLoader F014 忽略配置 配置文件路径(.treeignore 忽略目录名称集合 set[str] pathlib 标准库
DirectoryScanner F015 递归遍历 目标路径 + 忽略集合 目录树结构(嵌套字典) pathlibos 标准库
TreeFormatter F016 目录树 + F017 文件树 目录树结构 格式化字符串(含 ├── 缩进) 无额外依赖
TerminalOutput F018 终端输出 格式化字符串 终端显示stdout sys 标准库(编码设置)
MarkdownWriter F019 Markdown 保存 格式化字符串 + 输出路径 .md 文件 pathlib 标准库
StatisticsCollector F020 统计信息 目录树结构 统计信息字典(目录数、文件数、总大小) os 标准库

5. 技术选型结论总结

┌─────────────────────────────────────────────────────┐
│  最终技术选型Python 3.8+ 标准库                    │
│                                                     │
│  核心文件tree_gen.py单文件约 300-400 行)       │
│  配置文件:.treeignore可选                        │
│  输出文件tree_output.md默认                     │
│                                                     │
│  选择理由:                                           │
│  1. BAT 无法正确处理 Unicode 制表符F016          │
│  2. BAT 整数溢出问题F020 大文件统计)               │
│  3. Python 标准库完全覆盖所有 8 个功能                │
│  4. 单文件部署,零第三方依赖                          │
└─────────────────────────────────────────────────────┘

6. 错误处理策略

6.1 异常分类与处理

异常类型 触发条件 处理策略 用户提示
PathNotFoundError 目标路径不存在 捕获 FileNotFoundError,退出并提示 错误: 路径 "xxx" 不存在,请检查输入
PermissionError 无权限访问目录 跳过该目录,记录警告,继续遍历 警告: 无权限访问 "xxx",已跳过
SymlinkLoopError 符号链接循环 使用 pathlib.Path.resolve() 检测,跳过已访问路径 警告: 检测到符号链接循环,已跳过
EncodingError 文件名含特殊字符 使用 errors='replace' 容错 静默替换,不中断
OutputWriteError 无法写入输出文件 捕获 IOError/PermissionError,回退到仅终端输出 警告: 无法写入文件,仅显示到终端
InvalidConfigError 忽略配置文件格式错误 使用默认忽略列表,记录警告 警告: 配置文件格式错误,使用默认配置

6.2 退出码规范

退出码 含义
0 成功完成
1 参数错误(路径不存在、格式错误)
2 运行时错误(写入失败等)
3 中断Ctrl+C

7. 接口定义

7.1 数据流图

┌──────────┐     ┌──────────────┐     ┌─────────────────┐
│ 命令行参数  │────▶│  ArgParser   │────▶│  Config 对象    │
│ sys.argv   │     │ (F013)       │     │ {path, output,  │
└──────────┘     └──────────────┘     │  ignore, depth} │
                                       └────────┬────────┘
                                                │
                    ┌───────────────────────────┼───────────────────────────┐
                    │                           │                           │
                    ▼                           ▼                           ▼
           ┌──────────────┐            ┌──────────────┐            ┌──────────────┐
           │IgnoreLoader  │            │Directory     │            │Statistics    │
           │(F014)        │            │Scanner       │            │Collector     │
           │              │            │(F015)        │            │(F020)        │
           │.treeignore   │            │              │            │              │
           └──────┬───────┘            └──────┬───────┘            └──────┬───────┘
                  │                           │                           │
                  ▼                           ▼                           │
           ignore_set                     tree_dict                      │
           (set[str])                  (嵌套字典)                         │
                                        │                                │
                                        ▼                                │
                               ┌──────────────────┐                     │
                               │ TreeFormatter    │◀────────────────────┘
                               │ (F016/F017)     │
                               │                 │
                               │ tree_str        │
                               │ file_list_str   │
                               └────────┬────────┘
                                        │
                    ┌───────────────────┼───────────────────┐
                    ▼                   ▼                   ▼
           ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
           │ Terminal     │    │ Markdown     │    │ 统计信息     │
           │ Output       │    │ Writer       │    │ 输出         │
           │ (F018)       │    │ (F019)       │    │              │
           │              │    │              │    │              │
           │ stdout       │    │ tree_output  │    │ 目录/文件/   │
           │              │    │ .md          │    │ 总大小       │
           └──────────────┘    └──────────────┘    └──────────────┘

7.2 核心数据结构

# Config 对象ArgParser 输出)
Config = {
    "target_path": Path,          # 目标目录路径
    "output_path": Path,          # Markdown 输出路径(默认 tree_output.md
    "ignore_dirs": set[str],      # 忽略目录名称集合
    "max_depth": int | None,      # 最大递归深度None = 无限制)
    "files_only": bool,           # 仅显示文件模式
    "dirs_only": bool,            # 仅显示目录模式
}

# 目录树结构DirectoryScanner 输出)
TreeDict = {
    "name": str,                   # 目录/文件名
    "path": Path,                  # 完整路径
    "is_dir": bool,                # 是否为目录
    "children": list[TreeDict],    # 子节点列表(目录时有效)
    "size": int,                   # 文件大小(文件时有效)
}

# 统计信息StatisticsCollector 输出)
Statistics = {
    "dir_count": int,              # 目录数量
    "file_count": int,             # 文件数量
    "total_size": int,             # 总大小(字节)
    "total_size_human": str,       # 人类可读大小(如 "1.23 GB"
}

7.3 模块间接口

调用方 被调用方 接口方法 参数 返回值
main() ArgParser parse_args() sys.argv[1:] Config
main() IgnoreLoader load_ignores(config) Config set[str]
main() DirectoryScanner scan(path, ignore_set, max_depth) Path, set[str], int|None TreeDict
main() TreeFormatter format_tree(tree, style) TreeDict, str str
main() TreeFormatter format_files(tree) TreeDict str
main() TerminalOutput output(text) str None
main() MarkdownWriter write(text, path) str, Path None
main() StatisticsCollector collect(tree) TreeDict Statistics

8. 忽略配置方案F014

8.1 配置文件格式

文件名:.treeignore(放在目标目录下)

# 忽略配置示例
# 每行一个目录名,支持 # 注释

.git
.gitignore
node_modules
__pycache__
*.pyc
.DS_Store
Thumbs.db
venv
.env
.idea
.vscode
dist
build
*.egg-info

8.2 内置默认忽略列表

.treeignore 不存在时,使用以下默认列表:

DEFAULT_IGNORE = {
    ".git", ".svn", ".hg",           # 版本控制
    "node_modules", "bower_components",  # Node.js
    "__pycache__", "*.pyc", ".pytest_cache",  # Python
    ".idea", ".vscode",              # IDE
    "dist", "build", "target",       # 构建产物
    ".DS_Store", "Thumbs.db",        # 系统文件
    "venv", ".venv", "env",          # 虚拟环境
}

8.3 匹配规则

  • 目录名精确匹配不区分大小写Windows 特性)
  • 支持 * 通配符(如 *.pyc
  • 忽略配置仅作用于目录级别,不递归检查文件内容

9. 树形输出格式规范F016/F017

9.1 目录树格式

项目根目录/
├── src/
│   ├── main.py
│   ├── utils/
│   │   ├── helper.py
│   │   └── config.py
│   └── models/
│       └── user.py
├── tests/
│   ├── test_main.py
│   └── test_utils.py
├── config.json
└── README.md

规则:

  • 目录名后加 / 后缀
  • 分支符:├── (有后续兄弟节点)/ └── (最后一个节点)
  • 缩进线:(有后续兄弟节点)/ (无后续兄弟节点)
  • 缩进单位4 个字符( + 3 空格 或 4 空格)

9.2 文件树格式

文件列表:
C:\project\src\main.py
C:\project\src\utils\helper.py
C:\project\src\utils\config.py
C:\project\src\models\user.py
C:\project\tests\test_main.py
C:\project\tests\test_utils.py
C:\project\config.json
C:\project\README.md

规则:

  • 每个文件一行,带完整绝对路径
  • 使用 Windows 风格路径分隔符 \
  • 按字母顺序排序

9.3 统计信息格式

统计信息:
  目录数: 5
  文件数: 8
  总大小: 24.5 KB (25,088 字节)

10. Markdown 保存方案F019

10.1 输出文件格式

# 目录树 — 项目根目录

> 生成时间: 2026-05-16 16:00:00  
> 目标路径: C:\project  
> 扫描深度: 无限制

## 目录结构

项目根目录/ ├── src/ │ ├── main.py │ └── utils/ │ └── helper.py ├── config.json └── README.md


## 文件列表

| # | 文件路径 |
|---|---------|
| 1 | `C:\project\src\main.py` |
| 2 | `C:\project\src\utils\helper.py` |
| 3 | `C:\project\config.json` |
| 4 | `C:\project\README.md` |

## 统计信息

- **目录数:** 3
- **文件数:** 4
- **总大小:** 1.2 KB (1,234 字节)

10.2 保存策略

  • 默认文件名:tree_output.md(当前工作目录)
  • 可通过 -o / --output 参数指定自定义路径
  • 文件已存在时覆盖写入(不追加)
  • 编码UTF-8 with BOMWindows 记事本兼容)

11. 命令行接口设计

usage: tree_gen.py [-h] [-o OUTPUT] [-d DEPTH] [-f] [-D] [-i IGNORE_FILE] [path]

目录树生成脚本 - Windows 平台

positional arguments:
  path                  目标目录路径(默认: 当前目录)

options:
  -h, --help            显示帮助信息
  -o OUTPUT, --output OUTPUT
                        Markdown 输出文件路径(默认: tree_output.md
  -d DEPTH, --depth DEPTH
                        最大递归深度(默认: 无限制)
  -f, --files-only      仅显示文件树
  -D, --dirs-only       仅显示目录树
  -i IGNORE_FILE, --ignore IGNORE_FILE
                        忽略配置文件路径(默认: 目标目录下的 .treeignore

使用示例

# 扫描当前目录
python tree_gen.py

# 扫描指定目录
python tree_gen.py C:\Users\test\project

# 指定输出文件和深度
python tree_gen.py C:\project -o output.md -d 3

# 仅显示文件
python tree_gen.py C:\project -f

# 自定义忽略配置
python tree_gen.py C:\project -i my_ignore.txt

12. 编码规范

项目 规范
文件编码 UTF-8Python 源文件)
输出编码 UTF-8 with BOMMarkdown 文件)
终端编码 UTF-8通过 sys.stdout.reconfigure(encoding='utf-8') 设置)
行尾符 LFPython 标准)
缩进 4 空格
Python 版本 3.8+

13. 后续任务

任务 负责 Agent 状态
T021: Python 代码实现 BAT 编码 Agent实际应为 Python 编码 Agent 待激活
T022: 功能测试验证 测试验证 Agent 待激活
T024: 使用文档编写 Web 文档生成 Agent 待激活

文档结束。等待审批后进入编码阶段。