# sap-cli 操作手册 > 版本 2.3.0 · 最后更新 2026-08-06 --- ## 目录 1. [项目概述](#1-项目概述) 2. [项目结构](#2-项目结构) 3. [安装与配置](#3-安装与配置) 4. [日常使用:命令速查](#4-日常使用命令速查) 5. [典型工作流](#5-典型工作流) 6. [测试管理](#6-测试管理) 7. [版本与发布](#7-版本与发布) 8. [开发指南](#8-开发指南) 9. [故障排查](#9-故障排查) --- ## 1. 项目概述 **sap-cli** 是一个基于 SAP ADT REST API 的 ABAP 开发对象管理工具。 **能做什么:** - 从 SAP 系统下载/上传 ABAP 源代码 - 在本地编辑器编写 ABAP,一键同步到 SAP 并激活 - 批量管理项目(init → sync --all → refresh) - 16 种 SAP 对象类型(report/class/table/CDS View 等) - 传输请求管理、代码搜索、依赖分析 **基本信息:** - 仓库地址:https://gitee.com/markwury168/sap-cli - 本地路径:`D:\Codespace\sap-cli\` - 运行方式:`python main.py <命令>` 或 `sap-cli <命令>`(安装后) - Python 版本:≥ 3.10 --- ## 2. 项目结构 ``` D:\Codespace\sap-cli\ │ ├── main.py # 入口文件(python main.py <命令>) ├── config.ini # SAP 连接配置(不入库,含密码) ├── config.ini.example # 配置模板 ├── pyproject.toml # 项目构建配置 + 版本号 ├── requirements.txt # 依赖(备用,首选 pyproject.toml) ├── README.md # 项目介绍 + 快速上手 ├── FEATURES.md # 功能全景文档 ├── CHANGELOG.md # 版本变更记录 ├── CONTRIBUTING.md # 协作规范 ├── LICENSE # MIT 许可 │ ├── sapcli/ # 源码包(核心代码) │ ├── __init__.py # 版本号 __version__ = "2.3.0" │ ├── cli/ # CLI 层(参数解析 + 入口路由) │ │ ├── parser.py # 228 行 — argparse 命令定义 │ │ ├── app.py # 159 行 — main() 入口 + 命令路由 │ │ └── output.py # 50 行 — 彩色输出工具 │ ├── client/ # API 层(SAP ADT 通信)— Mixin 架构 │ │ ├── _base.py # 88 行 — 连接、认证、通用请求 │ │ ├── _source.py # 354 行 — 源码读写、锁定、激活 │ │ ├── _transport.py # 203 行 — 传输请求管理 │ │ ├── _search.py # 197 行 — 搜索、Where-Used │ │ ├── _ddic.py # 639 行 — 对象创建/删除/DDIC │ │ └── __init__.py # 29 行 — ADTClient = 5个Mixin组合 │ ├── commands/ # 命令层(业务逻辑) │ │ ├── crud.py # 890 行 — download/sync/delete/info/create │ │ ├── batch.py # 328 行 — init/sync-all/refresh │ │ ├── search.py # 147 行 — list/whereused/search │ │ ├── transport.py # 136 行 — 传输请求操作 │ │ ├── cds.py # 186 行 — CDS View 操作 │ │ ├── package_cmd.py # 107 行 — ABAP 包管理 │ │ ├── quality.py # 131 行 — ATC 检查/格式化 │ │ ├── diff_cmd.py # 89 行 — 代码差异对比 │ │ ├── analyze.py # 126 行 — 依赖分析 │ │ ├── scaffold.py # 251 行 — 项目模板 │ │ ├── config_cmd.py # 106 行 — 配置管理 │ │ └── __init__.py # 69 行 — 统一导出 │ ├── config.py # 95 行 — 配置加载 │ ├── auth.py # 124 行 — 密钥管理(keyring) │ ├── password.py # 76 行 — 密码解析(从 auth 拆出) │ ├── types.py # 243 行 — 16 种对象类型定义 │ ├── manifest.py # 174 行 — 项目清单管理 │ ├── scanner.py # 121 行 — 项目目录扫描 │ ├── sorter.py # 152 行 — 拓扑排序 │ ├── ddic.py # 277 行 — DDIC XML 构建 │ ├── exceptions.py # 77 行 — 异常体系 │ └── utils/ # 工具函数 │ ├── xml_utils.py # 13 行 — XML 转义 │ └── __init__.py │ ├── tests/ # 测试(412 用例,84% 覆盖率) │ ├── test_sapcli.py # 68 个 — 基础层测试 │ └── unit/ # 单元测试 │ ├── test_client.py # 82 个 — API 层测试 │ ├── test_commands.py # 45 个 — 命令层测试 │ ├── test_commands_extra.py # 64 个 — 命令边界场景 │ ├── test_cli.py # 41 个 — 参数解析测试 │ ├── test_batch_analyze.py # 40 个 — 批量操作+分析 │ ├── test_modules.py # 58 个 — 散落模块测试 │ └── test_app_config.py # 14 个 — 入口+配置测试 │ ├── docs/ # 文档 │ ├── guide.md # 详细使用指南(24KB) │ ├── adt/ # 7 篇 ADT 原理文章 │ └── dev/ # 开发文档 │ ├── architecture.md # 架构说明 │ ├── CLAUDE.md # AI 协作规范 │ ├── AGENTS.md # AI Agent 规范 │ ├── test-plan.md # 测试方案 │ └── test-coverage-report.md # 覆盖率报告 │ ├── openspec/ # OpenSpec SDD 规范 │ ├── specs/ # 7 个领域的需求规格 │ └── changes/ # 变更记录(已归档) │ ├── .github/workflows/ci.yml # CI 自动测试 ├── .editorconfig # 编辑器统一配置 ├── .pre-commit-config.yaml # Git 提交前自动检查 └── .gitignore # Git 忽略规则 ``` ### 架构分层 ``` 用户输入 │ ▼ main.py → cli/app.py → cli/parser.py ← CLI 层:解析参数 │ ▼ commands/*.py ← 命令层:业务逻辑 │ ▼ client/*.py (Mixin) ← API 层:SAP ADT 通信 │ ▼ config.py / types.py / manifest.py / ... ← 基础层:工具与配置 ``` --- ## 3. 安装与配置 ### 3.1 首次安装 ```bash cd D:\Codespace\sap-cli # 安装项目(开发模式,代码修改立即生效) pip install -e . # 安装可选依赖(密码安全存储) pip install -e ".[keyring]" # 安装开发依赖(测试工具) pip install -e ".[dev]" ``` 安装后可以直接使用 `sap-cli` 命令(无需 `python main.py`)。 ### 3.2 SAP 连接配置 **方式一:配置文件(推荐)** 复制模板并填写你的 SAP 系统信息: ```bash cp config.ini.example config.ini ``` 编辑 `config.ini`: ```ini [SAP] host = http://your-sap-server:8000 client = 100 user = your_username password = your_password ; 多系统配置(用 --profile 切换): [DEV] host = http://dev-sap:8000 client = 100 user = dev_user password = dev_password [QAS] host = http://qas-sap:8000 client = 200 user = qas_user password = qas_password ``` > ⚠️ `config.ini` 包含密码,已在 `.gitignore` 中排除,**绝不要提交到 Git**。 **方式二:环境变量** ```bash set SAP_HOST=http://your-sap:8000 set SAP_CLIENT=100 set SAP_USER=your_username set SAP_PASSWORD=your_password ``` **方式三:keyring 安全存储** ```bash python main.py auth login # 输入 host / client / user / password 后,密码存入系统密钥环 python main.py auth status # 查看状态 python main.py auth logout # 删除密码 ``` **密码优先级:** 环境变量 > keyring > config.ini ### 3.3 多系统切换 ```bash # 默认使用 [SAP] 配置 python main.py download --name ZTEST --type report --path ./out # 切换到 [DEV] 系统 python main.py --profile DEV download --name ZTEST --type report --path ./out # 切换到 [QAS] 系统 python main.py --profile QAS info --name ZCL_MY --type class ``` ### 3.4 SSL 证书 默认关闭 SSL 验证(SAP 开发环境通常使用自签名证书)。如果你的 SAP 系统有正式证书: ```bash python main.py --verify-ssl download --name ZTEST --type report --path ./out ``` --- ## 4. 日常使用:命令速查 ### 4.1 全局参数 | 参数 | 说明 | 示例 | |------|------|------| | `--config` | 指定配置文件路径 | `--config ./my.ini` | | `--profile` / `-p` | 切换系统配置 | `--profile DEV` | | `--verify-ssl` | 启用 SSL 证书验证 | `--verify-ssl` | ### 4.2 支持的 16 种对象类型 ``` report class interface function functiongroup domain dataelement table structure tabletype include cdsview messageclass view searchhelp lockobject ``` ### 4.3 命令一览(20 个) #### 核心操作 | 命令 | 用途 | 示例 | |------|------|------| | **download** | 下载 SAP 对象源码到本地 | `python main.py download --name ZTEST --type report --path ./out` | | **sync** | 上传本地代码到 SAP 并激活 | `python main.py sync --name ZTEST --type report --path ./ztest.abap` | | **create** | 在 SAP 创建新对象 | `python main.py create --name ZTEST --type report` | | **delete** | 从 SAP 删除对象 | `python main.py delete --name ZTEST --type report` | | **info** | 查询对象元数据 | `python main.py info --name ZCL_MY --type class` | #### 批量项目管理 | 命令 | 用途 | 示例 | |------|------|------| | **init** | 初始化项目清单 | `python main.py init --path ./my_project` | | **refresh** | 刷新清单中的 SAP 状态 | `python main.py refresh --path ./my_project` | #### 批量同步模式 ```bash # 批量同步所有对象 python main.py sync --all --path ./my_project # 预览模式(不实际操作) python main.py sync --all --path ./my_project --dry-run # 遇到失败立即停止 python main.py sync --all --path ./my_project --fail-fast # 指定传输请求号 python main.py sync --name ZTEST --type report --path ./ztest.abap --corr_nr DEVK901362 ``` #### 搜索与浏览 | 命令 | 用途 | 示例 | |------|------|------| | **list** | 列出 SAP 对象 | `python main.py list --type report --prefix Z*` | | **whereused** | Where-Used 引用查询 | `python main.py whereused --name ZTEST --type report` | | **search** | 源代码搜索 | `python main.py search --query "CALL FUNCTION"` | | **analyze** | 依赖自动分析 | `python main.py analyze --path ./my_project` | #### 传输管理 ```bash python main.py transport list # 列出可修改的传输请求 python main.py transport info --corr_nr DEVK901362 # 查看传输详情 python main.py transport release --corr_nr DEVK901362 # 释放传输 python main.py transport objects --corr_nr DEVK901362 # 列出传输中的对象 ``` #### 代码质量 | 命令 | 用途 | 示例 | |------|------|------| | **check** | ATC 代码检查 | `python main.py check --name ZTEST --type report` | | **format** | ABAP Pretty Printer | `python main.py format --name ZTEST --type report` | | **diff** | 本地 vs SAP 差异 | `python main.py diff --name ZTEST --type report --path ./ztest.abap` | #### CDS View ```bash python main.py cds download --name ZMY_CDS --path ./out # 下载 DDL python main.py cds sync --name ZMY_CDS --path ./ddl.abap # 同步 DDL python main.py cds create --name ZMY_CDS # 创建 CDS ``` #### 包管理 ```bash python main.py package create --name ZMY_PKG --description "我的包" # 创建 python main.py package info --name ZMY_PKG # 查看 python main.py package list --name ZMY_PKG # 列出对象 ``` #### 项目模板 ```bash # 列出可用模板 python main.py scaffold --name ZTEST # 使用指定模板 python main.py scaffold --name ZTEST --template alv-report # ALV 报表 python main.py scaffold --name ZTEST --template bapi-wrapper # BAPI 封装 python main.py scaffold --name ZTEST --template interface-class # 接口类 python main.py scaffold --name ZTEST --template data-model # 数据模型 ``` #### 配置与认证 ```bash python main.py config show # 显示当前配置 python main.py config list-profiles # 列出所有 profile python main.py config set host http://new-host:8000 # 修改配置 python main.py auth login # 保存密码到 keyring python main.py auth logout # 删除密码 python main.py auth status # 查看状态 ``` --- ## 5. 典型工作流 ### 工作流 A:下载 → 编辑 → 同步 ```bash # 1. 下载 SAP 对象源码 python main.py download --name ZMY_REPORT --type report --path ./src # 2. 用你喜欢的编辑器修改 ./src/zmy_report.abap # 3. 同步回 SAP 并激活 python main.py sync --name ZMY_REPORT --type report --path ./src/zmy_report.abap ``` ### 工作流 B:新建项目 + 批量开发 ```bash # 1. 创建项目目录结构 mkdir my_project mkdir my_project\reports my_project\classes my_project\functions # 2. 在各目录下编写 .abap 文件 # 3. 初始化项目清单(扫描目录 → 查询 SAP → 写 manifest.json) python main.py init --path ./my_project # 4. 批量同步到 SAP python main.py sync --all --path ./my_project # 5. 后续修改后再次同步 python main.py sync --all --path ./my_project # 6. 刷新 SAP 状态 python main.py refresh --path ./my_project ``` ### 工作流 C:使用模板快速创建 ```bash # 1. 生成 ALV 报表模板 python main.py scaffold --name ZALV_DEMO --template alv-report --path ./my_project # 2. 编辑生成的文件 # my_project/reports/zalv_demo.abap # 3. 初始化 + 同步 python main.py init --path ./my_project python main.py sync --all --path ./my_project ``` ### 工作流 D:DDIC 对象管理 ```bash # 创建 DDIC 对象(需要 JSON 定义文件) python main.py create --name ZMY_DOMAIN --type domain --definition ./domain_def.json python main.py create --name ZMY_TABLE --type table --definition ./table_def.json # 创建时指定包和传输请求 python main.py create --name ZMY_CLASS --type class --package ZMY_PKG --corr_nr DEVK901362 ``` ### 项目目录命名规范 批量模式时,scanner 按目录名识别对象类型: | 目录名 | 对象类型 | |--------|---------| | `reports/` | report | | `classes/` | class | | `interfaces/` | interface | | `functions/` | function(子目录 = 函数组名) | | `domains/` | domain | | `dataelements/` | dataelement | | `tables/` | table | | `structures/` | structure | | `tabletypes/` | tabletype | | `includes/` | include | | `cdsviews/` | cdsview | | `messageclasses/` | messageclass | | `views/` | view | | `searchhelps/` | searchhelp | | `lockobjects/` | lockobject | 函数组特殊结构: ``` functions/ └── zmy_group/ ← 函数组名(子目录名) ├── zfunc1.abap ← 函数模块 └── zfunc2.abap ``` --- ## 6. 测试管理 ### 6.1 运行测试 ```bash cd D:\Codespace\sap-cli # 运行全部测试(412 用例) python -m unittest discover -s tests -p "test_*.py" # 运行单个测试文件 python tests/unit/test_client.py python tests/test_sapcli.py # 运行特定测试类 python -m unittest tests.unit.test_cli.TestParserDownload # 运行特定测试方法 python -m unittest tests.unit.test_client.TestADTClient.test_login_success ``` ### 6.2 查看覆盖率 ```bash # 安装 coverage pip install coverage # 运行测试并收集覆盖率 coverage run -m unittest discover -s tests -p "test_*.py" # 查看终端报告 coverage report --include="sapcli/*" # 生成 HTML 报告(浏览器打开) coverage html --include="sapcli/*" # 报告在 tests/coverage_html/index.html ``` ### 6.3 测试文件说明 | 文件 | 用例数 | 覆盖内容 | |------|--------|----------| | `test_sapcli.py` | 68 | 基础层(types/config/exceptions/manifest) | | `test_client.py` | 82 | API 层(ADTClient 全部方法) | | `test_commands.py` | 45 | 命令层(各命令 happy path) | | `test_commands_extra.py` | 64 | 命令层(边界场景/错误处理) | | `test_cli.py` | 41 | 参数解析(全部 20 个命令) | | `test_batch_analyze.py` | 40 | 批量操作 + 依赖分析 | | `test_modules.py` | 58 | 散落模块(scanner/sorter/auth/password) | | `test_app_config.py` | 14 | CLI 入口 + 配置命令 | ### 6.4 当前覆盖率(84%) ``` 100% — parser, manifest, exceptions, utils, commands/__init__ 96%+ — batch, sorter, scanner, scaffold, types, config 90%+ — search, transport, client (各 Mixin) 80%+ — app, auth, config_cmd, ddic, quality 60%+ — crud, output ``` --- ## 7. 版本与发布 ### 7.1 版本号在哪 版本号 **只在一个地方维护**: ``` sapcli/__init__.py → __version__ = "2.3.0" ``` `pyproject.toml` 通过动态读取自动同步: ```toml [tool.setuptools.dynamic] version = {attr = "sapcli.__version__"} ``` **升级版本只需改 `sapcli/__init__.py` 中的 `__version__`。** ### 7.2 发布流程 ```bash # 1. 修改版本号 # 编辑 sapcli/__init__.py → __version__ = "2.2.0" # 2. 更新 CHANGELOG.md # 3. 提交 git add -A && git commit -m "release: v2.2.0" # 4. 打标签 git tag v2.2.0 # 5. 推送 git push --tags ``` ### 7.3 Git 操作常用命令 ```bash # 查看状态 git status # 查看历史 git log --oneline -10 # 提交代码 git add -A git commit -m "feat: 新增 xxx 功能" git push # 回退未提交的修改 git checkout -- . # 查看 config.ini 是否被误加入暂存 git ls-files | grep config.ini ``` --- ## 8. 开发指南 ### 8.1 添加新命令 **步骤:** 1. 在 `sapcli/commands/` 下新建或修改命令文件: ```python # sapcli/commands/my_cmd.py import argparse from sapcli.client import ADTClient def cmd_my_command(args: argparse.Namespace, client: ADTClient) -> None: """我的新命令。""" print(f"执行 my-command: {args.name}") ``` 2. 在 `sapcli/commands/__init__.py` 中导出: ```python from sapcli.commands.my_cmd import cmd_my_command ``` 3. 在 `sapcli/cli/parser.py` 的 `build_parser()` 中添加子命令定义 4. 在 `sapcli/cli/app.py` 的 `command_map` 中注册路由 5. 写测试 → 运行测试 ### 8.2 添加新对象类型 在 `sapcli/types.py` 中注册: ```python _TYPE_REGISTRY["mytype"] = ObjectTypeConfig( obj_type="mytype", program_type="MYT", adt_type="MYT", adt_uri="mytypes", # ... ) ``` 然后在 `scanner.py` 的 `DIRECTORY_TYPE_MAP` 和 `sorter.py` 的 `TYPE_PRIORITY` 中补充。 ### 8.3 代码风格 - Python PEP 8 - `.editorconfig` 已配置:4 空格缩进,UTF-8,LF 换行 - pre-commit hooks 自动检查(安装后运行 `pre-commit install`) ### 8.4 新增 API 方法 API 方法在 `sapcli/client/` 目录的 Mixin 模块中: | 功能域 | 文件 | 示例方法 | |--------|------|---------| | 连接/认证 | `_base.py` | login, object_exists | | 源码读写 | `_source.py` | get_source, set_source, lock, unlock | | 传输管理 | `_transport.py` | list_transport_requests, transport_release | | 搜索查询 | `_search.py` | list_objects, where_used, search_code | | 对象操作 | `_ddic.py` | create_object, delete_object, create_ddic_object | 添加新方法时,放在对应 Mixin 文件中即可。`ADTClient` 类自动继承所有 Mixin。 --- ## 9. 故障排查 ### 常见问题 | 问题 | 原因 | 解决 | |------|------|------| | `✗ 配置文件不存在` | 没有 config.ini | 复制 `config.ini.example` 为 `config.ini` 并填写 | | `✗ 登录失败` | SAP 地址/密码错误 | 检查 config.ini 中的 host/user/password | | `✗ 对象不存在` | 名称或类型不对 | 检查大小写,SAP 对象名通常大写 | | `SSL 证书错误` | SAP 自签名证书 | 默认已关闭验证,检查是否误加 `--verify-ssl` | | `keyring 不可用` | 未安装 keyring | `pip install keyring` | | `config.ini 入了 Git` | 误提交 | `git rm --cached config.ini && git commit` | ### 日志文件 运行日志自动写入 `log/adt_tools.log`(`.gitignore` 已排除)。 ### 调试技巧 ```bash # 查看完整错误堆栈 python main.py download --name ZTEST --type report --path ./out 2>&1 | more # 查看日志 cat log/adt_tools.log | tail -50 # 验证配置是否正确 python main.py config show # 验证连接是否可用 python main.py list --type report --prefix Z* ``` --- ## 附录:版本历史 | 版本 | 日期 | 关键变更 | |------|------|---------| | v2.1.0 | 2026-06-09 | 全面重构:20 命令、16 类型、Mixin 架构、412 测试 | | v2.0.0 | 2026-06-08 | OpenSpec SDD 重构、项目结构整理 | | v1.0.0 | 2026-05 | 初始版本 | > 详细变更记录见 `CHANGELOG.md`