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