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
+243
View File
@@ -0,0 +1,243 @@
from __future__ import annotations
from dataclasses import dataclass
from sapcli.exceptions import InvalidNameError
@dataclass(frozen=True)
class ObjectTypeConfig:
key: str
label: str
obj_uri_template: str
src_uri_template: str | None
collection_uri: str
create_content_type: str
has_source: bool = True
def format_obj_uri(self, name: str, **kwargs: str) -> str:
return self.obj_uri_template.format(name=name, **kwargs)
def format_src_uri(self, name: str, **kwargs: str) -> str | None:
if self.src_uri_template is None:
return None
return self.src_uri_template.format(name=name, **kwargs)
def format_collection_uri(self, **kwargs: str) -> str:
return self.collection_uri.format(**kwargs)
_OBJECT_TYPE_REGISTRY: dict[str, ObjectTypeConfig] = {}
def _register(cfg: ObjectTypeConfig) -> ObjectTypeConfig:
_OBJECT_TYPE_REGISTRY[cfg.key] = cfg
return cfg
REPORT = _register(ObjectTypeConfig(
key="report",
label="程序(REPORT)",
obj_uri_template="/sap/bc/adt/programs/programs/{name}",
src_uri_template="/sap/bc/adt/programs/programs/{name}/source/main",
collection_uri="/sap/bc/adt/programs/programs",
create_content_type="application/vnd.sap.adt.programs.programs.v2+xml",
))
CLASS = _register(ObjectTypeConfig(
key="class",
label="类(CLASS)",
obj_uri_template="/sap/bc/adt/oo/classes/{name}",
src_uri_template="/sap/bc/adt/oo/classes/{name}/source/main",
collection_uri="/sap/bc/adt/oo/classes",
create_content_type="application/vnd.sap.adt.oo.classes.v1+xml",
))
FUNCTION = _register(ObjectTypeConfig(
key="function",
label="函数模块(FUNCTION)",
obj_uri_template="/sap/bc/adt/functions/groups/{group}/fmodules/{name}",
src_uri_template="/sap/bc/adt/functions/groups/{group}/fmodules/{name}/source/main",
collection_uri="/sap/bc/adt/functions/groups/{group}/fmodules",
create_content_type="application/vnd.sap.adt.functions.fmodules.v1+xml",
))
FUNCTIONGROUP = _register(ObjectTypeConfig(
key="functiongroup",
label="函数组(FUNCTION GROUP)",
obj_uri_template="/sap/bc/adt/functions/groups/{name}",
src_uri_template=None,
collection_uri="/sap/bc/adt/functions/groups",
create_content_type="application/vnd.sap.adt.functions.groups.v2+xml",
has_source=False,
))
INTERFACE = _register(ObjectTypeConfig(
key="interface",
label="接口(INTERFACE)",
obj_uri_template="/sap/bc/adt/oo/interfaces/{name}",
src_uri_template="/sap/bc/adt/oo/interfaces/{name}/source/main",
collection_uri="/sap/bc/adt/oo/interfaces",
create_content_type="application/vnd.sap.adt.oo.interfaces.v1+xml",
))
DOMAIN = _register(ObjectTypeConfig(
key="domain",
label="域(DOMAIN)",
obj_uri_template="/sap/bc/adt/ddic/domains/{name}",
src_uri_template="/sap/bc/adt/ddic/domains/{name}/source/main",
collection_uri="/sap/bc/adt/ddic/domains",
create_content_type="application/vnd.sap.adt.domains.v2+xml",
))
DATAELEMENT = _register(ObjectTypeConfig(
key="dataelement",
label="数据元素(DATA ELEMENT)",
obj_uri_template="/sap/bc/adt/ddic/dataelements/{name}",
src_uri_template="/sap/bc/adt/ddic/dataelements/{name}/source/main",
collection_uri="/sap/bc/adt/ddic/dataelements",
create_content_type="application/vnd.sap.adt.dataelements.v2+xml",
))
TABLE = _register(ObjectTypeConfig(
key="table",
label="透明表(TABLE)",
obj_uri_template="/sap/bc/adt/ddic/tables/{name}",
src_uri_template="/sap/bc/adt/ddic/tables/{name}/source/main",
collection_uri="/sap/bc/adt/ddic/tables",
create_content_type="application/vnd.sap.adt.ddic.tables.v1+xml",
))
STRUCTURE = _register(ObjectTypeConfig(
key="structure",
label="结构(STRUCTURE)",
obj_uri_template="/sap/bc/adt/ddic/structures/{name}",
src_uri_template="/sap/bc/adt/ddic/structures/{name}/source/main",
collection_uri="/sap/bc/adt/ddic/structures",
create_content_type="application/vnd.sap.adt.ddic.structures.v1+xml",
))
TABLETYPE = _register(ObjectTypeConfig(
key="tabletype",
label="表类型(TABLE TYPE)",
obj_uri_template="/sap/bc/adt/vit/wb/object_type/ttypda/object_name/{name}",
src_uri_template=None,
collection_uri="/sap/bc/adt/ddic/tabletypes",
create_content_type="application/vnd.sap.adt.ddic.tabletypes.v1+xml",
has_source=False,
))
INCLUDE = _register(ObjectTypeConfig(
key="include",
label="Include程序(INCLUDE)",
obj_uri_template="/sap/bc/adt/programs/includes/{name}",
src_uri_template="/sap/bc/adt/programs/includes/{name}/source/main",
collection_uri="/sap/bc/adt/programs/includes",
create_content_type="application/vnd.sap.adt.programs.includes.v2+xml",
))
CDSVIEW = _register(ObjectTypeConfig(
key="cdsview",
label="CDS视图(CDS VIEW)",
obj_uri_template="/sap/bc/adt/dds/ddl/sources/{name}",
src_uri_template="/sap/bc/adt/dds/ddl/sources/{name}/content",
collection_uri="/sap/bc/adt/dds/ddl/sources",
create_content_type="text/plain",
))
MESSAGECLASS = _register(ObjectTypeConfig(
key="messageclass",
label="消息类(MESSAGE CLASS)",
obj_uri_template="/sap/bc/adt/oo/t100/messages/classes/{name}",
src_uri_template=None,
collection_uri="/sap/bc/adt/oo/t100/messages/classes",
create_content_type="application/vnd.sap.adt.t100.message.classes.v1+xml",
has_source=False,
))
VIEW = _register(ObjectTypeConfig(
key="view",
label="数据库视图(VIEW)",
obj_uri_template="/sap/bc/adt/ddic/views/{name}",
src_uri_template="/sap/bc/adt/ddic/views/{name}/source/main",
collection_uri="/sap/bc/adt/ddic/views",
create_content_type="application/vnd.sap.adt.ddic.views.v1+xml",
))
SEARCHHELP = _register(ObjectTypeConfig(
key="searchhelp",
label="搜索帮助(SEARCH HELP)",
obj_uri_template="/sap/bc/adt/ddic/searchhelps/{name}",
src_uri_template=None,
collection_uri="/sap/bc/adt/ddic/searchhelps",
create_content_type="application/vnd.sap.adt.ddic.searchhelps.v1+xml",
has_source=False,
))
LOCKOBJECT = _register(ObjectTypeConfig(
key="lockobject",
label="锁对象(LOCK OBJECT)",
obj_uri_template="/sap/bc/adt/ddic/lockobjects/{name}",
src_uri_template=None,
collection_uri="/sap/bc/adt/ddic/lockobjects",
create_content_type="application/vnd.sap.adt.ddic.lockobjects.v1+xml",
has_source=False,
))
def get_type_config(key: str) -> ObjectTypeConfig:
if key not in _OBJECT_TYPE_REGISTRY:
raise ValueError(f"不支持的对象类型: {key}")
return _OBJECT_TYPE_REGISTRY[key]
def all_type_keys() -> list[str]:
return list(_OBJECT_TYPE_REGISTRY.keys())
@dataclass(frozen=True)
class ParsedName:
obj_uri: str
src_uri: str | None
display_name: str
file_base: str
def parse_object_name(name: str, obj_type: str) -> ParsedName:
cfg = get_type_config(obj_type)
if obj_type == "function":
if "/" not in name:
raise InvalidNameError(
"function 类型需要'函数组名/函数模块名' 格式,例如: ZGROUP/Z_MY_FUNC"
)
group, fm = name.split("/", 1)
group = group.strip()
fm = fm.strip()
if not group or not fm:
raise InvalidNameError("函数组名和函数模块名不能为空")
return ParsedName(
obj_uri=cfg.format_obj_uri(fm.lower(), group=group.lower()),
src_uri=cfg.format_src_uri(fm.lower(), group=group.lower()),
display_name=name,
file_base=fm.lower(),
)
# VIT 端点需要大写名称以返回完整元数据;去掉前导 /
if obj_type == "tabletype":
clean = name.lstrip("/")
name_upper = clean.upper()
return ParsedName(
obj_uri=cfg.format_obj_uri(name_upper),
src_uri=cfg.format_src_uri(name_upper),
display_name=clean,
file_base=clean.lower(),
)
name_lower = name.lower()
return ParsedName(
obj_uri=cfg.format_obj_uri(name_lower),
src_uri=cfg.format_src_uri(name_lower),
display_name=name,
file_base=name_lower,
)