v2.3.0: info 新增开发包/传输请求字段 (纯只读 E071)
- info 输出新增「开发包」(packageRef)、「传输请求」(纯只读查 E071) - 优雅降级: 无请求/查询失败/非独立传输对象, 不中断 info - bump 2.2.1 -> 2.3.0 - pack 从源码同步 (含 parser/transport 最新代码)
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from sapcli.client import ADTClient
|
||||
@@ -18,7 +19,7 @@ from sapcli.exceptions import (
|
||||
SapCliError,
|
||||
)
|
||||
from sapcli.manifest import Manifest, ManifestEntry
|
||||
from sapcli.types import get_type_config, parse_object_name
|
||||
from sapcli.types import get_r3tr_object_code, get_type_config, parse_object_name
|
||||
|
||||
DDIC_TYPES = {"domain", "dataelement", "table", "structure", "tabletype"}
|
||||
|
||||
@@ -401,6 +402,30 @@ def _update_manifest_after_sync(
|
||||
logger.warning("更新清单失败: %s", e)
|
||||
|
||||
|
||||
def _query_transport_request(
|
||||
client: ADTClient, obj_type: str, display_name: str
|
||||
) -> str:
|
||||
"""查对象当前所在(未释放)的传输请求号。纯只读查 E071;失败优雅降级。"""
|
||||
r3tr_code = get_r3tr_object_code(obj_type)
|
||||
if not r3tr_code:
|
||||
return "—(非独立传输对象)"
|
||||
obj_name_upper = display_name.upper().split("/")[-1]
|
||||
if not re.fullmatch(r"[A-Za-z0-9_/$]+", obj_name_upper):
|
||||
return "(对象名非法,跳过)"
|
||||
try:
|
||||
sql = (
|
||||
f"SELECT trkorr FROM e071 WHERE pgmid='R3TR' "
|
||||
f"AND object='{r3tr_code}' AND obj_name='{obj_name_upper}' "
|
||||
f"UP TO 10 ROWS"
|
||||
)
|
||||
result = client.query_table_data(sql, max_rows=10)
|
||||
trkorrs = sorted({row[0] for row in result.get("rows", []) if row and row[0]})
|
||||
return ", ".join(trkorrs) if trkorrs else "无"
|
||||
except Exception:
|
||||
logger.debug("查询 E071 传输请求失败", exc_info=True)
|
||||
return "(无法获取)"
|
||||
|
||||
|
||||
def cmd_info(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
"""查询对象元数据信息。"""
|
||||
obj_type: str = args.type
|
||||
@@ -469,6 +494,14 @@ def cmd_info(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
info_responsible = root.attrib.get(f"{{{ns['adtcore']}}}responsible", "")
|
||||
info_language = root.attrib.get(f"{{{ns['adtcore']}}}masterLanguage", "")
|
||||
|
||||
# 开发包:解析对象 XML 自带的 packageRef 子元素
|
||||
pkg_ref = root.find(f".//{{{ns['adtcore']}}}packageRef")
|
||||
info_package = (
|
||||
pkg_ref.attrib.get(f"{{{ns['adtcore']}}}name", "")
|
||||
if pkg_ref is not None
|
||||
else ""
|
||||
)
|
||||
|
||||
if info_version == "active":
|
||||
status_icon = "✓ 已激活"
|
||||
elif info_version == "inactive":
|
||||
@@ -476,6 +509,9 @@ def cmd_info(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
else:
|
||||
status_icon = f"❓ {info_version}"
|
||||
|
||||
# 传输请求号:纯只读查 E071(不在对象元数据 XML 中)
|
||||
corr_display = _query_transport_request(client, obj_type, parsed.display_name)
|
||||
|
||||
print(f" ✓ 查询成功\n")
|
||||
print(f" {'─' * 50}")
|
||||
print(f" 名称: {info_name}")
|
||||
@@ -484,6 +520,8 @@ def cmd_info(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
print(f" 状态: {status_icon}")
|
||||
print(f" 负责人: {info_responsible}")
|
||||
print(f" 语言: {info_language}")
|
||||
print(f" 开发包: {info_package or '(未指定)'}")
|
||||
print(f" 传输请求: {corr_display}")
|
||||
print(f" 创建者: {info_created_by}")
|
||||
print(f" 修改者: {info_changed_by}")
|
||||
print(f" 修改时间: {info_changed_at}")
|
||||
|
||||
@@ -21,12 +21,15 @@ def cmd_transport(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
_transport_release(args, client)
|
||||
elif action == "objects":
|
||||
_transport_objects(args, client)
|
||||
elif action == "create":
|
||||
_transport_create(args, client)
|
||||
else:
|
||||
print(" 用法: sap-cli transport [list|info|release|objects]")
|
||||
print(" 用法: sap-cli transport [list|info|release|objects|create]")
|
||||
print(" list — 列出可修改的传输请求")
|
||||
print(" info — 查看传输请求详情")
|
||||
print(" release — 释放传输请求")
|
||||
print(" objects — 列出传输请求中的对象")
|
||||
print(" create — 新建传输请求 (--description)")
|
||||
|
||||
|
||||
def _transport_list(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
@@ -107,6 +110,28 @@ def _transport_release(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
print(f" ✗ 释放失败,请检查传输请求状态")
|
||||
|
||||
|
||||
def _transport_create(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
"""新建传输请求。"""
|
||||
description: str = args.description
|
||||
|
||||
print("=" * 60)
|
||||
print(" SAP 新建传输请求")
|
||||
print("=" * 60)
|
||||
print(f" 描述: {description}")
|
||||
|
||||
print(f"\n → 正在创建...")
|
||||
try:
|
||||
new_nr = client.create_transport_request(description)
|
||||
except Exception as e:
|
||||
print(f" ✗ 创建失败: {e}")
|
||||
return
|
||||
|
||||
if new_nr:
|
||||
print(f"\n ✓ 传输请求已创建: {new_nr}")
|
||||
else:
|
||||
print(f"\n ✗ 创建失败(未返回编号),请检查系统或描述合法性")
|
||||
|
||||
|
||||
def _transport_objects(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
"""列出传输请求中的对象。"""
|
||||
corr_nr: str = args.corr_nr
|
||||
|
||||
Reference in New Issue
Block a user