方向反转:此前 SKILL.md 是「模板渲染产物」、sap-cli 是源;现 sap-cli 归档, sap-cli-skill 承接开发与分发,SKILL.md 回归手工维护的正本。 迁移(来自 sap-cli,共 104 文件): - tests/ 692 例测试(15 个文件的内联 sys.path 改指 assets/) - openspec/ SDD 规格与归档变更(42 文件) - docs/ 开发文档与 ADT 原理(含 dev/CLAUDE.md、AGENTS.md) - .claude/ rules 副本 + settings.json(供 Claude Code) - .github/ .hermes/ .pre-commit-config.yaml .editorconfig CLAUDE.md - scripts/ 保持仅 setup.py(pack_skill.py 已随旧仓归档,不迁) 修复(迁移暴露的真实缺陷): - assets/pyproject.toml 的 build-backend 写作 `setuptools.backends._legacy:_Backend`, 该模块在 setuptools 中不存在 → `pip install -e` 从来装不上。改为 build_meta。 实测:临时 venv 安装成功,sap-cli --help 正常列出 31 个命令 - pyproject readme 指向不存在的 assets/README.md(editable 安装会失败)→ 改内联文本 - pyproject urls 改指 sap-cli-skill 机制调整: - .github/workflows/ci.yml 适配 assets/ 布局;顶部注明该工作流仅 GitHub 执行, 本仓在 Gitee 不会自动跑 - pre-commit 增本地测试门禁(Gitee 上真正生效的那道) - .gitignore 合并旧仓完整规则(保留 log/ 下 md 知识库入库,只忽略运行日志) - 大文件上限 100KB→1MB(架构图 512KB) 守卫测试 tests/unit/test_repo_guards.py(10 → 18 例): - SKILL.md 须记录 parser 全部 CLI 命令 / 铁律 1-5 须为真实小节标题 / 示例不得违反铁律 5 - references/ 规则齐备;.claude/rules 与 references 必须一致(实测抓到一次真实漂移) - VERSION == sapcli.__version__ == README 版本 - 仓内不得再出现 pack_skill.py / skill-src(防废弃流程回潮) 698 tests OK;editable 安装与 CLI 入口经临时 venv 实测通过。 docs/RELEASING.md 重写为单源开发流程。
21 KiB
sap-cli 操作手册
版本 2.3.0 · 最后更新 2026-08-06
目录
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 首次安装
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 系统信息:
cp config.ini.example config.ini
编辑 config.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。
方式二:环境变量
set SAP_HOST=http://your-sap:8000
set SAP_CLIENT=100
set SAP_USER=your_username
set SAP_PASSWORD=your_password
方式三:keyring 安全存储
python main.py auth login
# 输入 host / client / user / password 后,密码存入系统密钥环
python main.py auth status # 查看状态
python main.py auth logout # 删除密码
密码优先级: 环境变量 > keyring > config.ini
3.3 多系统切换
# 默认使用 [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 系统有正式证书:
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 |
批量同步模式
# 批量同步所有对象
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 |
传输管理
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
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
包管理
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 # 列出对象
项目模板
# 列出可用模板
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 # 数据模型
配置与认证
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:下载 → 编辑 → 同步
# 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:新建项目 + 批量开发
# 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:使用模板快速创建
# 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 对象管理
# 创建 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 运行测试
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 查看覆盖率
# 安装 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 通过动态读取自动同步:
[tool.setuptools.dynamic]
version = {attr = "sapcli.__version__"}
升级版本只需改 sapcli/__init__.py 中的 __version__。
7.2 发布流程
# 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 操作常用命令
# 查看状态
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 添加新命令
步骤:
-
在
sapcli/commands/下新建或修改命令文件:# 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}") -
在
sapcli/commands/__init__.py中导出:from sapcli.commands.my_cmd import cmd_my_command -
在
sapcli/cli/parser.py的build_parser()中添加子命令定义 -
在
sapcli/cli/app.py的command_map中注册路由 -
写测试 → 运行测试
8.2 添加新对象类型
在 sapcli/types.py 中注册:
_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 已排除)。
调试技巧
# 查看完整错误堆栈
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