"""代码质量命令:check (ATC) / format (Pretty Printer)。""" 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.quality") def cmd_check(args: argparse.Namespace, client: ADTClient) -> None: """ATC 代码检查。""" name: str = args.name obj_type: str = args.type variant: str | None = getattr(args, "variant", None) parsed = parse_object_name(name, obj_type) type_label = get_type_config(obj_type).label print("=" * 60) print(" SAP ATC 代码检查") print("=" * 60) print(f" 对象名称: {parsed.display_name}") print(f" 对象类型: {type_label}") if variant: print(f" 检查变体: {variant}") print(f"\n → 正在执行 ATC 检查...") try: success, findings = client.atc_check(name, parsed.obj_uri, variant) except Exception as e: print(f" ✗ ATC 检查失败: {e}") return if success and not findings: print(" ✓ ATC 检查通过,无发现项") return errors = [f for f in findings if f["type"] in ("E", "1")] warnings = [f for f in findings if f["type"] in ("W", "2")] infos = [f for f in findings if f["type"] in ("I", "3")] print(f"\n {'─' * 50}") if success: print(f" ✓ ATC 检查完成(无严重错误)") else: print(f" ✗ ATC 检查发现 {len(errors)} 个错误") print(f" 错误: {len(errors)} | 警告: {len(warnings)} | 信息: {len(infos)}") print(f" {'─' * 50}") for finding in findings: severity_icon = {"E": "✗", "1": "✗", "W": "⚠", "2": "⚠", "I": "ℹ", "3": "ℹ"}.get( finding["type"], "?" ) line = finding.get("line", "?") text = finding.get("text", "") print(f" {severity_icon} [{finding['type']}] 行 {line}: {text}") def cmd_format(args: argparse.Namespace, client: ADTClient) -> None: """代码格式化(ABAP Pretty Printer)。""" name: str = args.name obj_type: str = args.type 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}没有源代码,不支持格式化操作") return print("=" * 60) print(" SAP ABAP 代码格式化") print("=" * 60) print(f" 对象名称: {parsed.display_name}") print(f" 对象类型: {type_label}") # 读取当前源码 print(f"\n → 正在读取源代码...") try: source = client.get_source(parsed.src_uri) except Exception as e: print(f" ✗ 读取源代码失败: {e}") return print(f" ✓ 源代码读取成功 ({len(source)} 字符)") # 调用 Pretty Printer print(f"\n → 正在调用 Pretty Printer...") try: formatted = client.pretty_print(source) except Exception as e: print(f" ✗ 格式化失败: {e}") return if formatted == source: print(" ℹ 代码已经是格式化的,无需修改") return print(f" ✓ 格式化完成") # 写回 SAP print(f"\n → 正在写回 SAP...") try: lock_handle, corr_nr = client.lock(parsed.obj_uri) try: client.set_source(parsed.src_uri, formatted, lock_handle, corr_nr) print(f" ✓ 源代码已写回") finally: client.unlock(parsed.obj_uri, lock_handle) except Exception as e: print(f" ✗ 写回失败: {e}") return # 激活 try: success, messages = client.activate(name, parsed.obj_uri) if success: print(f" ✓ 激活成功") else: errors = [m for m in messages if m["type"] == "E"] print(f" ⚠ 激活返回 {len(errors)} 个错误") for e in errors: print(f" [错误] 行 {e['line']}: {e['text']}") except Exception as e: print(f" ⚠ 激活失败: {e}") print(f"\n ✓ 格式化操作完成!")