返回

CLI-Anything 教程 2:第一阶段 Analyze(软件源码分析与 API 映射)

CLI-Anything 第一阶段 Analyze 详解:如何扫描软件源码、识别核心功能、映射 GUI 动作到 API,生成初始 API 映射文档。包含分析方法、关键检查点和常见陷阱。

教程概述

系列目录:CLI-Anything 教程系列索引

Analyze 是 CLI-Anything 7 阶段流程的第一阶段。这一阶段的核心任务是:深入理解软件源码,识别可供 Agent 调用的功能点

你将学到

  • ✅ Analyze 阶段的输入输出
  • ✅ 源码扫描的核心方法
  • ✅ GUI 到 API 的映射策略
  • ✅ API 映射文档的结构
  • ✅ 常见分析陷阱与应对

为什么需要 Analyze 阶段?

直接生成的问题

如果没有分析阶段直接生成 CLI:

flowchart LR
    A[软件源码] --> B[直接生成 CLI]
    B --> C[功能遗漏 60%]
    B --> D[API 设计不合理]
    B --> E[无法覆盖核心功能]

    style C fill:#ffcccc
    style D fill:#ffcccc
    style E fill:#ffcccc

Analyze 后的效果

flowchart TD
    A[软件源码] --> B[Analyze 阶段]
    B --> C[完整 API 映射]
    C --> D[95%+ 功能覆盖]
    C --> E[合理的 API 分组]
    C --> F[清晰的依赖关系]

    style B fill:#e3f2fd
    style C fill:#e8f5e9

Analyze 阶段的核心任务

任务 1:源码结构扫描

flowchart TD
    A[源码目录] --> B[识别入口文件]
    A --> C[识别核心模块]
    A --> D[识别插件/扩展系统]
    A --> E[识别配置系统]

    B --> F[API 映射文档]
    C --> F
    D --> F
    E --> F

扫描目标

类型 说明 示例
入口文件 程序启动点 main.py, __init__.py
核心模块 主要功能实现 core/, modules/
GUI 代码 界面层代码 ui/, gui/, widgets/
业务逻辑 核心算法 engine/, algorithms/
插件系统 扩展机制 plugins/, extensions/
配置系统 设置和状态 config/, settings/

任务 2:功能点识别

识别维度

# 分析清单
analysis_checklist = {
    "文件操作": [
        "新建项目/文档",
        "打开文件",
        "保存/另存为",
        "导入/导出",
    ],
    "编辑操作": [
        "撤销/重做",
        "剪切/复制/粘贴",
        "选择/全选",
        "删除",
    ],
    "视图操作": [
        "缩放",
        "导航",
        "显示/隐藏面板",
    ],
    "核心功能": [
        "软件特有功能(如图像滤镜)",
        "批处理功能",
        "自动化功能",
    ],
    "设置配置": [
        "首选项",
        "快捷键",
        "工作区布局",
    ]
}

任务 3:GUI 到 API 映射

flowchart LR
    A[GUI 元素] --> B[信号/槽机制]
    B --> C[底层 API 调用]
    C --> D[可 CLI 化的接口]

    style D fill:#e8f5e9

映射示例(以 GIMP 为例):

GUI 操作 信号/槽 底层 API CLI 候选
File > New activate gimp_image_new() image new
Filters > Blur activate plug_in_gauss_blur() filter blur
Layer > New activate gimp_layer_new() layer new
Export As activate file_export() export render

API 映射文档结构

Analyze 阶段的输出是一份结构化的 API 映射文档

# API 映射文档 - <软件名称>

## 1. 软件概述

- **名称**: GIMP
- **版本**: 2.10.x
- **语言**: C
- **GUI 框架**: GTK+
- **插件系统**: Script-Fu, Python-Fu

## 2. 目录结构

gimp/ ├── app/ # 主应用程序 ├── core/ # 核心库 ├── gui/ # GUI 层 ├── plug-ins/ # 插件目录 ├── libgimp/ # C API 库 └── libgimpbase/ # 基础库


## 3. 功能模块映射

### 3.1 文件操作模块

| GUI 路径 | 信号处理 | C API | CLI 建议 |
|---------|---------|-------|---------|
| File > New | file_new_cmd_callback | gimp_image_new | image new |
| File > Open | file_open_cmd_callback | gimp_image_load | image open |
| File > Export | file_export_cmd_callback | file_export | export render |

### 3.2 图像操作模块

| GUI 路径 | 信号处理 | C API | CLI 建议 |
|---------|---------|-------|---------|
| Image > Scale | scale_cmd_callback | gimp_image_scale | image scale |
| Image > Crop | crop_cmd_callback | gimp_image_crop | image crop |
| Image > Flatten | flatten_cmd_callback | gimp_image_flatten | image flatten |

### 3.3 滤镜模块

| GUI 路径 | 信号处理 | C API | CLI 建议 |
|---------|---------|-------|---------|
| Filters > Blur > Gaussian | gaussian_blur_callback | plug_in_gauss_blur | filter gaussian-blur |
| Filters > Enhance > Sharpen | sharpen_callback | plug_in_sharpen | filter sharpen |

## 4. 状态模型

### 4.1 核心状态对象

- **Image**: 图像对象,包含图层、通道、路径
- **Layer**: 图层对象
- **Selection**: 选区对象
- **Project**: 项目文件(.xcf)

### 4.2 状态关系图

```mermaid
flowchart TD
    P[Project] --> I[Image]
    I --> L[Layers]
    I --> C[Channels]
    I --> S[Selection]

5. 批处理与自动化

5.1 现有批处理能力

  • Script-Fu: 内置脚本语言
  • Python-Fu: Python 脚本接口
  • Batch Mode: 无 GUI 批处理模式

5.2 CLI 化机会

  • 所有 Script-Fu 函数 → CLI 命令
  • Python-Fu 脚本 → CLI 子命令
  • Batch 命令序列 → REPL 会话

6. 依赖与约束

6.1 外部依赖

  • GTK+ 3.x
  • GEGL (图像处理引擎)
  • babl (像素格式转换)

6.2 运行时要求

  • X11 或 Wayland(或 headless 模式)
  • 最低 512MB RAM
  • 插件需要 GIMP 运行

7. API 覆盖率评估

模块 GUI 功能数 可映射 API 覆盖率
文件操作 15 15 100%
图像操作 42 40 95%
图层操作 38 35 92%
选区操作 24 22 92%
滤镜 156 140 90%
工具 48 25 52%
总计 323 277 86%

8. 风险与注意事项

  • 部分工具需要交互式输入,难以 CLI 化
  • 滤镜参数复杂,需要仔细设计 CLI 参数
  • 插件系统动态加载,需要运行时检测

## 分析方法详解

### 方法 1:源码静态分析

**步骤**:

```bash
# 1. 获取源码结构
tree -L 3 /path/to/software

# 2. 识别主入口
grep -r "def main" --include="*.py" .
grep -r "int main" --include="*.c" --include="*.cpp" .

# 3. 查找 GUI 回调
# GTK 应用
grep -r "g_signal_connect" --include="*.c" .
# Qt 应用
grep -r "connect(" --include="*.cpp" .

# 4. 识别公共 API
grep -r "^gimp_" --include="*.h" .  # GIMP C API

方法 2:运行时分析

# 对于 Python 应用,可以使用运行时分析
import inspect

# 列出模块所有函数
def list_module_apis(module):
    return [name for name, obj in inspect.getmembers(module)
            if inspect.isfunction(obj)]

# 追踪函数调用
import trace
tracer = trace.Trace(trace=1)
tracer.run('main()')

方法 3:文档与头文件分析

# 分析头文件获取 API 签名
# C/C++ 项目
cat /usr/include/gimp-2.0/libgimp/gimp.h

# Python 项目
python3 -c "import module; help(module)"

# 生成 API 文档
pip install pydoc-markdown
pydoc-markdown -p module > api.md

方法 4:现有脚本接口分析

许多软件已有脚本接口,这是 CLI 化的最佳起点:

# GIMP - Script-Fu
grep -r "define" /usr/share/gimp/2.0/scripts/*.scm

# Blender - Python API
ls /usr/share/blender/4.*/scripts/modules/bpy/

# LibreOffice - UNO API
find /usr/lib/libreoffice -name "*.idl"

实战案例:GIMP 分析

步骤 1:获取源码结构

# 克隆 GIMP 源码
git clone https://gitlab.gnome.org/GNOME/gimp.git
cd gimp

# 查看目录结构
tree -L 2 -d

输出分析

gimp/
├── app/           # 主应用程序代码
├── core/          # GIMP 核心库
├── gui/           # GTK+ GUI 代码
├── libgimp/       # C API 库(关键!)
├── libgimpbase/   # 基础数据结构
├── libgimpwidgets/# GIMP 专用 GTK 部件
├── plug-ins/      # 内置插件
├── data/          # 默认配置和数据文件
├── docs/          # 文档
└── devel-docs/    # 开发者文档

步骤 2:识别 C API

# libgimp/ 是 GIMP 的 C API 接口
ls libgimp/*.h | head -20

关键头文件

libgimp/gimp.h              # 主 API 头文件
libgimp/gimpimage.h         # 图像操作
libgimp/gimplayer.h         # 图层操作
libgimp/gimpselection.h     # 选区操作
libgimp/gimpchannel.h       # 通道操作
libgimp/gimppdb.h           # 过程数据库(所有可调用的过程)

步骤 3:列出所有可调用的过程

# 使用 GIMP 的 PDB(Procedure Database)
gimp-console --no-interface --batch-mode \
  -b - <<'EOF'
(let* (
    (procedures (gimp-pdb-query ".*" ".*" ".*" ".*" ".*" ".*" ".*"))
    (procedure-names (cadr procedures))
  )
  (while (not (null? procedure-names))
    (gimp-message (car procedure-names))
    (set! procedure-names (cdr procedure-names))
  )
)
(gimp-quit 0)
EOF

结果:发现 1000+ 可调用的 PDB 过程!

步骤 4:分类整理

# 按前缀分类
categories = {
    "file_": "文件操作",
    "gimp_image_": "图像操作",
    "gimp_layer_": "图层操作",
    "gimp_selection_": "选区操作",
    "plug_in_": "插件/滤镜",
    "script_fu_": "Script-Fu 脚本",
}

常见陷阱与应对

陷阱 1:混淆 GUI 层与业务层

flowchart TD
    A[错误:直接映射 GUI 代码]
    B[正确:找到 GUI 调用的业务逻辑]

    A --> C[CLI 依赖 GTK+]
    B --> D[CLI 独立运行]

    style A fill:#ffcccc
    style C fill:#ffcccc
    style B fill:#e8f5e9
    style D fill:#e8f5e9

应对方法

  • 追踪从 GUI 回调到业务逻辑的调用链
  • 找到"最后与 GUI 无关的函数"
  • 将该函数作为 CLI 入口

陷阱 2:忽视状态管理

# ❌ 错误:无状态设计
def apply_blur(image_path, radius):
    # 每次都要打开文件
    image = open_image(image_path)
    return blur(image, radius)

# ✅ 正确:支持状态管理
class Project:
    def __init__(self):
        self.images = {}
        self.active_image = None

    def open(self, path):
        self.active_image = open_image(path)

    def blur(self, radius):
        return blur(self.active_image, radius)

陷阱 3:遗漏批处理能力

检查清单

  • 软件是否有批处理模式?
  • 是否支持脚本语言?
  • 是否有 headless/无 GUI 模式?
  • 命令行参数支持哪些功能?

陷阱 4:忽视错误处理

# ❌ 错误:假设总是成功
def export(image, path):
    image.save(path)  # 可能抛出异常

# ✅ 正确:完善的错误处理
def export(image, path):
    try:
        if not image.is_valid():
            raise ValueError("Invalid image")
        if not path.endswith(('.png', '.jpg')):
            raise ValueError("Unsupported format")
        image.save(path)
        return {"success": True, "path": path}
    except Exception as e:
        return {"success": False, "error": str(e)}

工具与技巧

推荐工具

工具 用途 安装
ctags 代码标签索引 apt install universal-ctags
cscope C 代码浏览 apt install cscope
pyright Python 类型分析 pip install pyright
doxygen 文档生成 apt install doxygen
tree 目录结构查看 apt install tree

快捷键技巧

# 快速查找函数定义
grep -rn "def function_name" --include="*.py" .

# 查找所有调用某函数的地方
grep -rn "function_name(" --include="*.py" .

# 统计代码行数
find . -name "*.py" | xargs wc -l

# 查找 TODO/FIXME
grep -rn "TODO\|FIXME" --include="*.py" .

验证分析质量

检查清单

## 分析质量检查清单

### 完整性
- [ ] 覆盖了软件所有主要功能模块
- [ ] 识别了至少 80% 的可 CLI 化功能
- [ ] 记录了所有外部依赖

### 准确性
- [ ] API 名称与源码一致
- [ ] 参数类型正确
- [ ] 返回值描述准确

### 可操作性
- [ ] 每个 GUI 操作都有对应的 API
- [ ] 状态模型清晰完整
- [ ] 依赖关系明确

### 文档质量
- [ ] 使用标准模板
- [ ] 包含示例代码
- [ ] 覆盖率评估完整

小结

Analyze 阶段是 CLI-Anything 的基础:

  1. 扫描源码 - 理解软件结构和组织方式
  2. 识别功能 - 找出可供 CLI 调用的功能点
  3. 映射 API - 建立 GUI 到 API 的对应关系
  4. 生成文档 - 产出标准化的 API 映射文档

关键要点

  • ✅ 深入源码,不要停留在表面
  • ✅ 找到 GUI 层之下的业务逻辑
  • ✅ 重视状态模型的设计
  • ✅ 充分利用现有脚本接口
  • ✅ 评估真实的 API 覆盖率

系列导航