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:
@@ -0,0 +1,89 @@
|
||||
"""代码差异对比命令:diff。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import difflib
|
||||
import logging
|
||||
import os
|
||||
|
||||
from sapcli.client import ADTClient
|
||||
from sapcli.types import get_type_config, parse_object_name
|
||||
|
||||
logger = logging.getLogger("sapcli.commands.diff_cmd")
|
||||
|
||||
|
||||
def cmd_diff(args: argparse.Namespace, client: ADTClient) -> None:
|
||||
"""本地 vs SAP 代码差异对比。"""
|
||||
name: str = args.name
|
||||
obj_type: str = args.type
|
||||
local_path: str | None = getattr(args, "path", None)
|
||||
|
||||
parsed = parse_object_name(name, obj_type)
|
||||
type_label = get_type_config(obj_type).label
|
||||
|
||||
if parsed.src_uri is None:
|
||||
print(f"\n ✗ {type_label}没有源代码,不支持 diff 操作")
|
||||
return
|
||||
|
||||
print("=" * 60)
|
||||
print(" SAP ADT 代码差异对比")
|
||||
print("=" * 60)
|
||||
print(f" 对象名称: {parsed.display_name}")
|
||||
print(f" 对象类型: {type_label}")
|
||||
|
||||
# 读取本地文件
|
||||
if local_path is None:
|
||||
# 尝试自动推断文件路径
|
||||
local_path = f"{parsed.file_base}.abap"
|
||||
if not os.path.isfile(local_path):
|
||||
print(f"\n ✗ 本地文件不存在: {local_path}")
|
||||
return
|
||||
|
||||
with open(local_path, "r", encoding="utf-8") as f:
|
||||
local_source = f.read()
|
||||
|
||||
local_lines = local_source.splitlines(keepends=True)
|
||||
print(f" 本地文件: {local_path} ({len(local_lines)} 行)")
|
||||
|
||||
# 读取 SAP 端源码
|
||||
print(f"\n → 正在读取 SAP 端源码...")
|
||||
try:
|
||||
sap_source = client.read_source_for_diff(name, obj_type)
|
||||
except Exception as e:
|
||||
print(f" ✗ 读取 SAP 源码失败: {e}")
|
||||
return
|
||||
|
||||
sap_source = sap_source.replace("\r\n", "\n").replace("\r", "\n")
|
||||
sap_lines = sap_source.splitlines(keepends=True)
|
||||
print(f" ✓ SAP 源码读取成功 ({len(sap_lines)} 行)")
|
||||
|
||||
# 生成 unified diff
|
||||
diff_lines = list(difflib.unified_diff(
|
||||
sap_lines,
|
||||
local_lines,
|
||||
fromfile=f"SAP:{parsed.display_name}",
|
||||
tofile=f"本地:{os.path.basename(local_path)}",
|
||||
lineterm="",
|
||||
))
|
||||
|
||||
if not diff_lines:
|
||||
print(f"\n ✓ 本地文件与 SAP 端完全一致,无差异")
|
||||
return
|
||||
|
||||
print(f"\n {'─' * 60}")
|
||||
print(f" 差异摘要:")
|
||||
added = sum(1 for l in diff_lines if l.startswith("+") and not l.startswith("+++"))
|
||||
removed = sum(1 for l in diff_lines if l.startswith("-") and not l.startswith("---"))
|
||||
print(f" 新增行: {added} | 删除行: {removed}")
|
||||
print(f" {'─' * 60}\n")
|
||||
|
||||
# 输出 diff
|
||||
for line in diff_lines:
|
||||
if line.startswith("+") and not line.startswith("+++"):
|
||||
print(f" \033[32m{line}\033[0m")
|
||||
elif line.startswith("-") and not line.startswith("---"):
|
||||
print(f" \033[31m{line}\033[0m")
|
||||
elif line.startswith("@@"):
|
||||
print(f" \033[36m{line}\033[0m")
|
||||
else:
|
||||
print(f" {line}")
|
||||
Reference in New Issue
Block a user