This commit is contained in:
@@ -86,6 +86,8 @@ class EndpointChangeReport:
|
|||||||
parameter_changes: List[ParameterChange] = field(default_factory=list)
|
parameter_changes: List[ParameterChange] = field(default_factory=list)
|
||||||
is_new_endpoint: bool = False
|
is_new_endpoint: bool = False
|
||||||
is_removed_endpoint: bool = False
|
is_removed_endpoint: bool = False
|
||||||
|
is_renamed_endpoint: bool = False
|
||||||
|
old_uri: Optional[str] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_changes(self) -> bool:
|
def has_changes(self) -> bool:
|
||||||
@@ -93,6 +95,7 @@ class EndpointChangeReport:
|
|||||||
return (
|
return (
|
||||||
self.is_new_endpoint
|
self.is_new_endpoint
|
||||||
or self.is_removed_endpoint
|
or self.is_removed_endpoint
|
||||||
|
or self.is_renamed_endpoint
|
||||||
or len(self.parameter_changes) > 0
|
or len(self.parameter_changes) > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -215,26 +218,75 @@ def compare_endpoints(
|
|||||||
"""
|
"""
|
||||||
对比新旧两个版本的全部 Controller 端点,生成变更报告列表。
|
对比新旧两个版本的全部 Controller 端点,生成变更报告列表。
|
||||||
|
|
||||||
:param old_endpoints: 旧版本 { endpoint_key: ApiEndpoint }
|
支持 URI 重命名检测(路径变更)。
|
||||||
:param new_endpoints: 新版本 { endpoint_key: ApiEndpoint }
|
|
||||||
:return: 有变更的接口报告列表
|
|
||||||
"""
|
"""
|
||||||
reports: List[EndpointChangeReport] = []
|
reports: List[EndpointChangeReport] = []
|
||||||
|
|
||||||
all_keys = set(old_endpoints.keys()) | set(new_endpoints.keys())
|
old_keys = set(old_endpoints.keys())
|
||||||
|
new_keys = set(new_endpoints.keys())
|
||||||
|
|
||||||
for key in sorted(all_keys):
|
removed_keys = old_keys - new_keys
|
||||||
old_ep = old_endpoints.get(key)
|
added_keys = new_keys - old_keys
|
||||||
new_ep = new_endpoints.get(key)
|
common_keys = old_keys & new_keys
|
||||||
|
|
||||||
if old_ep is None and new_ep is not None:
|
# 1. URI 重命名检测:在 removed + added 中找 method+controller+method_name 相同的配对
|
||||||
# 全新接口
|
unmatched_removed: List[Tuple[str, ApiEndpoint]] = []
|
||||||
|
unmatched_added: List[Tuple[str, ApiEndpoint]] = []
|
||||||
|
|
||||||
|
for key in removed_keys:
|
||||||
|
unmatched_removed.append((key, old_endpoints[key]))
|
||||||
|
for key in added_keys:
|
||||||
|
unmatched_added.append((key, new_endpoints[key]))
|
||||||
|
|
||||||
|
matched_removed: Set[str] = set()
|
||||||
|
matched_added: Set[str] = set()
|
||||||
|
|
||||||
|
for r_key, r_ep in unmatched_removed:
|
||||||
|
for a_key, a_ep in unmatched_added:
|
||||||
|
if a_key in matched_added:
|
||||||
|
continue
|
||||||
|
# 匹配条件:method 相同 + controller 相同 + method_name 相同
|
||||||
|
if (
|
||||||
|
r_ep.http_method == a_ep.http_method
|
||||||
|
and r_ep.controller_class == a_ep.controller_class
|
||||||
|
and r_ep.method_name == a_ep.method_name
|
||||||
|
):
|
||||||
|
reports.append(
|
||||||
|
EndpointChangeReport(
|
||||||
|
uri=a_ep.uri,
|
||||||
|
http_method=a_ep.http_method,
|
||||||
|
controller_class=a_ep.controller_class,
|
||||||
|
method_name=a_ep.method_name,
|
||||||
|
is_renamed_endpoint=True,
|
||||||
|
old_uri=r_ep.uri,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
matched_removed.add(r_key)
|
||||||
|
matched_added.add(a_key)
|
||||||
|
break
|
||||||
|
|
||||||
|
# 2. 剩余未匹配的 removed → 删除接口
|
||||||
|
for key, ep in unmatched_removed:
|
||||||
|
if key not in matched_removed:
|
||||||
reports.append(
|
reports.append(
|
||||||
EndpointChangeReport(
|
EndpointChangeReport(
|
||||||
uri=new_ep.uri,
|
uri=ep.uri,
|
||||||
http_method=new_ep.http_method,
|
http_method=ep.http_method,
|
||||||
controller_class=new_ep.controller_class,
|
controller_class=ep.controller_class,
|
||||||
method_name=new_ep.method_name,
|
method_name=ep.method_name,
|
||||||
|
is_removed_endpoint=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. 剩余未匹配的 added → 新增接口
|
||||||
|
for key, ep in unmatched_added:
|
||||||
|
if key not in matched_added:
|
||||||
|
reports.append(
|
||||||
|
EndpointChangeReport(
|
||||||
|
uri=ep.uri,
|
||||||
|
http_method=ep.http_method,
|
||||||
|
controller_class=ep.controller_class,
|
||||||
|
method_name=ep.method_name,
|
||||||
is_new_endpoint=True,
|
is_new_endpoint=True,
|
||||||
parameter_changes=[
|
parameter_changes=[
|
||||||
ParameterChange(
|
ParameterChange(
|
||||||
@@ -243,26 +295,15 @@ def compare_endpoints(
|
|||||||
param_type=p.type,
|
param_type=p.type,
|
||||||
required=p.required,
|
required=p.required,
|
||||||
)
|
)
|
||||||
for p in new_ep.parameters
|
for p in ep.parameters
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
continue
|
|
||||||
|
|
||||||
if new_ep is None and old_ep is not None:
|
# 4. 共同 URI:对比参数变更
|
||||||
# 接口被删除
|
for key in common_keys:
|
||||||
reports.append(
|
old_ep = old_endpoints[key]
|
||||||
EndpointChangeReport(
|
new_ep = new_endpoints[key]
|
||||||
uri=old_ep.uri,
|
|
||||||
http_method=old_ep.http_method,
|
|
||||||
controller_class=old_ep.controller_class,
|
|
||||||
method_name=old_ep.method_name,
|
|
||||||
is_removed_endpoint=True,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 同 URI 对比参数
|
|
||||||
param_changes = compare_parameters(old_ep.parameters, new_ep.parameters)
|
param_changes = compare_parameters(old_ep.parameters, new_ep.parameters)
|
||||||
if param_changes:
|
if param_changes:
|
||||||
reports.append(
|
reports.append(
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ def _format_endpoint_block(report: EndpointChangeReport) -> str:
|
|||||||
detail_lines.append("### <font color=\"warning\">参数变更明细</font>")
|
detail_lines.append("### <font color=\"warning\">参数变更明细</font>")
|
||||||
|
|
||||||
if report.parameter_changes:
|
if report.parameter_changes:
|
||||||
# 简化:使用列表格式匹配模板
|
|
||||||
for change in report.parameter_changes:
|
for change in report.parameter_changes:
|
||||||
md = change.to_markdown_line(plain=report.is_new_endpoint)
|
md = change.to_markdown_line(plain=report.is_new_endpoint)
|
||||||
detail_lines.append(md)
|
detail_lines.append(md)
|
||||||
@@ -72,19 +71,41 @@ def build_markdown_notification(
|
|||||||
:param llm_summary: LLM 兼容性摘要(可选,简短)
|
:param llm_summary: LLM 兼容性摘要(可选,简短)
|
||||||
:return: Markdown 文本
|
:return: Markdown 文本
|
||||||
"""
|
"""
|
||||||
parts = [
|
parts: List[str] = []
|
||||||
"# API参数变更通知",
|
|
||||||
f"- **变更类型:** 修改参数",
|
|
||||||
f"- **修改人:** {push_user}",
|
|
||||||
f"- **修改时间:** {push_time}",
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
|
|
||||||
# 新增 Controller(全部为新接口)与变更接口分组
|
# 分组:路径变更、参数变更、新增、删除
|
||||||
|
renamed_reports = [r for r in reports if r.is_renamed_endpoint]
|
||||||
new_reports = [r for r in reports if r.is_new_endpoint]
|
new_reports = [r for r in reports if r.is_new_endpoint]
|
||||||
changed_reports = [r for r in reports if not r.is_new_endpoint and not r.is_removed_endpoint]
|
changed_reports = [
|
||||||
|
r for r in reports
|
||||||
|
if not r.is_new_endpoint and not r.is_removed_endpoint and not r.is_renamed_endpoint
|
||||||
|
]
|
||||||
removed_reports = [r for r in reports if r.is_removed_endpoint]
|
removed_reports = [r for r in reports if r.is_removed_endpoint]
|
||||||
|
|
||||||
|
# 路径变更优先使用 model1.md 模板
|
||||||
|
for report in renamed_reports:
|
||||||
|
old_uri = report.old_uri or "-"
|
||||||
|
new_uri = report.uri or "已删除"
|
||||||
|
path_md = build_path_change_markdown(
|
||||||
|
old_uri=old_uri,
|
||||||
|
new_uri=new_uri,
|
||||||
|
change_type="修改路径",
|
||||||
|
push_user=push_user,
|
||||||
|
push_time=push_time,
|
||||||
|
file_name=report.controller_class,
|
||||||
|
)
|
||||||
|
parts.append(path_md)
|
||||||
|
parts.append("")
|
||||||
|
|
||||||
|
if new_reports or changed_reports or removed_reports:
|
||||||
|
parts.extend([
|
||||||
|
"# API参数变更通知",
|
||||||
|
f"- **变更类型:** 修改参数",
|
||||||
|
f"- **修改人:** {push_user}",
|
||||||
|
f"- **修改时间:** {push_time}",
|
||||||
|
"",
|
||||||
|
])
|
||||||
|
|
||||||
for report in new_reports:
|
for report in new_reports:
|
||||||
parts.append(_format_endpoint_block(report))
|
parts.append(_format_endpoint_block(report))
|
||||||
parts.append("")
|
parts.append("")
|
||||||
|
|||||||
Reference in New Issue
Block a user