feat: sap-cli skill v2.1.0 — self-contained distributable package

- assets/: sap-cli source (v2.1.0, 26 commands, 16 object types)
- references/: tool constraints + error handling (self-contained)
- scripts/setup.py: one-click install/config/verify
- SKILL.md: full command reference + dual-platform install guide
- VERSION: 2.1.0

Built from D:/Codespace/sap-cli via scripts/pack_skill.py
This commit is contained in:
2026-06-13 20:52:24 +08:00
commit 1e39b6da88
49 changed files with 7172 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
"""搜索与浏览命令:list / whereused / search。"""
from __future__ import annotations
import argparse
import logging
from sapcli.client import ADTClient
from sapcli.types import get_type_config, parse_object_name
logger = logging.getLogger("sapcli.commands.search")
# 对象类型关键字 → ADT 类型代码映射
_TYPE_FILTER_MAP: dict[str, str] = {
"report": "PROG/P",
"class": "CLAS/OC",
"interface": "INTF/OI",
"function": "FUNC/F",
"functiongroup": "FUGR/F",
"domain": "DOMA/DD",
"dataelement": "DTEL/DE",
"table": "TABL/TT",
"structure": "TABL/ST",
"tabletype": "TTYP",
"include": "PROG/I",
"cdsview": "DDLS/DF",
"messageclass": "MSAG",
"view": "VIEW",
}
def cmd_list(args: argparse.Namespace, client: ADTClient) -> None:
"""列出 SAP 对象。"""
obj_type = getattr(args, "type", None)
package = getattr(args, "package", None)
prefix = getattr(args, "prefix", None)
# 将友好类型名转换为 ADT 类型代码
adt_type = None
if obj_type:
adt_type = _TYPE_FILTER_MAP.get(obj_type, obj_type)
print("=" * 60)
print(" SAP ADT 对象列表")
print("=" * 60)
if obj_type:
print(f" 类型过滤: {obj_type}")
if package:
print(f" 包过滤: {package}")
if prefix:
print(f" 名称前缀: {prefix}")
print(f"\n → 正在搜索对象...")
try:
results = client.list_objects(obj_type=adt_type, package=package, prefix=prefix)
except Exception as e:
print(f" ✗ 搜索失败: {e}")
return
if not results:
print(" 未找到匹配的对象")
return
print(f" ✓ 找到 {len(results)} 个对象\n")
print(f" {'名称':<30s} {'类型':<12s} {'':<15s} {'描述':<30s}")
print(f" {'' * 30} {'' * 12} {'' * 15} {'' * 30}")
for obj in results:
name = obj.get("name", "")[:30]
otype = obj.get("type", "")[:12]
pkg = obj.get("package", "")[:15]
desc = obj.get("description", "")[:30]
print(f" {name:<30s} {otype:<12s} {pkg:<15s} {desc:<30s}")
def cmd_whereused(args: argparse.Namespace, client: ADTClient) -> None:
"""Where-Used 引用查询。"""
name: str = args.name
obj_type: str | None = getattr(args, "type", None)
parsed = parse_object_name(name, obj_type or "report")
type_label = get_type_config(obj_type or "report").label
print("=" * 60)
print(" SAP ADT Where-Used 查询")
print("=" * 60)
print(f" 对象名称: {parsed.display_name}")
if obj_type:
print(f" 对象类型: {type_label}")
print(f"\n → 正在查询引用关系...")
adt_type = _TYPE_FILTER_MAP.get(obj_type, obj_type) if obj_type else None
try:
results = client.where_used(name, parsed.obj_uri, adt_type)
except Exception as e:
print(f" ✗ 查询失败: {e}")
return
if not results:
print(" 未找到引用关系")
return
print(f" ✓ 找到 {len(results)} 个引用\n")
print(f" {'名称':<30s} {'类型':<12s} {'':<15s} {'URI':<40s}")
print(f" {'' * 30} {'' * 12} {'' * 15} {'' * 40}")
for ref in results:
ref_name = ref.get("name", "")[:30]
ref_type = ref.get("type", "")[:12]
ref_pkg = ref.get("package", "")[:15]
ref_uri = ref.get("uri", "")[:40]
print(f" {ref_name:<30s} {ref_type:<12s} {ref_pkg:<15s} {ref_uri:<40s}")
def cmd_search(args: argparse.Namespace, client: ADTClient) -> None:
"""源代码搜索。"""
query: str = args.query
obj_type: str | None = getattr(args, "type", None)
# 将友好类型名转换为 ADT 类型代码
adt_type = None
if obj_type:
adt_type = _TYPE_FILTER_MAP.get(obj_type, obj_type)
print("=" * 60)
print(" SAP ADT 源代码搜索")
print("=" * 60)
print(f" 搜索关键词: {query}")
if obj_type:
print(f" 类型过滤: {obj_type}")
print(f"\n → 正在搜索...")
try:
results = client.search_code(query, obj_type=adt_type)
except Exception as e:
print(f" ✗ 搜索失败: {e}")
return
if not results:
print(" 未找到匹配的代码")
return
print(f" ✓ 找到 {len(results)} 个结果\n")
print(f" {'名称':<30s} {'类型':<12s} {'描述':<40s}")
print(f" {'' * 30} {'' * 12} {'' * 40}")
for obj in results:
obj_name = obj.get("name", "")[:30]
obj_type_val = obj.get("type", "")[:12]
desc = obj.get("description", "")[:40]
print(f" {obj_name:<30s} {obj_type_val:<12s} {desc:<40s}")