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:
@@ -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)
|
||||
+61
@@ -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 查询
|
||||
+37
@@ -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** 系统从密钥环读取密码
|
||||
+17
@@ -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 不存在的错误
|
||||
+13
@@ -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
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
schema: spec-driven
|
||||
change: p1-cds-whereused-diff-transport-package
|
||||
status: archived
|
||||
archived_at: "2026-06-09"
|
||||
+26
@@ -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 个子操作
|
||||
+61
@@ -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 包
|
||||
+33
@@ -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 连接(本地操作)
|
||||
+41
@@ -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 命令完全不变
|
||||
+47
@@ -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.md(Why / What Changes / Impact)
|
||||
- [x] 1.3 编写 specs/object-lifecycle/spec.md(ADDED: Source Code Upload、Syntax Check)
|
||||
- [x] 1.4 编写 tasks.md 任务清单
|
||||
|
||||
## 2. TDD 测试(先写测试,必须 RED)
|
||||
|
||||
- [x] 2.1 TestUploadCommand:test_upload_success(断言 syntax_check/activate 未被调用)
|
||||
- [x] 2.2 TestUploadCommand:test_upload_nonexistent_object(ObjectNotFoundError)
|
||||
- [x] 2.3 TestUploadCommand:test_upload_type_without_source(InvalidNameError)
|
||||
- [x] 2.4 TestUploadCommand:test_upload_with_corr_nr(通过 --corr_nr 指定)
|
||||
- [x] 2.5 TestUploadCommand:test_upload_file_not_found(ConfigError)
|
||||
- [x] 2.6 TestSyntaxCheckCommand:test_syntax_check_passed(输出含"通过")
|
||||
- [x] 2.7 TestSyntaxCheckCommand:test_syntax_check_failed(输出含错误行号)
|
||||
- [x] 2.8 TestSyntaxCheckCommand:test_syntax_check_nonexistent(ObjectNotFoundError)
|
||||
- [x] 2.9 TestSyntaxCheckCommand:test_syntax_check_type_without_source(InvalidNameError)
|
||||
- [x] 2.10 运行测试确认全部 RED(9 个测试 ModuleNotFoundError 失败)
|
||||
|
||||
## 3. 实现命令
|
||||
|
||||
- [x] 3.1 实现 sapcli/commands/upload.py(cmd_upload,参照 activate.py 结构)
|
||||
- [x] 3.2 实现 sapcli/commands/syntax_check.py(cmd_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
|
||||
@@ -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"
|
||||
@@ -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** — 无 ObjectTypeConfig(CDS 通过独立命令 `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,无法不指定来列出模板 |
|
||||
@@ -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 中的最新状态并更新清单
|
||||
@@ -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** 系统从密钥环读取密码
|
||||
@@ -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 退出
|
||||
@@ -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** 系统报告该类型不支持语法检查操作
|
||||
@@ -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** 系统显示可用的模板列表
|
||||
@@ -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 包
|
||||
@@ -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** 系统显示该传输请求中包含的所有开发对象列表
|
||||
Reference in New Issue
Block a user