Files
sap-cli-skill/assets/sapcli/commands/search.py
T
wurangyu 38e99638c5 chore: sync skill to v2.2.1
- NW 7.40 E2E-verified compatibility matrix in SKILL.md
- DDIC fixes: include namespace, tabletype exists check, DDIC delete lock Accept
- New commands: clone, enhancement, history, unit-test
- 665 tests, 96% coverage
2026-07-10 19:13:46 +08:00

152 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""搜索与浏览命令: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",
"searchhelp": "SHLP",
"lockobject": "LOCK",
"dcl": "DCLS",
"ddlX": "DDLX",
}
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}")