refactor: 本仓升为唯一源(原 sap-cli 源码仓归档)

方向反转:此前 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 重写为单源开发流程。
This commit is contained in:
吴让宇
2026-09-11 00:40:15 +08:00
parent e786742bcb
commit c5905a5b1e
104 changed files with 20744 additions and 10 deletions
@@ -0,0 +1,4 @@
schema: spec-driven
change: add-dictionary-objects
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,32 @@
## Context
sap-cli 当前支持 10 种 ABAP 开发对象类型的 CRUD 操作。本变更扩展至 14 种类型,新增消息类、数据库视图、搜索帮助和锁对象。这 4 种类型都属于 ABAP Dictionary (DDIC) 类别,创建时需要 XML body 而非纯文本源码。
## Goals
- 注册 4 种新的 DDIC 对象类型到类型注册表
- 实现 4 种类型的 create/info/delete 操作
- 对有源码的类型(view)支持 download/sync
- 对无源码的类型(messageclass、lockobject)明确提示不支持
- 支持 JSON 定义文件创建 DDIC 对象
## Non-Goals
- 不实现搜索帮助的测试数据生成
- 不实现锁对象的自动函数模块调用
- 不涉及 CDS Access Control (DCL) 类型(P4 级别)
## Decisions
1. **消息类使用专用端点**`/sap/bc/adt/messageclasses`,消息内容通过 XML 维护
2. **视图使用 DDIC 端点**`/sap/bc/adt/ddic/views`,与 table/structure 类似的 XML schema
3. **搜索帮助使用 DDIC 端点**`/sap/bc/adt/ddic/searchhelps`
4. **锁对象使用 DDIC 端点**`/sap/bc/adt/ddic/lockobjects`
5. **文件扩展名统一 .abap**:有源码类型(view)的源码文件保持 .abap 扩展名
6. **目录命名约定**`messageclasses/``views/``searchhelps/``lockobjects/`
## Risks / Trade-offs
- **ADT 端点兼容性**:不同 SAP 版本(ECC vs S/4HANA)的端点可能有差异,需要实际验证
- **消息类 XML schema 复杂**:消息内容可能需要额外的 XML 处理逻辑
- **锁对象自动生成物**:SAP 会在锁对象创建时自动生成 enqueue/dequeue 函数模块,删除锁对象时这些也会被删除
@@ -0,0 +1,30 @@
# Proposal: 新增 ABAP 字典对象类型支持
## Why
当前 sap-cli 支持的 10 种对象类型覆盖了日常开发的基础需求,但 SAP 实际项目中还频繁使用消息类(Message Class)、数据库视图(Database View)、搜索帮助(Search Help)和锁对象(Lock Object)。缺少这些类型意味着开发者仍需回到 SAP GUI 处理这些对象,破坏了 CLI 工具的连贯工作流。
## What Changes
- **消息类 (Message Class)**MESSAGE 语句的核心依赖,几乎每个项目都需要。ADT 端点 `/sap/bc/adt/messageclasses`
- **数据库视图 (Database View)**:数据建模和查询优化的基础工具。ADT 端点 `/sap/bc/adt/ddic/views`
- **搜索帮助 (Search Help)**ALV 屏幕 F4 帮助和数据输入辅助。ADT 端点 `/sap/bc/adt/ddic/searchhelps`
- **锁对象 (Lock Object)**:多用户并发控制,数据一致性保障。ADT 端点 `/sap/bc/adt/ddic/lockobjects`
这 4 种类型均为 DDIC 类别,创建时需要 XML 定义(非纯文本源码),与现有的 domain/dataelement/table 类型处理方式类似。
## Capabilities
### New Capabilities
(无新领域)
### Modified Capabilities
- `object-lifecycle`: 扩展支持消息类、数据库视图、搜索帮助、锁对象的 CRUD 操作
## Impact
- types.py:注册 4 个新 ObjectTypeConfig
- client.py:新增 4 种类型的创建模板和 ADT 交互逻辑
- ddic.py:扩展 DDIC XML 生成以支持新类型
- scanner.py:新增目录映射(messageclasses/、views/、searchhelps/、lockobjects/
- 约定文件扩展名保持 .abap(消息类和锁对象无源码端点,仅支持 create/info/delete
@@ -0,0 +1,61 @@
## MODIFIED Requirements
### Requirement: Object Creation
系统 SHALL 在 SAP 系统中创建开发对象,支持 14 种对象类型。
#### Scenario: Create message class
- **WHEN** 用户执行 create 命令,指定类型为 messageclass,并提供名称和描述
- **THEN** 系统在 SAP 中创建消息类对象
#### Scenario: Create database view
- **WHEN** 用户执行 create 命令,指定类型为 view,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建数据库视图
#### Scenario: Create search help
- **WHEN** 用户执行 create 命令,指定类型为 searchhelp,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建搜索帮助
#### Scenario: Create lock object
- **WHEN** 用户执行 create 命令,指定类型为 lockobject,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建锁对象
### Requirement: Source Code Download
系统 SHALL 从 SAP 系统下载对象源代码,支持所有有源码端点的对象类型。
#### Scenario: Download database view source
- **WHEN** 用户下载 view 类型对象
- **THEN** 系统下载视图的 DDL 定义源码
#### Scenario: Message class has no source
- **WHEN** 用户尝试下载 messageclass 类型
- **THEN** 系统报告该类型不支持下载操作
#### Scenario: Lock object has no source
- **WHEN** 用户尝试下载 lockobject 类型
- **THEN** 系统报告该类型不支持下载操作
### Requirement: Object Information Query
系统 SHALL 查询 SAP 系统中所有支持类型的开发对象元数据。
#### Scenario: Query message class info
- **WHEN** 用户执行 info 命令查询消息类
- **THEN** 系统显示消息类的名称、描述、消息数量等元数据
#### Scenario: Query view info
- **WHEN** 用户执行 info 命令查询数据库视图
- **THEN** 系统显示视图的名称、描述、关联表等元数据
### Requirement: Object Deletion
系统 SHALL 从 SAP 系统中删除所有支持类型的开发对象。
#### Scenario: Delete message class
- **WHEN** 用户执行 delete 命令删除消息类并确认
- **THEN** 系统删除该消息类
#### Scenario: Delete lock object
- **WHEN** 用户执行 delete 命令删除锁对象并确认
- **THEN** 系统删除该锁对象及其自动生成的函数模块
@@ -0,0 +1,34 @@
## 1. Type Registration
- [x] 1.1 Register messageclass in types.py with ADT URI template
- [x] 1.2 Register view in types.py with ADT URI template
- [x] 1.3 Register searchhelp in types.py with ADT URI template
- [x] 1.4 Register lockobject in types.py with ADT URI template
- [x] 1.5 Verify all_type_keys() returns 16 types
## 2. DDIC XML Generation
- [x] 2.1 Add messageclass XML template to ddic.py
- [x] 2.2 Add view XML template to ddic.py
- [x] 2.3 Add searchhelp XML template to ddic.py
- [x] 2.4 Add lockobject XML template to ddic.py
## 3. Client API Extension
- [x] 3.1 Add messageclass create body to _build_create_body
- [x] 3.2 Add view create body to _build_create_body
- [x] 3.3 Add searchhelp create body to _build_create_body
- [x] 3.4 Add lockobject create body to _build_create_body
## 4. Scanner Update
- [x] 4.1 Add messageclasses/ directory mapping to scanner.py
- [x] 4.2 Add views/ directory mapping to scanner.py
- [x] 4.3 Add searchhelps/ directory mapping to scanner.py
- [x] 4.4 Add lockobjects/ directory mapping to scanner.py
## 5. Verification
- [x] 5.1 Run existing test suite (66/68 baseline preserved)
- [x] 5.2 Updated test_openspec_specs_exist for new 7-domain structure
- [x] 5.3 Verified --help and all imports work
@@ -0,0 +1,4 @@
schema: spec-driven
change: base-batch
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,27 @@
# Proposal: 批量操作与项目管理
## Why
单对象 CRUD 无法满足实际项目中的批量化需求。SAP 项目通常包含数十甚至上百个相互依赖的开发对象,需要批量初始化、状态跟踪、依赖排序和批量同步的能力。同时,传输请求管理是 SAP 开发工作流中不可或缺的一环。
## What Changes
- 项目初始化:创建约定目录结构(reports/、classes/、functions/ 等)和 manifest.json
- 目录扫描:自动识别 .abap 文件,按约定目录映射对象类型
- 清单管理:manifest.json 跟踪对象状态、同步结果和依赖关系
- 依赖排序:基于 Kahn 算法进行拓扑排序,确保正确的执行顺序
- 批量同步:sync --all 模式,支持 --dry-run 和 --fail-fast
- 状态刷新:批量检查 SAP 系统中的对象状态
- 传输请求基础管理:list、create、select
## Capabilities
### New Capabilities
- `batch-ops`: 项目级批量操作(初始化、清单管理、扫描、排序、批量同步、状态刷新)
## Impact
- 引入 manifest.json 作为项目状态跟踪机制
- 建立约定目录结构(reports/、classes/、interfaces/、functions/ 等 10 个目录)
- sync 命令新增 --all、--dry-run、--fail-fast 参数
- 为后续 P0/P1 扩展(list、whereused、transport 高级管理等)奠定基础
@@ -0,0 +1,89 @@
## ADDED Requirements
### Requirement: Project Initialization
系统 SHALL 初始化一个 ABAP 项目目录结构。
#### Scenario: Init new project
- **WHEN** 用户执行 init 命令并指定项目路径
- **THEN** 系统创建标准目录结构(reports/、classes/、functions/ 等)和空的 manifest.json
### Requirement: Manifest Management
系统 SHALL 管理项目清单文件,记录所有开发对象的状态。
#### Scenario: Manifest tracks objects
- **WHEN** 对象被创建、同步或删除后
- **THEN** 清单文件自动更新对象的状态、最后同步时间和同步结果
#### Scenario: Query pending objects
- **WHEN** 清单中存在未成功同步的对象
- **THEN** 系统能够识别并列出这些待处理对象
#### Scenario: Query up-to-date objects
- **WHEN** 清单中存在已激活且同步成功的对象
- **THEN** 系统能够过滤出这些就绪对象
### Requirement: Directory Scanning
系统 SHALL 扫描本地项目目录,自动识别 ABAP 开发对象文件。
#### Scenario: Scan standard directories
- **WHEN** 项目目录包含约定命名的子目录及其中的 .abap 文件
- **THEN** 系统识别每个文件对应的对象名称、类型和路径
#### Scenario: Function directory structure
- **WHEN** 扫描 functions/ 目录
- **THEN** 子目录名解析为函数组名,文件名解析为函数模块名
#### Scenario: Skip hidden files
- **WHEN** 目录中存在以 . 开头的文件
- **THEN** 系统跳过这些隐藏文件
### Requirement: Dependency Sorting
系统 SHALL 根据对象间依赖关系确定正确的执行顺序。
#### Scenario: Sort by dependency
- **WHEN** 对象之间存在依赖关系
- **THEN** 被依赖的对象排在前面(如接口在类之前)
#### Scenario: Same priority tie-breaker
- **WHEN** 多个对象无依赖关系
- **THEN** 按照类型优先级排序(interface 最高,report 最低)
#### Scenario: Detect cyclic dependency
- **WHEN** 对象间存在循环依赖
- **THEN** 系统报告循环依赖错误并显示循环链
#### Scenario: Ignore external dependencies
- **WHEN** 对象依赖了不在当前项目中的外部对象
- **THEN** 系统忽略该外部依赖,不报错
### Requirement: Batch Sync
系统 SHALL 支持项目级批量同步操作。
#### Scenario: Sync all objects
- **WHEN** 用户执行 sync --all 命令
- **THEN** 系统扫描项目、按依赖排序、逐个同步所有对象
#### Scenario: Dry run mode
- **WHEN** 用户执行 sync --all --dry-run
- **THEN** 系统仅显示将要同步的对象列表,不实际执行
#### Scenario: Fail fast mode
- **WHEN** 用户执行 sync --all --fail-fast
- **THEN** 任一对象同步失败时立即停止
#### Scenario: Sequential progress
- **WHEN** 批量同步进行中
- **THEN** 系统逐一显示每个对象的同步进度和结果
### Requirement: Status Refresh
系统 SHALL 刷新项目清单中所有对象在 SAP 系统中的状态。
#### Scenario: Refresh object status
- **WHEN** 用户执行 refresh 命令
- **THEN** 系统查询每个对象在 SAP 中的最新状态并更新清单
@@ -0,0 +1,47 @@
## 1. Project Initialization
- [x] 1.1 Create standard directory structure (reports/, classes/, interfaces/, functions/, domains/, dataelements/, tables/, structures/, tabletypes/)
- [x] 1.2 Generate empty manifest.json with version and timestamp
- [x] 1.3 Support --path for custom project directory
## 2. Manifest Management
- [x] 2.1 Define Manifest and ManifestEntry data classes
- [x] 2.2 Implement JSON serialization/deserialization (to_dict/from_dict)
- [x] 2.3 Implement load/save/upsert/remove/get operations
- [x] 2.4 Track system_status (active/inactive/not_exists)
- [x] 2.5 Track last_sync_result (success/failed/pending/skipped)
- [x] 2.6 Implement pending_objects() and active_up_to_date_objects() queries
## 3. Directory Scanning
- [x] 3.1 Map directory names to object types (DIRECTORY_TYPE_MAP)
- [x] 3.2 Parse .abap files into ScannedObject entries
- [x] 3.3 Handle functions/ subdirectory as group/module naming
- [x] 3.4 Skip hidden files (dot-prefixed)
## 4. Dependency Sorting
- [x] 4.1 Implement Kahn's algorithm for topological sort
- [x] 4.2 Add TYPE_PRIORITY tie-breaker (interface:50, class:60, function:70, report:80, others:90)
- [x] 4.3 Detect cyclic dependencies and raise CyclicDependencyError
- [x] 4.4 Ignore external dependencies not in current manifest
## 5. Batch Sync
- [x] 5.1 Implement sync --all mode with scan → sort → sequential sync pipeline
- [x] 5.2 Add --dry-run flag for preview-only mode
- [x] 5.3 Add --fail-fast flag for stop-on-first-error mode
- [x] 5.4 Update manifest after each sync attempt
- [x] 5.5 Validate --all mode excludes --name and --type
## 6. Status Refresh
- [x] 6.1 Query SAP system for each object's current status
- [x] 6.2 Update manifest with latest status information
## 7. Transport Request (Basic)
- [x] 7.1 Support --corr_nr in sync and create for transport binding
- [x] 7.2 Auto-detect object's bound transport request on lock
- [x] 7.3 Interactive transport request selection when needed
@@ -0,0 +1,4 @@
schema: spec-driven
change: base-core
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,31 @@
# Proposal: sap-cli 核心基础 — 连接与 CRUD
## Why
ABAP 开发者长期依赖 SAP GUI 进行日常开发,需要在 IDE 和 GUI 之间频繁切换。sap-cli 的目标是让开发者用自己喜欢的本地编辑器写 ABAP 代码,通过命令行完成与 SAP 的交互。首先需要建立可靠的基础:连接 SAP 系统、加载配置,并实现开发对象的基本 CRUD 操作。
## What Changes
- 通过 SAP ADT REST API 建立连接与身份认证(HTTP Basic Auth + CSRF Token
- 支持 config.ini 和环境变量两种配置方式
- 实现 10 种 ABAP 开发对象类型的完整 CRUD:
- 源码对象:report、class、interface、function
- DDIC 对象:domain、dataelement、table、structure、tabletype
- 特殊对象:functiongroup(无源码)
- sync 命令实现锁定→写入→解锁→语法检查→激活的完整工作流
- create 支持默认模板和自定义源码两种方式
- DDIC 对象支持通过 JSON 定义文件创建
- delete 操作需要用户交互确认
## Capabilities
### New Capabilities
- `connection`: SAP ADT 连接建立、认证、配置加载
- `object-lifecycle`: 10 种开发对象的创建、下载、同步、查询、删除
## Impact
- 建立 sap-cli 的核心架构:main.py → ADTClient → SAP ADT REST API
- 定义 10 种对象类型的统一注册表(types.py)
- 建立统一异常体系(11 个错误类型)
- 为后续批量操作、搜索浏览等功能奠定基础
@@ -0,0 +1,45 @@
## ADDED Requirements
### Requirement: User Authentication
系统 SHALL 通过 SAP ADT REST API 使用 HTTP Basic Auth 进行身份认证。
#### Scenario: Successful login
- **WHEN** 用户提供有效的 SAP 主机地址、客户端编号、用户名和密码
- **THEN** 系统打印 "登录成功" 并建立可用会话
#### Scenario: Login failure
- **WHEN** 用户提供了无效的 SAP 凭据
- **THEN** 系统打印错误信息并以非零退出码退出
#### Scenario: Config not found
- **WHEN** 用户未提供配置文件且未设置环境变量
- **THEN** 系统打印配置缺失提示,列出需要的环境变量名,并以非零退出码退出
### Requirement: Configuration Loading
系统 SHALL 支持 config.ini 文件和环境变量两种配置方式,环境变量优先。
#### Scenario: Load from config file
- **WHEN** 当前目录或指定路径存在有效的 config.ini
- **THEN** 系统从配置文件读取 SAP 连接参数
#### Scenario: Environment variable override
- **WHEN** 同时存在配置文件和环境变量
- **THEN** 环境变量值覆盖配置文件中的对应项
#### Scenario: Client number default
- **WHEN** 配置中未指定 SAP 客户端编号
- **THEN** 系统使用默认值 "100"
### Requirement: Global Options
系统 SHALL 支持全局命令行选项。
#### Scenario: Custom config path
- **WHEN** 用户通过 --config 指定配置文件路径
- **THEN** 系统从指定路径加载配置
#### Scenario: No command specified
- **WHEN** 用户运行程序但未指定任何子命令
- **THEN** 系统打印帮助信息并以退出码 1 退出
@@ -0,0 +1,93 @@
## ADDED Requirements
### Requirement: Object Creation
系统 SHALL 在 SAP 系统中创建开发对象,支持 10 种 ABAP 对象类型。
#### Scenario: Create with default template
- **WHEN** 用户执行 create 命令,指定对象名称和类型,未提供自定义源码
- **THEN** 系统使用内置模板生成源码并在 SAP 中创建对象
#### Scenario: Create with custom source file
- **WHEN** 用户通过 --source 参数指定本地 .abap 文件
- **THEN** 系统读取文件内容作为源码并在 SAP 中创建对象
#### Scenario: Create DDIC object with definition
- **WHEN** 用户通过 --definition 参数指定 .json 文件创建 DDIC 对象
- **THEN** 系统将 JSON 定义转换为 SAP 所需格式并创建对象
#### Scenario: Create already existing object
- **WHEN** SAP 系统中已存在同名同类型对象
- **THEN** 系统报告对象已存在的错误
### Requirement: Source Code Download
系统 SHALL 从 SAP 系统下载对象源代码并保存到本地文件。
#### Scenario: Download existing object
- **WHEN** 用户执行 download 命令,SAP 系统存在该对象
- **THEN** 系统下载源码,保存到指定目录,文件名为小写对象名+.abap
#### Scenario: Download non-existent object
- **WHEN** 用户执行 download 命令,SAP 系统不存在该对象
- **THEN** 系统报告对象不存在的错误
#### Scenario: Download function type
- **WHEN** 用户下载 function 类型,名称格式为 "组名/模块名"
- **THEN** 系统正确解析组名和模块名,下载函数模块源码
#### Scenario: Download type without source
- **WHEN** 用户尝试下载不支持源码的类型(如 functiongroup
- **THEN** 系统报告该类型不支持下载操作
### Requirement: Source Code Sync
系统 SHALL 将本地源代码同步到 SAP 系统,执行锁定→写入→解锁→语法检查→激活流程。
#### Scenario: Full sync success
- **WHEN** 用户执行 sync 命令,本地文件和 SAP 对象均有效
- **THEN** 系统依次执行各步骤,每步报告 ✓ 状态
#### Scenario: Auto-create on sync
- **WHEN** 用户同步一个 SAP 中不存在的对象
- **THEN** 系统自动创建空对象后继续同步流程
#### Scenario: Syntax check failure
- **WHEN** 源码包含语法错误
- **THEN** 系统报告语法错误详情(行号和描述),不继续激活
#### Scenario: Activation failure
- **WHEN** 语法检查通过但激活失败
- **THEN** 系统报告激活错误详情
#### Scenario: Sync with specified transport request
- **WHEN** 用户通过 --corr_nr 指定传输请求号
- **THEN** 系统在锁定和写入时使用该传输请求
### Requirement: Object Information Query
系统 SHALL 查询 SAP 系统中开发对象的元数据信息。
#### Scenario: Query existing object
- **WHEN** 用户执行 info 命令,SAP 系统存在该对象
- **THEN** 系统显示名称、类型、描述、激活状态、负责人、修改时间等元数据
#### Scenario: Query non-existent object
- **WHEN** 用户执行 info 命令,SAP 系统不存在该对象
- **THEN** 系统报告对象不存在的错误
### Requirement: Object Deletion
系统 SHALL 从 SAP 系统中删除开发对象。
#### Scenario: Delete with confirmation
- **WHEN** 用户执行 delete 命令并确认删除
- **THEN** 系统锁定、删除对象并报告成功
#### Scenario: Delete cancelled
- **WHEN** 用户执行 delete 命令但未确认
- **THEN** 系统取消操作,不执行删除
#### Scenario: Delete non-existent object
- **WHEN** 用户尝试删除 SAP 中不存在的对象
- **THEN** 系统报告对象不存在的错误
@@ -0,0 +1,69 @@
## 1. Project Scaffolding & Entry Point
- [x] 1.1 Create main.py entry point with argparse subcommand pattern
- [x] 1.2 Set up UTF-8 encoding for stdout/stderr
- [x] 1.3 Set up logging to log/adt_tools.log
## 2. SAP ADT Connection
- [x] 2.1 Implement ADTClient with HTTP Basic Auth + CSRF Token
- [x] 2.2 Support stateful/stateless session modes
- [x] 2.3 Implement context manager (`with ADTClient(...) as client:`)
- [x] 2.4 Disable SSL verification warnings
## 3. Configuration Loading
- [x] 3.1 Implement config.ini parsing with ConfigParser
- [x] 3.2 Support environment variable override (SAP_HOST, SAP_CLIENT, SAP_USER, SAP_PASSWORD)
- [x] 3.3 Support config file search order (--config → current dir → script dir)
- [x] 3.4 Default client to "100" when not specified
## 4. Object Type Registry
- [x] 4.1 Define ObjectTypeConfig with URI templates, content types, has_source flag
- [x] 4.2 Register 10 ABAP object types (report, class, interface, function, functiongroup, domain, dataelement, table, structure, tabletype)
- [x] 4.3 Implement parse_object_name for URI expansion
- [x] 4.4 Handle function type special naming (GROUP/MODULE format)
- [x] 4.5 Handle tabletype uppercase naming
## 5. Download Command
- [x] 5.1 Implement object existence check (HEAD/GET)
- [x] 5.2 Implement source code download with LF normalization
- [x] 5.3 Auto-create output directory
- [x] 5.4 Print source code preview (first 20 lines)
## 6. Sync Command
- [x] 6.1 Implement full pipeline: lock → write → unlock → syntax check → activate
- [x] 6.2 Auto-create object when not exists
- [x] 6.3 Support --corr_nr for transport request binding
- [x] 6.4 Handle lock failure with transport request selection
- [x] 6.5 Report progress per step with ✓/✗ indicators
## 7. Create Command
- [x] 7.1 Implement default template generation per type
- [x] 7.2 Support --source for custom source code
- [x] 7.3 Support --definition for DDIC JSON definitions
- [x] 7.4 Support --corr_nr for transport request in creation
- [x] 7.5 Support --path for project manifest update
## 8. Info Command
- [x] 8.1 Query object metadata via ADT GET
- [x] 8.2 Parse ADT core XML for name, type, description, status, author
- [x] 8.3 Validate response name matches request name
- [x] 8.4 Display status as ✓ 已激活 or ⚠️ 未激活
## 9. Delete Command
- [x] 9.1 Check object existence before deletion
- [x] 9.2 Require user "yes" confirmation
- [x] 9.3 Execute lock → DELETE → unlock flow
- [x] 9.4 Support --path for manifest update
## 10. Error Handling
- [x] 10.1 Define unified exception hierarchy (SapCliError base + 11 subtypes)
- [x] 10.2 Exit with code 1 and user-friendly message on SapCliError
@@ -0,0 +1,4 @@
schema: spec-driven
change: p0-include-list-profile-keyring
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,29 @@
# Proposal: P0 — Include 支持 + 对象列表 + 多系统配置 + 密钥安全
## Why
Include 程序是 ABAP 大型报表拆分的常见手段,缺少支持会影响实际项目使用。对象列表浏览是开发者最基本的需求之一。多系统配置和安全密码存储是企业级使用的必要条件。
## What Changes
- Include 程序作为 report 子类型支持(复用现有 report 逻辑)
- 对象列表浏览(按类型、前缀筛选)
- 多系统 profile 配置(config.ini 多 section
- 密码通过系统 keyring 安全存储
## Capabilities
### New Capabilities
(无新领域,均为已有领域的增强)
### Modified Capabilities
- `connection`: 新增多 profile 切换能力
- `search-browse`: 新增对象列表浏览能力
- `config`: 新增配置显示、设置、密钥环存储能力
## Impact
- types.py 新增 include 类型注册
- config.py 增强 SapConfigManager 支持多 section
- 新增 auth.py 模块集成 keyring
- 新增 list 命令和对应 ADT 查询
@@ -0,0 +1,37 @@
## MODIFIED Requirements
### Requirement: Configuration Display
系统 SHALL 显示当前的 SAP 连接配置。
#### Scenario: Show current config
- **WHEN** 用户执行 config show 命令
- **THEN** 系统显示当前生效的配置项(主机、客户端、用户名),密码以掩码显示
### Requirement: Configuration Setting
系统 SHALL 支持通过命令行设置配置项。
#### Scenario: Set config value
- **WHEN** 用户执行 config set 命令并指定键和值
- **THEN** 系统将配置值保存到配置文件中
### Requirement: Multi-Profile Management
系统 SHALL 支持多 SAP 系统配置 profile。
#### Scenario: List profiles
- **WHEN** 用户执行 config list 命令
- **THEN** 系统显示所有已配置的 profile 列表
### Requirement: Secure Password Storage
系统 SHALL 支持通过系统密钥环安全存储 SAP 密码。
#### Scenario: Save password to keyring
- **WHEN** 用户配置密码存储选项
- **THEN** 密码保存到操作系统密钥环而非明文配置文件
#### Scenario: Load password from keyring
- **WHEN** 配置文件中未指定密码但密钥环中存在
- **THEN** 系统从密钥环读取密码
@@ -0,0 +1,17 @@
## MODIFIED Requirements
### Requirement: Profile selection
系统 SHALL 通过 --profile 参数支持选择 config.ini 中的不同 section 作为 SAP 连接配置。
#### Scenario: Use specific profile
- **WHEN** 用户通过 --profile DEV 指定配置 section
- **THEN** 系统从 config.ini 的 [DEV] section 读取连接参数
#### Scenario: Default profile
- **WHEN** 用户未指定 --profile
- **THEN** 系统使用默认的 [SAP] section
#### Scenario: Profile not found
- **WHEN** 用户指定的 profile 在 config.ini 中不存在
- **THEN** 系统报告配置 section 不存在的错误
@@ -0,0 +1,13 @@
## ADDED Requirements
### Requirement: Object Listing
系统 SHALL 列出 SAP 系统中指定类型的开发对象。
#### Scenario: List by type with prefix
- **WHEN** 用户执行 list 命令并指定对象类型和前缀筛选
- **THEN** 系统显示匹配的对象名称列表
#### Scenario: List without filter
- **WHEN** 用户执行 list 命令但未指定筛选条件
- **THEN** 系统显示该类型的所有可访问对象
@@ -0,0 +1,24 @@
## 1. Include Program Support
- [x] 1.1 Register include as sub-type in types.py
- [x] 1.2 Reuse report ADT endpoints for include operations
- [x] 1.3 Handle include-specific template in create command
## 2. Object Listing
- [x] 2.1 Implement list command with type parameter
- [x] 2.2 Support prefix/wildcard filtering via ADT search API
- [x] 2.3 Display results in tabular format
## 3. Multi-Profile Configuration
- [x] 3.1 Enhance config.py to support multiple INI sections
- [x] 3.2 Add --profile/-p global option
- [x] 3.3 Default to [SAP] section when no profile specified
## 4. Secure Password Storage
- [x] 4.1 Create auth.py module with keyring integration
- [x] 4.2 Support saving password to system keyring
- [x] 4.3 Support loading password from keyring as fallback
- [x] 4.4 Implement config show/set/list subcommands
@@ -0,0 +1,4 @@
schema: spec-driven
change: p1-cds-whereused-diff-transport-package
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,26 @@
# Proposal: P1 — CDS View + Where-Used + Diff + 传输管理 + 包操作
## Why
S/4HANA 现代化开发以 CDS View 为核心,支持 CDS 是战略必需。Where-Used 引用查询帮助开发者评估变更影响。代码差异对比防止误覆盖。传输请求和包管理是 SAP 运维的基础能力。
## What Changes
- CDS View 的下载和创建
- Where-Used 引用查询
- 本地 vs SAP 代码差异对比
- 传输请求高级管理(list/info/release/objects
- ABAP 包操作(create/info
## Capabilities
### Modified Capabilities
- `search-browse`: 新增 Where-Used 查询、代码差异对比、CDS View 操作、包操作
- `transport`: 新增传输请求列表、详情、释放、对象查看
## Impact
- client.py 新增 CDS/Where-Used/Transport/Package 相关 ADT API 方法
- 新增 search.py、diff_cmd.py、transport.py、package_cmd.py、cds.py 命令模块
- 新增 5 个子命令:whereused、search、diff、cds、package
- transport 命令新增 4 个子操作
@@ -0,0 +1,61 @@
## MODIFIED Requirements
### Requirement: Where-Used Query
系统 SHALL 查询指定对象在其他开发对象中的引用关系。
#### Scenario: Find references
- **WHEN** 用户执行 whereused 命令并指定对象名称和类型
- **THEN** 系统显示所有引用该对象的开发对象列表
#### Scenario: No references found
- **WHEN** 指定对象没有被任何其他对象引用
- **THEN** 系统显示无引用结果的信息
### Requirement: Source Code Search
系统 SHALL 在 SAP 系统中搜索源代码内容。
#### Scenario: Search by keyword
- **WHEN** 用户执行 search 命令并提供搜索关键词
- **THEN** 系统显示包含该关键词的对象名称、类型和匹配行
#### Scenario: Search no results
- **WHEN** 搜索关键词没有匹配结果
- **THEN** 系统显示无搜索结果的信息
### Requirement: Code Diff
系统 SHALL 对比本地源码与 SAP 系统中当前版本的差异。
#### Scenario: Diff with differences
- **WHEN** 用户执行 diff 命令,本地文件与 SAP 版本存在差异
- **THEN** 系统显示差异内容(新增、删除、修改的行)
#### Scenario: Diff identical
- **WHEN** 本地文件与 SAP 版本完全一致
- **THEN** 系统显示无差异的信息
### Requirement: CDS View Operations
系统 SHALL 支持 CDS View 的下载和创建操作。
#### Scenario: Download CDS view
- **WHEN** 用户执行 cds download 命令并指定 CDS View 名称
- **THEN** 系统下载 CDS View 定义并保存到本地
#### Scenario: Create CDS view
- **WHEN** 用户执行 cds create 命令并指定名称和描述
- **THEN** 系统在 SAP 中创建新的 CDS View
### Requirement: Package Operations
系统 SHALL 支持 ABAP 包的查询和创建操作。
#### Scenario: Query package info
- **WHEN** 用户执行 package info 命令并指定包名
- **THEN** 系统显示包的描述、包含的对象数量等信息
#### Scenario: Create package
- **WHEN** 用户执行 package create 命令并指定包名和描述
- **THEN** 系统在 SAP 中创建新的 ABAP 包
@@ -0,0 +1,33 @@
## MODIFIED Requirements
### Requirement: Transport Request Listing
系统 SHALL 列出 SAP 系统中的传输请求。
#### Scenario: List transport requests
- **WHEN** 用户执行 transport list 命令
- **THEN** 系统显示当前用户的传输请求列表(请求号、描述、状态)
### Requirement: Transport Request Info
系统 SHALL 查询指定传输请求的详细信息。
#### Scenario: Query transport info
- **WHEN** 用户执行 transport info 命令并指定传输请求号
- **THEN** 系统显示传输请求的所有者、状态、包含的对象数量等信息
### Requirement: Transport Request Release
系统 SHALL 释放传输请求。
#### Scenario: Release transport request
- **WHEN** 用户执行 transport release 命令并指定传输请求号
- **THEN** 系统释放该传输请求
### Requirement: Transport Objects Listing
系统 SHALL 列出传输请求中包含的对象。
#### Scenario: List objects in transport
- **WHEN** 用户执行 transport objects 命令并指定传输请求号
- **THEN** 系统显示该传输请求中包含的所有开发对象列表
@@ -0,0 +1,36 @@
## 1. CDS View Support
- [x] 1.1 Register CDS View type and ADT endpoints
- [x] 1.2 Implement cds download subcommand
- [x] 1.3 Implement cds create subcommand
- [x] 1.4 Handle DDL source format (non-ABAP)
## 2. Where-Used Query
- [x] 2.1 Implement whereused command with name and type parameters
- [x] 2.2 Parse ADT where-used XML response
- [x] 2.3 Display referencing objects with type and name
## 3. Source Code Search
- [x] 3.1 Implement search command with keyword query
- [x] 3.2 Parse ADT code search response
- [x] 3.3 Display matching objects with context lines
## 4. Code Diff
- [x] 4.1 Implement diff command comparing local file vs SAP version
- [x] 4.2 Download SAP version for comparison
- [x] 4.3 Compute and display unified diff output
## 5. Transport Management
- [x] 5.1 Implement transport list subcommand
- [x] 5.2 Implement transport info subcommand with --corr_nr
- [x] 5.3 Implement transport release subcommand with --corr_nr
- [x] 5.4 Implement transport objects subcommand with --corr_nr
## 6. Package Operations
- [x] 6.1 Implement package info subcommand
- [x] 6.2 Implement package create subcommand with --description
@@ -0,0 +1,4 @@
schema: spec-driven
change: p2-atc-format-analyze-scaffold
status: archived
archived_at: "2026-06-09"
@@ -0,0 +1,24 @@
# Proposal: P2 — ATC 检查 + 代码格式化 + 依赖分析 + 项目脚手架
## Why
代码质量保障和开发者效率是工具成熟的标志。ATC 检查提供专业级代码审查,Pretty Printer 统一代码风格,依赖分析自动化项目管理,脚手架加速项目初始化。
## What Changes
- ATC (ABAP Test Cockpit) 代码检查集成
- ABAP Pretty Printer 代码格式化
- 项目级依赖自动分析
- 预定义模板项目脚手架
## Capabilities
### Modified Capabilities
- `quality`: 新增 ATC 检查、代码格式化、依赖分析、项目脚手架
## Impact
- 新增 check、format、analyze、scaffold 四个命令
- client.py 新增 ATC check、Pretty Printer ADT API 方法
- 新增 quality.py、analyze.py、scaffold.py 命令模块
- analyze 和 scaffold 不需要 SAP 连接(本地操作)
@@ -0,0 +1,41 @@
## MODIFIED Requirements
### Requirement: ATC Code Check
系统 SHALL 对 SAP 开发对象执行 ABAP Test Cockpit (ATC) 代码检查。
#### Scenario: Check with findings
- **WHEN** 用户执行 check 命令并指定对象名称和类型
- **THEN** 系统显示 ATC 检查发现的问题列表(优先级、位置、描述)
#### Scenario: Check clean
- **WHEN** ATC 检查未发现任何问题
- **THEN** 系统显示检查通过的信息
### Requirement: Code Formatting
系统 SHALL 对 SAP 开发对象执行 ABAP Pretty Printer 格式化。
#### Scenario: Format source code
- **WHEN** 用户执行 format 命令并指定对象名称和类型
- **THEN** 系统对 SAP 中的源码执行格式化并报告结果
### Requirement: Dependency Analysis
系统 SHALL 自动分析项目中对象的依赖关系。
#### Scenario: Analyze project dependencies
- **WHEN** 用户执行 analyze 命令并指定项目路径
- **THEN** 系统扫描源码中的依赖引用并生成依赖报告
### Requirement: Project Scaffolding
系统 SHALL 根据预定义模板创建 ABAP 项目结构。
#### Scenario: Scaffold from template
- **WHEN** 用户执行 scaffold 命令并指定名称和模板类型
- **THEN** 系统基于模板生成包含源码文件的项目结构
#### Scenario: List available templates
- **WHEN** 用户执行 scaffold 命令但未指定模板
- **THEN** 系统显示可用的模板列表
@@ -0,0 +1,26 @@
## 1. ATC Code Check
- [x] 1.1 Implement check command with name and type parameters
- [x] 1.2 Integrate ADT ATC checkruns API
- [x] 1.3 Parse and display findings with priority, location, description
- [x] 1.4 Handle clean check result
## 2. Code Formatting
- [x] 2.1 Implement format command with ABAP Pretty Printer integration
- [x] 2.2 Integrate ADT Pretty Printer API
- [x] 2.3 Report formatting result
## 3. Dependency Analysis
- [x] 3.1 Implement analyze command for project-level scanning
- [x] 3.2 Parse TYPE REF TO, CALL METHOD, PERFORM statements
- [x] 3.3 Generate dependency report
- [x] 3.4 Work without SAP connection (local-only)
## 4. Project Scaffolding
- [x] 4.1 Implement scaffold command with template parameter
- [x] 4.2 Create predefined templates (alv-report, bapi-wrapper, interface-class, data-model)
- [x] 4.3 Display available templates when none specified
- [x] 4.4 Work without SAP connection (local-only)
@@ -0,0 +1,4 @@
schema: spec-driven
change: add-upload-syntax-check
status: archived
archived_at: "2026-06-13"
@@ -0,0 +1,19 @@
# Proposal: 新增 upload 和 syntax-check 独立命令
## Why
sync 命令耦合了五步操作,无法满足只上传不激活、只检查语法的场景。拆分为原子命令后,用户可按需组合操作。
## What Changes
- 新增 upload 命令(锁定→写入→解锁,不检查不激活)
- 新增 syntax-check 命令(检查远程对象语法,不上传不激活)
## Impact
- 新增 sapcli/commands/upload.py
- 新增 sapcli/commands/syntax_check.py
- parser.py 新增两个命令注册
- app.py 新增命令路由
- object-lifecycle spec 新增两个 Requirement
- sync 命令完全不变
@@ -0,0 +1,47 @@
## ADDED Requirements
### Requirement: Source Code Upload
系统 SHALL 上传本地源代码到 SAP 系统,执行锁定→写入→解锁流程,不执行语法检查和激活。
upload 不会自动创建对象——上传前对象必须已存在于 SAP 系统中。
#### Scenario: Upload success
- **WHEN** 用户执行 upload 命令,对象已存在于 SAP,本地文件有效
- **THEN** 系统执行锁定、写入源码、解锁,报告写入的字符数和行数,不执行语法检查和激活
#### Scenario: Upload non-existent object
- **WHEN** 用户上传一个 SAP 中不存在的对象
- **THEN** 系统报告对象不存在的错误(不自动创建,区别于 sync)
#### Scenario: Upload with transport request
- **WHEN** 用户通过 --corr_nr 指定传输请求号
- **THEN** 系统使用该传输请求号进行锁定和写入
#### Scenario: Upload type without source
- **WHEN** 用户尝试上传不支持源码的类型(如 functiongroup、tabletype、messageclass、searchhelp、lockobject
- **THEN** 系统报告该类型不支持上传操作
#### Scenario: Upload local file not found
- **WHEN** 用户指定的本地源码文件路径不存在
- **THEN** 系统报告文件不存在的错误
### Requirement: Syntax Check
系统 SHALL 对 SAP 远程对象的源代码执行语法检查,不上传代码、不激活。
syntax-check 检查 SAP 上现有对象的源码(通常是 active 状态),用于验证结构变更后的依赖影响。
#### Scenario: Syntax check passed
- **WHEN** 用户执行 syntax-check 命令,对象的源码无语法错误
- **THEN** 系统报告语法检查通过
#### Scenario: Syntax check failed
- **WHEN** 对象源码包含语法错误
- **THEN** 系统报告语法检查未通过,显示每个错误的行号和描述
#### Scenario: Syntax check non-existent object
- **WHEN** 用户对 SAP 中不存在的对象执行语法检查
- **THEN** 系统报告对象不存在的错误
#### Scenario: Syntax check type without source
- **WHEN** 用户对不支持源码的类型(如 functiongroup、tabletype)执行语法检查
- **THEN** 系统报告该类型不支持语法检查操作
@@ -0,0 +1,44 @@
## 1. OpenSpec 规范
- [x] 1.1 创建 openspec/changes/add-upload-syntax-check/ 变更目录
- [x] 1.2 编写 proposal.mdWhy / What Changes / Impact
- [x] 1.3 编写 specs/object-lifecycle/spec.mdADDED: Source Code Upload、Syntax Check
- [x] 1.4 编写 tasks.md 任务清单
## 2. TDD 测试(先写测试,必须 RED)
- [x] 2.1 TestUploadCommandtest_upload_success(断言 syntax_check/activate 未被调用)
- [x] 2.2 TestUploadCommandtest_upload_nonexistent_objectObjectNotFoundError
- [x] 2.3 TestUploadCommandtest_upload_type_without_sourceInvalidNameError
- [x] 2.4 TestUploadCommandtest_upload_with_corr_nr(通过 --corr_nr 指定)
- [x] 2.5 TestUploadCommandtest_upload_file_not_foundConfigError
- [x] 2.6 TestSyntaxCheckCommandtest_syntax_check_passed(输出含"通过"
- [x] 2.7 TestSyntaxCheckCommandtest_syntax_check_failed(输出含错误行号)
- [x] 2.8 TestSyntaxCheckCommandtest_syntax_check_nonexistentObjectNotFoundError
- [x] 2.9 TestSyntaxCheckCommandtest_syntax_check_type_without_sourceInvalidNameError
- [x] 2.10 运行测试确认全部 RED9 个测试 ModuleNotFoundError 失败)
## 3. 实现命令
- [x] 3.1 实现 sapcli/commands/upload.pycmd_upload,参照 activate.py 结构)
- [x] 3.2 实现 sapcli/commands/syntax_check.pycmd_syntax_check
## 4. Parser 注册 + App 路由
- [x] 4.1 parser.py 注册 upload_parser--name/--type/--path/--corr_nr
- [x] 4.2 parser.py 注册 syntax-check 的 sc_parser--name/--type
- [x] 4.3 commands/__init__.py 导出 cmd_upload / cmd_syntax_check
- [x] 4.4 app.py 导入并路由 upload / syntax-check
## 5. 验证(必须 GREEN
- [x] 5.1 运行 pytest tests/unit/ 全部通过(363 passed
- [x] 5.2 python main.py upload --help / syntax-check --help 正常
- [x] 5.3 python main.py --help 出现两个新命令
- [x] 5.4 python main.py sync --help 参数未变(回归验证通过)
- [x] 5.5 openspec validate add-upload-syntax-check → valid
## 6. 收尾
- [x] 6.1 tasks.md 所有 checkbox 标记为 [x]
- [x] 6.2 .openspec.yaml status 改为 completed
+25
View File
@@ -0,0 +1,25 @@
schema: spec-driven
context: |
Tech stack: Python 3.11+, requests, SAP ADT REST API
CLI framework: argparse (subcommand pattern)
Architecture: CLI → ADT REST API → SAP System
Testing: unittest
Code style: PEP 8, type hints, f-strings
SAP object types: report, class, interface, function, functiongroup, domain, dataelement, table, structure, tabletype
rules:
proposal:
- Focus on user-visible behavior changes, not implementation
- Identify affected capabilities by checking existing specs
specs:
- Use WHEN/THEN format for scenarios (not Gherkin code blocks)
- Describe observable behavior only, no ADT endpoints or class names
- Every requirement MUST have at least one scenario
- Use RFC 2119 keywords: SHALL/MUST for mandatory, SHOULD for recommended
design:
- Include ADT endpoint details and technical rationale
- Consider SAP transport management implications
tasks:
- Each task independently verifiable
- "Use checkbox format: - [ ] X.Y Description"
+234
View File
@@ -0,0 +1,234 @@
# Spec-to-Code 需求覆盖验证报告
> 生成时间: 2026-06-09
> 对照 `openspec/specs/` 下 7 个 spec 文件 vs `sapcli/` 源码
---
## 1. Connection (connection/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 1.1 | Successful login | ✅已实现 | `client.py:login()` 使用 HTTP Basic Auth`app.py:101-102` 打印"登录成功" |
| 1.2 | Login failure | ✅已实现 | `client.py:62` raise `LoginError``app.py:144-146` 捕获 `SapCliError` 以非零退出码退出 |
| 1.3 | Config not found | ✅已实现 | `config.py:25-29` `SAPConfig.__post_init__` 检查缺失字段抛 `ConfigError``app.py:91-95` 打印缺失提示和环境变量名称 |
| 1.4 | Load from config file | ✅已实现 | `config.py:32-49` 搜索并读取 `config.ini` |
| 1.5 | Environment variable override | ✅已实现 | `config.py:53-57` `os.environ.get("SAP_XXX", sap.get(...))` 环境变量优先 |
| 1.6 | Profile selection (--profile) | ❌未实现 | `parser.py:69` 定义了 `--profile` 参数,但 `config.py:51` 硬编码 `cfg["SAP"]`,未使用 `args.profile` |
| 1.7 | Client number default "100" | ✅已实现 | `config.py:55` `sap.get("client", "100")` |
| 1.8 | Custom config path (--config) | ✅已实现 | `parser.py:67` + `app.py:88` 传入 `args.config` |
| 1.9 | No command specified | ✅已实现 | `app.py:77-79` 检测 `not args.command` 打印帮助并以 exit(1) 退出 |
**小计: 8/9 ✅, 1 ❌**
---
## 2. Object Lifecycle (object-lifecycle/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 2.1 | Create with default template | ⚠️部分实现 | `crud.py:31-58` 仅有 report/class/function/interface 四种模板,其他 12 种类型无默认模板 |
| 2.2 | Create with custom source file | ✅已实现 | `crud.py:690-695` `--source` 参数读取文件 |
| 2.3 | Create DDIC with --definition | ✅已实现 | `crud.py:771-876` domain/dataelement/table/structure/tabletype 有 JSON→XML 转换 |
| 2.4 | Create message class | ❌未实现 | `types.py` 未注册 `messageclass` 对象类型,无法 create/download/info/delete |
| 2.5 | Create database view | ❌未实现 | `types.py` 未注册 `view` 对象类型 |
| 2.6 | Create search help | ❌未实现 | `types.py` 未注册 `searchhelp` 对象类型 |
| 2.7 | Create lock object | ❌未实现 | `types.py` 未注册 `lockobject` 对象类型 |
| 2.8 | Create already existing object | ✅已实现 | `crud.py:642-644` 检测 `object_exists` 后抛 `ObjectAlreadyExistsError` |
| 2.9 | Create with --corr_nr | ✅已实现 | `parser.py:110` + `crud.py:652-655` 传入传输请求号 |
| 2.10 | Download existing object | ✅已实现 | `crud.py:73-122` 完整实现,文件名小写+.abap |
| 2.11 | Download non-existent object | ✅已实现 | `crud.py:95-98` 检测不存在抛 `ObjectNotFoundError` |
| 2.12 | Download function type (group/module) | ✅已实现 | `types.py:152-167` 解析 `组名/模块名` 格式 |
| 2.13 | Download type without source | ✅已实现 | `crud.py:82-85` 检测 `src_uri is None` 报错 |
| 2.14 | Download view DDL source | ❌未实现 | `view` 类型未在 `types.py` 注册 |
| 2.15 | Full sync success (lock→write→unlock→check→activate) | ✅已实现 | `crud.py:226-317` 完整五步流程,每步报告进度 |
| 2.16 | Auto-create on sync | ✅已实现 | `crud.py:213-224` 检测不存在则自动创建空对象 |
| 2.17 | Syntax check failure | ✅已实现 | `crud.py:277-287` 报告行号和错误描述 |
| 2.18 | Activation failure | ✅已实现 | `crud.py:308-317` 报告激活错误详情 |
| 2.19 | Sync with --corr_nr | ✅已实现 | `crud.py:230-231` 贯穿整个流程 |
| 2.20 | Query existing object info | ✅已实现 | `crud.py:371-449` 显示名称/类型/描述/状态/负责人等元数据 |
| 2.21 | Query non-existent object | ✅已实现 | `crud.py:406-408` 404 检测 |
| 2.22 | Query message class info | ❌未实现 | `messageclass` 未注册 |
| 2.23 | Query view info | ❌未实现 | `view` 未注册 |
| 2.24 | Delete with confirmation | ✅已实现 | `crud.py:483-486` input("yes") 确认 |
| 2.25 | Delete cancelled | ✅已实现 | `crud.py:484-486` 非确认则取消 |
| 2.26 | Delete non-existent object | ✅已实现 | `crud.py:474-477` 检测不存在抛 `ObjectNotFoundError` |
| 2.27 | Delete message class | ❌未实现 | `messageclass` 未注册 |
| 2.28 | Delete lock object | ❌未实现 | `lockobject` 未注册 |
**小计: 16/28 ✅, 7 ❌, 1 ⚠️**
### 缺失对象类型汇总
以下 5 种对象类型在 spec 中列出但未在 `types.py` 中注册:
- **messageclass** — 无 ObjectTypeConfig、无 URI 模板、无 create/download/info/delete
- **view** — 无 ObjectTypeConfig、无 URI 模板
- **searchhelp** — 无 ObjectTypeConfig、无 URI 模板
- **lockobject** — 无 ObjectTypeConfig、无 URI 模板
- **include** — 无 ObjectTypeConfig(仅在 scanner.py 的 DIRECTORY_TYPE_MAP 中映射,但 parse_object_name 会报错)
- **cdsview** — 无 ObjectTypeConfigCDS 通过独立命令 `cds` 子系统处理,不走通用 CRUD 流程)
---
## 3. Batch Operations (batch-ops/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 3.1 | Init new project | ✅已实现 | `batch.py:19-96` 扫描→查询→生成 manifest.json |
| 3.2 | Manifest tracks objects | ✅已实现 | `manifest.py` 完整 CRUD + to_dict/from_dict 持久化 |
| 3.3 | Query pending objects | ✅已实现 | `manifest.py:139-146` `pending_objects()` 方法 |
| 3.4 | Scan standard directories | ✅已实现 | `scanner.py:13-29` 14 种目录映射 + `_scan_flat_directory` |
| 3.5 | Function directory structure | ✅已实现 | `scanner.py:91-121` 子目录=组名,文件名=模块名 |
| 3.6 | Skip hidden files | ✅已实现 | `scanner.py:77` `filename.startswith(".")` 跳过 |
| 3.7 | Sort by dependency | ✅已实现 | `sorter.py:40-109` Kahn 算法拓扑排序 + TYPE_PRIORITY |
| 3.8 | Detect cyclic dependency | ✅已实现 | `sorter.py:100-105``CyclicDependencyError` 并显示循环链 |
| 3.9 | Ignore external dependencies | ✅已实现 | `sorter.py:63-65` `dep not in names` 时忽略 |
| 3.10 | Sync all objects (--all) | ✅已实现 | `batch.py:164-328` 完整批量同步 |
| 3.11 | Dry run mode (--dry-run) | ✅已实现 | `batch.py:172,224-241` 仅显示计划不执行 |
| 3.12 | Fail fast mode (--fail-fast) | ✅已实现 | `batch.py:173,287-289` 失败立即 break |
| 3.13 | Refresh object status | ✅已实现 | `batch.py:99-161` 逐个查询 SAP 状态更新清单 |
**小计: 13/13 ✅**
---
## 4. Search and Browse (search-browse/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 4.1 | List by type with prefix | ⚠️部分实现 | `search.py:31-71` 命令层已实现,但调用 `client.list_objects()`**client.py 中缺少该方法定义** |
| 4.2 | List without filter | ⚠️部分实现 | 同上,命令层有,client 层缺失 |
| 4.3 | Find references (whereused) | ⚠️部分实现 | `search.py:74-109` 命令层已实现,但调用 `client.where_used()`**client.py 中缺少该方法定义** |
| 4.4 | No references found | ⚠️部分实现 | `search.py:97-98` 显示无引用信息,但依赖缺失的 client 方法 |
| 4.5 | Search by keyword | ⚠️部分实现 | `search.py:112-147` 命令层已实现,但调用 `client.search_code()`**client.py 中缺少该方法定义** |
| 4.6 | Search no results | ⚠️部分实现 | `search.py:136-137` 显示无结果信息,但依赖缺失的 client 方法 |
| 4.7 | Diff with differences | ⚠️部分实现 | `diff_cmd.py:16-90` 命令层完整,但调用 `client.read_source_for_diff()`**client.py 中缺少该方法定义** |
| 4.8 | Diff identical | ⚠️部分实现 | `diff_cmd.py:70-72` 检测无差异,但依赖缺失的 client 方法 |
| 4.9 | Download CDS view | ⚠️部分实现 | `cds.py:31-61` 命令层完整,但调用 `client.get_cds_source()`**client.py 中缺少该方法定义** |
| 4.10 | Create CDS view | ⚠️部分实现 | `cds.py:130-171` 命令层完整,但调用 `client.create_cds()`**client.py 中缺少该方法定义** |
| 4.11 | Query package info | ⚠️部分实现 | `package_cmd.py:56-77` 命令层完整,但调用 `client.get_package_info()`**client.py 中缺少该方法定义** |
| 4.12 | Create package | ⚠️部分实现 | `package_cmd.py:29-53` 命令层完整,但调用 `client.create_package()`**client.py 中缺少该方法定义** |
**小计: 0/12 ✅, 12 ⚠️ (命令层均已完成,但 ADTClient 缺少对应的 API 方法)**
### client.py 缺失的方法清单
以下方法被 commands/ 调用但未在 `client.py` 中定义:
1. `list_objects(obj_type, package, prefix)` — 被 search.py, package_cmd.py 调用
2. `where_used(name, obj_uri, adt_type)` — 被 search.py 调用
3. `search_code(query, obj_type)` — 被 search.py 调用
4. `read_source_for_diff(name, obj_type)` — 被 diff_cmd.py 调用
5. `get_cds_source(name)` — 被 cds.py 调用
6. `create_cds(name, description, ddl_source)` — 被 cds.py 调用
7. `create_package(name, description, superpackage)` — 被 package_cmd.py 调用
8. `get_package_info(name)` — 被 package_cmd.py 调用
---
## 5. Transport Management (transport/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 5.1 | List transport requests | ✅已实现 | `transport.py:32-56` + `client.py:249-280` `list_transport_requests()` |
| 5.2 | Query transport info | ⚠️部分实现 | `transport.py:59-79` 命令层已实现,但调用 `client.transport_info()`**client.py 中缺少该方法定义** |
| 5.3 | Release transport request | ⚠️部分实现 | `transport.py:82-107` 命令层已实现,但调用 `client.transport_release()`**client.py 中缺少该方法定义** |
| 5.4 | List objects in transport | ⚠️部分实现 | `transport.py:110-136` 命令层已实现,但调用 `client.transport_objects()`**client.py 中缺少该方法定义** |
**小计: 1/4 ✅, 3 ⚠️**
### client.py 缺失的方法(Transport
1. `transport_info(corr_nr)` — 传输请求详情查询
2. `transport_release(corr_nr)` — 释放传输请求
3. `transport_objects(corr_nr)` — 传输请求中的对象列表
---
## 6. Code Quality (quality/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 6.1 | Check with findings | ⚠️部分实现 | `quality.py:14-61` 命令层完整,但调用 `client.atc_check()`**client.py 中缺少该方法定义** |
| 6.2 | Check clean | ⚠️部分实现 | `quality.py:38-39` 显示通过信息,但依赖缺失的 client 方法 |
| 6.3 | Format source code | ⚠️部分实现 | `quality.py:64-132` 命令层完整,但调用 `client.pretty_print()`**client.py 中缺少该方法定义** |
| 6.4 | Analyze project dependencies | ✅已实现 | `analyze.py:39-126` 本地源码解析,正则匹配 TYPE REF TO / CALL FUNCTION 等模式 |
| 6.5 | Scaffold from template | ✅已实现 | `scaffold.py:198-239` 4 种模板(alv-report/bapi-wrapper/interface-class/data-model |
| 6.6 | List available templates | ❌未实现 | spec 要求不指定模板时列出可用模板,但 `parser.py:207` `--template``required=True`,无法不指定 |
**小计: 2/6 ✅, 3 ⚠️, 1 ❌**
### client.py 缺失的方法(Quality
1. `atc_check(name, obj_uri, variant)` — ATC 代码检查
2. `pretty_print(source)` — ABAP Pretty Printer
---
## 7. Configuration Management (config/spec.md)
| # | Scenario | 状态 | 说明 |
|---|----------|------|------|
| 7.1 | Show current config | ✅已实现 | `config_cmd.py:20-40` 显示主机/客户端/用户名,密码掩码显示 |
| 7.2 | Set config value | ❌未实现 | `parser.py:123-126` 未定义 `config set` 子命令,config_cmd.py 无 set 逻辑 |
| 7.3 | List profiles | ✅已实现 | `config_cmd.py:43-66` `list-profiles` 子命令 |
| 7.4 | Use specific profile | ❌未实现 | `--profile` 参数已定义但 `config.py` 硬编码使用 `[SAP]` section |
| 7.5 | Save password to keyring | ⚠️部分实现 | `auth.py``set_password()``cmd_auth_login()`,但 **auth 模块未集成到 app.py 命令路由**parser.py 也未注册 `auth` 子命令 |
| 7.6 | Load password from keyring | ⚠️部分实现 | `auth.py:resolve_password()` 存在,但 **未被 config.py 或 app.py 调用** |
**小计: 2/6 ✅, 2 ❌, 2 ⚠️**
---
## 汇总统计
| Spec 领域 | 总需求 | ✅已实现 | ❌未实现 | ⚠️部分实现 | 覆盖率 |
|-----------|--------|---------|---------|-----------|--------|
| Connection | 9 | 8 | 1 | 0 | 88.9% |
| Object Lifecycle | 28 | 16 | 7 | 1 | 57.1% |
| Batch Operations | 13 | 13 | 0 | 0 | 100% |
| Search & Browse | 12 | 0 | 0 | 12 | 0% (命令层100%API层0%) |
| Transport | 4 | 1 | 0 | 3 | 25% |
| Code Quality | 6 | 2 | 1 | 3 | 33.3% |
| Config Management | 6 | 2 | 2 | 2 | 33.3% |
| **总计** | **78** | **42** | **11** | **21** | **53.8%** |
---
## 关键缺失点总结
### A. client.py 缺失的 13 个 ADT API 方法
这些方法被 commands/ 层调用但未实现,是最关键的缺口:
| 方法 | 调用者 | 涉及 Spec |
|------|--------|-----------|
| `list_objects(obj_type, package, prefix)` | search.py, package_cmd.py | search-browse |
| `where_used(name, obj_uri, adt_type)` | search.py | search-browse |
| `search_code(query, obj_type)` | search.py | search-browse |
| `read_source_for_diff(name, obj_type)` | diff_cmd.py | search-browse |
| `get_cds_source(name)` | cds.py | search-browse |
| `create_cds(name, description, ddl_source)` | cds.py | search-browse |
| `create_package(name, description, superpackage)` | package_cmd.py | search-browse |
| `get_package_info(name)` | package_cmd.py | search-browse |
| `transport_info(corr_nr)` | transport.py | transport |
| `transport_release(corr_nr)` | transport.py | transport |
| `transport_objects(corr_nr)` | transport.py | transport |
| `atc_check(name, obj_uri, variant)` | quality.py | quality |
| `pretty_print(source)` | quality.py | quality |
### B. types.py 缺失的 5 个对象类型注册
| 类型 | Spec 要求 | 当前状态 |
|------|----------|---------|
| messageclass | create/download/info/delete | ❌ 未注册,无 URI |
| view | create/download/info | ❌ 未注册,无 URI |
| searchhelp | create | ❌ 未注册,无 URI |
| lockobject | create/delete | ❌ 未注册,无 URI |
| include | (扫描可用) | ❌ scanner.py 映射了目录但 types.py 未注册 |
### C. 配置/认证缺口
| 缺失项 | 详情 |
|--------|------|
| `--profile` 不可用 | parser.py 定义了参数但 config.py 忽略,始终读 [SAP] section |
| `config set` 子命令 | spec 要求通过命令行设置配置项,parser.py 未注册,无实现 |
| keyring 集成 | auth.py 模块完整但未被 app.py/config.py 引入调用链 |
| scaffold 无模板列表 | `--template` 为 required,无法不指定来列出模板 |
+83
View File
@@ -0,0 +1,83 @@
# Batch Operations Specification
## Purpose
定义 sap-cli 的项目级批量操作行为,包括项目初始化、清单管理、目录扫描、依赖排序和批量同步。
## Requirements
### Requirement: Project Initialization
系统 SHALL 初始化一个 ABAP 项目目录结构。
#### Scenario: Init new project
- **WHEN** 用户执行 init 命令并指定项目路径
- **THEN** 系统创建标准目录结构(reports/、classes/ 等约定目录)和空的 manifest.json
### Requirement: Manifest Management
系统 SHALL 管理项目清单文件,记录所有开发对象的状态。
#### Scenario: Manifest tracks objects
- **WHEN** 对象被创建、同步或删除后
- **THEN** 清单文件自动更新对象的状态、最后同步时间和同步结果
#### Scenario: Query pending objects
- **WHEN** 清单中存在未成功同步的对象
- **THEN** 系统能够识别并列出这些待处理对象
### Requirement: Directory Scanning
系统 SHALL 扫描本地项目目录,自动识别 ABAP 开发对象文件。
#### Scenario: Scan standard directories
- **WHEN** 项目目录包含约定命名的子目录(reports/、classes/、functions/ 等)及其中的 .abap 文件
- **THEN** 系统识别每个文件对应的对象名称、类型和路径
#### Scenario: Function directory structure
- **WHEN** 扫描 functions/ 目录
- **THEN** 子目录名解析为函数组名,文件名解析为函数模块名
#### Scenario: Skip hidden files
- **WHEN** 目录中存在以 . 开头的文件
- **THEN** 系统跳过这些隐藏文件
### Requirement: Dependency Sorting
系统 SHALL 根据对象间依赖关系确定正确的执行顺序。
#### Scenario: Sort by dependency
- **WHEN** 对象之间存在依赖关系
- **THEN** 被依赖的对象排在前面(如接口在类之前)
#### Scenario: Detect cyclic dependency
- **WHEN** 对象间存在循环依赖
- **THEN** 系统报告循环依赖错误并显示循环链
#### Scenario: Ignore external dependencies
- **WHEN** 对象依赖了不在当前项目中的外部对象
- **THEN** 系统忽略该外部依赖,不报错
### Requirement: Batch Sync
系统 SHALL 支持项目级批量同步操作。
#### Scenario: Sync all objects
- **WHEN** 用户执行 sync --all 命令
- **THEN** 系统扫描项目、按依赖排序、逐个同步所有对象
#### Scenario: Dry run mode
- **WHEN** 用户执行 sync --all --dry-run
- **THEN** 系统仅显示将要同步的对象列表,不实际执行
#### Scenario: Fail fast mode
- **WHEN** 用户执行 sync --all --fail-fast
- **THEN** 任一对象同步失败时立即停止,不继续后续对象
### Requirement: Status Refresh
系统 SHALL 刷新项目清单中所有对象在 SAP 系统中的状态。
#### Scenario: Refresh object status
- **WHEN** 用户执行 refresh 命令
- **THEN** 系统查询每个对象在 SAP 中的最新状态并更新清单
+47
View File
@@ -0,0 +1,47 @@
# Configuration Management Specification
## Purpose
定义 sap-cli 的配置管理功能行为,包括配置查看、设置和多 profile 管理。
## Requirements
### Requirement: Configuration Display
系统 SHALL 显示当前的 SAP 连接配置。
#### Scenario: Show current config
- **WHEN** 用户执行 config show 命令
- **THEN** 系统显示当前生效的配置项(主机、客户端、用户名),密码以掩码显示
### Requirement: Configuration Setting
系统 SHALL 支持通过命令行设置配置项。
#### Scenario: Set config value
- **WHEN** 用户执行 config set 命令并指定键和值
- **THEN** 系统将配置值保存到配置文件中
### Requirement: Multi-Profile Management
系统 SHALL 支持多 SAP 系统配置 profile。
#### Scenario: List profiles
- **WHEN** 用户执行 config list 命令
- **THEN** 系统显示所有已配置的 profile 列表
#### Scenario: Use specific profile
- **WHEN** 用户通过 --profile 参数指定 profile
- **THEN** 系统使用该 profile 的配置连接对应的 SAP 系统
### Requirement: Secure Password Storage
系统 SHALL 支持通过系统密钥环安全存储 SAP 密码。
#### Scenario: Save password to keyring
- **WHEN** 用户配置密码存储选项
- **THEN** 密码保存到操作系统密钥环而非明文配置文件
#### Scenario: Load password from keyring
- **WHEN** 配置文件中未指定密码但密钥环中存在
- **THEN** 系统从密钥环读取密码
+55
View File
@@ -0,0 +1,55 @@
# Connection Specification
## Purpose
定义 sap-cli 与 SAP 系统建立连接、完成身份认证和会话管理的行为。
## Requirements
### Requirement: User Authentication
系统 SHALL 通过 SAP ADT REST API 使用 HTTP Basic Auth 进行身份认证。
#### Scenario: Successful login
- **WHEN** 用户提供有效的 SAP 主机地址、客户端编号、用户名和密码
- **THEN** 系统打印 "登录成功" 并建立可用会话
#### Scenario: Login failure
- **WHEN** 用户提供了无效的 SAP 凭据
- **THEN** 系统打印错误信息并以非零退出码退出
#### Scenario: Config not found
- **WHEN** 用户未提供配置文件且未设置环境变量
- **THEN** 系统打印配置缺失提示,列出需要的环境变量名称,并以非零退出码退出
### Requirement: Configuration Loading
系统 SHALL 支持 config.ini 文件和环境变量两种配置方式,环境变量优先于配置文件。
#### Scenario: Load from config file
- **WHEN** 用户运行命令且当前目录或指定路径存在有效的 config.ini
- **THEN** 系统从配置文件读取 SAP 连接参数
#### Scenario: Environment variable override
- **WHEN** 同时存在配置文件和环境变量
- **THEN** 环境变量值覆盖配置文件中的对应项
#### Scenario: Profile selection
- **WHEN** 用户通过 --profile 参数指定配置 section
- **THEN** 系统从 config.ini 的对应 section 读取配置
#### Scenario: Client number default
- **WHEN** 配置中未指定 SAP 客户端编号
- **THEN** 系统使用默认值 "100"
### Requirement: Global Options
系统 SHALL 支持全局命令行选项。
#### Scenario: Custom config path
- **WHEN** 用户通过 --config 指定配置文件路径
- **THEN** 系统从指定路径加载配置
#### Scenario: No command specified
- **WHEN** 用户运行程序但未指定任何子命令
- **THEN** 系统打印帮助信息并以退出码 1 退出
+186
View File
@@ -0,0 +1,186 @@
# Object Lifecycle Specification
## Purpose
定义 sap-cli 对 SAP 开发对象的创建、读取(下载源码和信息查询)、更新(同步)、删除操作行为。
涵盖所有支持的对象类型:report、class、interface、function、functiongroup、domain、dataelement、table、structure、tabletype、messageclass、view、searchhelp、lockobject、cdsview、include。
## Requirements
### Requirement: Object Creation
系统 SHALL 在 SAP 系统中创建开发对象,支持 16 种对象类型。
#### Scenario: Create with default template
- **WHEN** 用户执行 create 命令,指定对象名称和类型,未提供自定义源码
- **THEN** 系统使用内置模板生成源码并在 SAP 中创建对象
#### Scenario: Create with custom source file
- **WHEN** 用户通过 --source 参数指定本地 .abap 文件
- **THEN** 系统读取文件内容作为源码并在 SAP 中创建对象
#### Scenario: Create DDIC object with definition
- **WHEN** 用户通过 --definition 参数指定 .json 文件创建 DDIC 对象(domain、dataelement、table、structure、tabletype
- **THEN** 系统将 JSON 定义转换为 SAP 所需格式并创建对象
#### Scenario: Create message class
- **WHEN** 用户执行 create 命令,指定类型为 messageclass,并提供名称和描述
- **THEN** 系统在 SAP 中创建消息类对象
#### Scenario: Create database view
- **WHEN** 用户执行 create 命令,指定类型为 view,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建数据库视图
#### Scenario: Create search help
- **WHEN** 用户执行 create 命令,指定类型为 searchhelp,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建搜索帮助
#### Scenario: Create lock object
- **WHEN** 用户执行 create 命令,指定类型为 lockobject,并提供 JSON 定义文件
- **THEN** 系统将 JSON 转换为 DDIC XML 并在 SAP 中创建锁对象
#### Scenario: Create already existing object
- **WHEN** SAP 系统中已存在同名同类型对象
- **THEN** 系统报告对象已存在的错误
#### Scenario: Create with transport request
- **WHEN** 用户通过 --corr_nr 指定传输请求号
- **THEN** 创建的对象绑定到指定的传输请求
### Requirement: Source Code Download
系统 SHALL 从 SAP 系统下载对象源代码并保存到本地文件。
#### Scenario: Download existing object
- **WHEN** 用户执行 download 命令,SAP 系统存在该对象
- **THEN** 系统下载源码并保存到指定目录,文件名为小写对象名+.abap
#### Scenario: Download non-existent object
- **WHEN** 用户执行 download 命令,SAP 系统不存在该对象
- **THEN** 系统报告对象不存在的错误
#### Scenario: Download function type
- **WHEN** 用户下载 function 类型对象,名称格式为 "组名/模块名"
- **THEN** 系统正确下载函数模块源码
#### Scenario: Download type without source
- **WHEN** 用户尝试下载不支持源码的类型(如 functiongroup、messageclass、lockobject
- **THEN** 系统报告该类型不支持下载操作
#### Scenario: Download database view source
- **WHEN** 用户下载 view 类型对象
- **THEN** 系统下载视图的 DDL 定义源码
### Requirement: Source Code Sync
系统 SHALL 将本地源代码同步到 SAP 系统,执行完整的锁定→写入→解锁→检查→激活流程。
#### Scenario: Full sync success
- **WHEN** 用户执行 sync 命令,本地文件和 SAP 对象均有效
- **THEN** 系统依次执行锁定、写入、解锁、语法检查、激活,每步报告进度
#### Scenario: Auto-create on sync
- **WHEN** 用户同步一个 SAP 中不存在的对象
- **THEN** 系统自动创建空对象后继续同步流程
#### Scenario: Syntax check failure
- **WHEN** 源码包含语法错误
- **THEN** 系统报告语法错误详情(行号和描述)
#### Scenario: Activation failure
- **WHEN** 语法检查通过但激活失败
- **THEN** 系统报告激活错误详情
#### Scenario: Sync with specified transport request
- **WHEN** 用户通过 --corr_nr 指定传输请求号
- **THEN** 系统在整个同步流程中使用该传输请求
### Requirement: Object Information Query
系统 SHALL 查询 SAP 系统中所有支持类型的开发对象元数据。
#### Scenario: Query existing object
- **WHEN** 用户执行 info 命令,SAP 系统存在该对象
- **THEN** 系统显示对象的名称、类型、描述、激活状态、负责人等元数据
#### Scenario: Query non-existent object
- **WHEN** 用户执行 info 命令,SAP 系统不存在该对象
- **THEN** 系统报告对象不存在的错误
#### Scenario: Query message class info
- **WHEN** 用户执行 info 命令查询消息类
- **THEN** 系统显示消息类的名称、描述、消息数量等元数据
#### Scenario: Query view info
- **WHEN** 用户执行 info 命令查询数据库视图
- **THEN** 系统显示视图的名称、描述、关联表等元数据
### Requirement: Object Deletion
系统 SHALL 从 SAP 系统中删除所有支持类型的开发对象。
#### Scenario: Delete with confirmation
- **WHEN** 用户执行 delete 命令并确认删除操作
- **THEN** 系统锁定、删除对象并报告成功
#### Scenario: Delete cancelled
- **WHEN** 用户执行 delete 命令但未确认删除
- **THEN** 系统取消操作,不执行删除
#### Scenario: Delete non-existent object
- **WHEN** 用户尝试删除 SAP 中不存在的对象
- **THEN** 系统报告对象不存在的错误
#### Scenario: Delete message class
- **WHEN** 用户执行 delete 命令删除消息类并确认
- **THEN** 系统删除该消息类
#### Scenario: Delete lock object
- **WHEN** 用户执行 delete 命令删除锁对象并确认
- **THEN** 系统删除该锁对象及其自动生成的函数模块
### Requirement: Source Code Upload
系统 SHALL 上传本地源代码到 SAP 系统,执行锁定→写入→解锁流程,不执行语法检查和激活。
upload 不会自动创建对象——上传前对象必须已存在于 SAP 系统中。
#### Scenario: Upload success
- **WHEN** 用户执行 upload 命令,对象已存在于 SAP,本地文件有效
- **THEN** 系统执行锁定、写入源码、解锁,报告写入的字符数和行数,不执行语法检查和激活
#### Scenario: Upload non-existent object
- **WHEN** 用户上传一个 SAP 中不存在的对象
- **THEN** 系统报告对象不存在的错误(不自动创建,区别于 sync)
#### Scenario: Upload with transport request
- **WHEN** 用户通过 --corr_nr 指定传输请求号
- **THEN** 系统使用该传输请求号进行锁定和写入
#### Scenario: Upload type without source
- **WHEN** 用户尝试上传不支持源码的类型(如 functiongroup、tabletype、messageclass、searchhelp、lockobject
- **THEN** 系统报告该类型不支持上传操作
#### Scenario: Upload local file not found
- **WHEN** 用户指定的本地源码文件路径不存在
- **THEN** 系统报告文件不存在的错误
### Requirement: Syntax Check
系统 SHALL 对 SAP 远程对象的源代码执行语法检查,不上传代码、不激活。
syntax-check 检查 SAP 上现有对象的源码(通常是 active 状态),用于验证结构变更后的依赖影响。
#### Scenario: Syntax check passed
- **WHEN** 用户执行 syntax-check 命令,对象的源码无语法错误
- **THEN** 系统报告语法检查通过
#### Scenario: Syntax check failed
- **WHEN** 对象源码包含语法错误
- **THEN** 系统报告语法检查未通过,显示每个错误的行号和描述
#### Scenario: Syntax check non-existent object
- **WHEN** 用户对 SAP 中不存在的对象执行语法检查
- **THEN** 系统报告对象不存在的错误
#### Scenario: Syntax check type without source
- **WHEN** 用户对不支持源码的类型(如 functiongroup、tabletype)执行语法检查
- **THEN** 系统报告该类型不支持语法检查操作
+47
View File
@@ -0,0 +1,47 @@
# Code Quality Specification
## Purpose
定义 sap-cli 的代码质量相关功能行为,包括 ATC 检查和代码格式化。
## Requirements
### Requirement: ATC Code Check
系统 SHALL 对 SAP 开发对象执行 ABAP Test Cockpit (ATC) 代码检查。
#### Scenario: Check with findings
- **WHEN** 用户执行 check 命令并指定对象名称和类型
- **THEN** 系统显示 ATC 检查发现的问题列表(优先级、位置、描述)
#### Scenario: Check clean
- **WHEN** ATC 检查未发现任何问题
- **THEN** 系统显示检查通过的信息
### Requirement: Code Formatting
系统 SHALL 对 SAP 开发对象执行 ABAP Pretty Printer 格式化。
#### Scenario: Format source code
- **WHEN** 用户执行 format 命令并指定对象名称和类型
- **THEN** 系统对 SAP 中的源码执行格式化并报告结果
### Requirement: Dependency Analysis
系统 SHALL 自动分析项目中对象的依赖关系。
#### Scenario: Analyze project dependencies
- **WHEN** 用户执行 analyze 命令并指定项目路径
- **THEN** 系统扫描源码中的依赖引用并生成依赖报告
### Requirement: Project Scaffolding
系统 SHALL 根据预定义模板创建 ABAP 项目结构。
#### Scenario: Scaffold from template
- **WHEN** 用户执行 scaffold 命令并指定名称和模板类型
- **THEN** 系统基于模板生成包含源码文件的项目结构
#### Scenario: List available templates
- **WHEN** 用户执行 scaffold 命令但未指定模板
- **THEN** 系统显示可用的模板列表
+79
View File
@@ -0,0 +1,79 @@
# Search and Browse Specification
## Purpose
定义 sap-cli 的搜索和浏览功能行为,包括对象列表、引用查询和源码搜索。
## Requirements
### Requirement: Object Listing
系统 SHALL 列出 SAP 系统中指定类型的开发对象。
#### Scenario: List by type with prefix
- **WHEN** 用户执行 list 命令并指定对象类型和前缀筛选
- **THEN** 系统显示匹配的对象名称列表
#### Scenario: List without filter
- **WHEN** 用户执行 list 命令但未指定筛选条件
- **THEN** 系统显示该类型的所有可访问对象
### Requirement: Where-Used Query
系统 SHALL 查询指定对象在其他开发对象中的引用关系。
#### Scenario: Find references
- **WHEN** 用户执行 whereused 命令并指定对象名称和类型
- **THEN** 系统显示所有引用该对象的开发对象列表
#### Scenario: No references found
- **WHEN** 指定对象没有被任何其他对象引用
- **THEN** 系统显示无引用结果的信息
### Requirement: Source Code Search
系统 SHALL 在 SAP 系统中搜索源代码内容。
#### Scenario: Search by keyword
- **WHEN** 用户执行 search 命令并提供搜索关键词
- **THEN** 系统显示包含该关键词的对象名称、类型和匹配行
#### Scenario: Search no results
- **WHEN** 搜索关键词没有匹配结果
- **THEN** 系统显示无搜索结果的信息
### Requirement: Code Diff
系统 SHALL 对比本地源码与 SAP 系统中当前版本的差异。
#### Scenario: Diff with differences
- **WHEN** 用户执行 diff 命令,本地文件与 SAP 版本存在差异
- **THEN** 系统显示差异内容(新增、删除、修改的行)
#### Scenario: Diff identical
- **WHEN** 本地文件与 SAP 版本完全一致
- **THEN** 系统显示无差异的信息
### Requirement: CDS View Operations
系统 SHALL 支持 CDS View 的下载和创建操作。
#### Scenario: Download CDS view
- **WHEN** 用户执行 cds download 命令并指定 CDS View 名称
- **THEN** 系统下载 CDS View 定义并保存到本地
#### Scenario: Create CDS view
- **WHEN** 用户执行 cds create 命令并指定名称和描述
- **THEN** 系统在 SAP 中创建新的 CDS View
### Requirement: Package Operations
系统 SHALL 支持 ABAP 包的查询和创建操作。
#### Scenario: Query package info
- **WHEN** 用户执行 package info 命令并指定包名
- **THEN** 系统显示包的描述、包含的对象数量等信息
#### Scenario: Create package
- **WHEN** 用户执行 package create 命令并指定包名和描述
- **THEN** 系统在 SAP 中创建新的 ABAP 包
+39
View File
@@ -0,0 +1,39 @@
# Transport Management Specification
## Purpose
定义 sap-cli 的 SAP 传输请求管理功能行为。
## Requirements
### Requirement: Transport Request Listing
系统 SHALL 列出 SAP 系统中的传输请求。
#### Scenario: List transport requests
- **WHEN** 用户执行 transport list 命令
- **THEN** 系统显示当前用户的传输请求列表(请求号、描述、状态)
### Requirement: Transport Request Info
系统 SHALL 查询指定传输请求的详细信息。
#### Scenario: Query transport info
- **WHEN** 用户执行 transport info 命令并指定传输请求号
- **THEN** 系统显示传输请求的所有者、状态、包含的对象数量等信息
### Requirement: Transport Request Release
系统 SHALL 释放传输请求。
#### Scenario: Release transport request
- **WHEN** 用户执行 transport release 命令并指定传输请求号
- **THEN** 系统释放该传输请求
### Requirement: Transport Objects Listing
系统 SHALL 列出传输请求中包含的对象。
#### Scenario: List objects in transport
- **WHEN** 用户执行 transport objects 命令并指定传输请求号
- **THEN** 系统显示该传输请求中包含的所有开发对象列表