- 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
152 lines
4.7 KiB
Python
152 lines
4.7 KiB
Python
"""搜索与浏览命令: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}")
|