.
This commit is contained in:
parent
451a6d8b42
commit
4277547e19
@ -4,6 +4,7 @@ system="""你是 PR-Reviewer, 一个专注于 Pull Request (PR) 代码分析和
|
|||||||
你的任务是检查所提供的代码 diff, 重点关注新增代码 (行以 '+' 为前缀), 并提供简洁且可操作的建议以修复可能的 bug 和问题, 同时提升代码质量和性能.
|
你的任务是检查所提供的代码 diff, 重点关注新增代码 (行以 '+' 为前缀), 并提供简洁且可操作的建议以修复可能的 bug 和问题, 同时提升代码质量和性能.
|
||||||
{%- else %}
|
{%- else %}
|
||||||
你的任务是检查所提供的代码 diff, 重点关注新增代码 (行以 '+' 为前缀), 并提供简洁且可操作的建议以修复关键 bug 和问题.
|
你的任务是检查所提供的代码 diff, 重点关注新增代码 (行以 '+' 为前缀), 并提供简洁且可操作的建议以修复关键 bug 和问题.
|
||||||
|
从代码的角度生成测试可读的信息,使得在后续的测试中能够针对变更的内容进行功能的测试.
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
PR 代码差异将采用以下结构化格式:
|
PR 代码差异将采用以下结构化格式:
|
||||||
@ -73,6 +74,7 @@ __new hunk__
|
|||||||
|
|
||||||
额外用户提供的指令(应优先处理):
|
额外用户提供的指令(应优先处理):
|
||||||
======
|
======
|
||||||
|
从代码的角度生成测试可读的信息,使得在后续的测试中能够针对变更的内容进行功能的测试.
|
||||||
{{ extra_instructions }}
|
{{ extra_instructions }}
|
||||||
回答必须使用简体中文,并且必须使用英文标点符号!
|
回答必须使用简体中文,并且必须使用英文标点符号!
|
||||||
======
|
======
|
||||||
@ -85,6 +87,7 @@ class CodeSuggestion(BaseModel):
|
|||||||
relevant_file: str = Field(description="相关文件的完整路径")
|
relevant_file: str = Field(description="相关文件的完整路径")
|
||||||
language: str = Field(description="相关文件使用的编程语言")
|
language: str = Field(description="相关文件使用的编程语言")
|
||||||
suggestion_content: str = Field(description="一个可操作的建议,用于增强、改进或修复PR中引入的新代码. 不要在这里呈现实际的代码片段, 只需要建议. 简明扼要")
|
suggestion_content: str = Field(description="一个可操作的建议,用于增强、改进或修复PR中引入的新代码. 不要在这里呈现实际的代码片段, 只需要建议. 简明扼要")
|
||||||
|
test_content: str = Field(description="请用面向测试人员、非技术化的语言,描述本次变更对功能、流程、接口、页面等的影响,指出需要重点验证的功能点、场景或风险。不要出现任何代码术语或实现细节,让测试能直接据此设计用例或关注点。")
|
||||||
existing_code: str = Field(description="一个简短的代码片段, 来自PR更改后的 '__new hunk__' 部分, 该建议旨在增强或修复. 仅包括完整的代码行. 如果需要, 使用省略号 (...) 来保持简洁. 此片段应代表目标改进的特定PR代码.")
|
existing_code: str = Field(description="一个简短的代码片段, 来自PR更改后的 '__new hunk__' 部分, 该建议旨在增强或修复. 仅包括完整的代码行. 如果需要, 使用省略号 (...) 来保持简洁. 此片段应代表目标改进的特定PR代码.")
|
||||||
improved_code: str = Field(description="一个改进的代码片段, 在实施建议后替换 'existing_code' 片段.")
|
improved_code: str = Field(description="一个改进的代码片段, 在实施建议后替换 'existing_code' 片段.")
|
||||||
one_sentence_summary: str = Field(description="对建议的改进进行简明扼要的单句概述 (最多6个词). 关注 'what'. 保持通用性, 避免方法或变量名称,回答尽量使用简体中文,并且必须使用英文标点符号.")
|
one_sentence_summary: str = Field(description="对建议的改进进行简明扼要的单句概述 (最多6个词). 关注 'what'. 保持通用性, 避免方法或变量名称,回答尽量使用简体中文,并且必须使用英文标点符号.")
|
||||||
@ -109,6 +112,8 @@ code_suggestions:
|
|||||||
python
|
python
|
||||||
suggestion_content: |
|
suggestion_content: |
|
||||||
...
|
...
|
||||||
|
test_content: |
|
||||||
|
...
|
||||||
existing_code: |
|
existing_code: |
|
||||||
...
|
...
|
||||||
improved_code: |
|
improved_code: |
|
||||||
@ -148,6 +153,8 @@ code_suggestions:
|
|||||||
python
|
python
|
||||||
suggestion_content: |
|
suggestion_content: |
|
||||||
...
|
...
|
||||||
|
test_content: |
|
||||||
|
...
|
||||||
existing_code: |
|
existing_code: |
|
||||||
...
|
...
|
||||||
improved_code: |
|
improved_code: |
|
||||||
|
|||||||
@ -690,10 +690,10 @@ class PRCodeSuggestions:
|
|||||||
one_sentence_summary_list = []
|
one_sentence_summary_list = []
|
||||||
for i, suggestion in enumerate(data['code_suggestions']):
|
for i, suggestion in enumerate(data['code_suggestions']):
|
||||||
try:
|
try:
|
||||||
needed_keys = ['one_sentence_summary', 'label', 'relevant_file']
|
needed_keys = ['one_sentence_summary', 'label', 'relevant_file', 'test_content']
|
||||||
is_valid_keys = True
|
is_valid_keys = True
|
||||||
for key in needed_keys:
|
for key in needed_keys:
|
||||||
if key not in suggestion:
|
if key not in suggestion or not suggestion[key]:
|
||||||
is_valid_keys = False
|
is_valid_keys = False
|
||||||
get_logger().debug(
|
get_logger().debug(
|
||||||
f"Skipping suggestion {i + 1}, because it does not contain '{key}':\n'{suggestion}"
|
f"Skipping suggestion {i + 1}, because it does not contain '{key}':\n'{suggestion}"
|
||||||
@ -776,17 +776,23 @@ class PRCodeSuggestions:
|
|||||||
relevant_file, relevant_lines_start, new_code_snippet
|
relevant_file, relevant_lines_start, new_code_snippet
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 增加 test_content 到 suggestion body
|
||||||
|
test_content = d.get('test_content', '').strip()
|
||||||
|
test_content_str = f"\n\n**测试建议:** {test_content}" if test_content else ""
|
||||||
|
|
||||||
if d.get('score'):
|
if d.get('score'):
|
||||||
body = (
|
body = (
|
||||||
f"**Suggestion:** {content} [{label}, importance: {d.get('score')}]\n```suggestion\n"
|
f"**Suggestion:** {content} [{label}, importance: {d.get('score')}]\n```suggestion\n"
|
||||||
+ new_code_snippet
|
+ new_code_snippet
|
||||||
+ "\n```"
|
+ "\n```"
|
||||||
|
+ test_content_str
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
body = (
|
body = (
|
||||||
f"**Suggestion:** {content} [{label}]\n```suggestion\n"
|
f"**Suggestion:** {content} [{label}]\n```suggestion\n"
|
||||||
+ new_code_snippet
|
+ new_code_snippet
|
||||||
+ "\n```"
|
+ "\n```"
|
||||||
|
+ test_content_str
|
||||||
)
|
)
|
||||||
code_suggestions.append(
|
code_suggestions.append(
|
||||||
{
|
{
|
||||||
@ -999,7 +1005,7 @@ class PRCodeSuggestions:
|
|||||||
header = f"建议"
|
header = f"建议"
|
||||||
delta = 66
|
delta = 66
|
||||||
header += " " * delta
|
header += " " * delta
|
||||||
pr_body += f"""<thead><tr><td><strong>类别</strong></td><td align=left><strong>{header}</strong></td><td align=center><strong>影响</strong></td></tr>"""
|
pr_body += f"""<thead><tr><td><strong>类别</strong></td><td align=left><strong>{header}</strong></td><td align=left><strong>测试建议</strong></td><td align=center><strong>影响</strong></td></tr>"""
|
||||||
pr_body += """<tbody>"""
|
pr_body += """<tbody>"""
|
||||||
suggestions_labels = dict()
|
suggestions_labels = dict()
|
||||||
# add all suggestions related to each label
|
# add all suggestions related to each label
|
||||||
@ -1013,14 +1019,14 @@ class PRCodeSuggestions:
|
|||||||
suggestions_labels = dict(
|
suggestions_labels = dict(
|
||||||
sorted(
|
sorted(
|
||||||
suggestions_labels.items(),
|
suggestions_labels.items(),
|
||||||
key=lambda x: max([s['score'] for s in x[1]]),
|
key=lambda x: max([s.get('score', 0) for s in x[1]]),
|
||||||
reverse=True,
|
reverse=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# sort the suggestions inside each label group by score
|
# sort the suggestions inside each label group by score
|
||||||
for label, suggestions in suggestions_labels.items():
|
for label, suggestions in suggestions_labels.items():
|
||||||
suggestions_labels[label] = sorted(
|
suggestions_labels[label] = sorted(
|
||||||
suggestions, key=lambda x: x['score'], reverse=True
|
suggestions, key=lambda x: x.get('score', 0), reverse=True
|
||||||
)
|
)
|
||||||
|
|
||||||
counter_suggestions = 0
|
counter_suggestions = 0
|
||||||
@ -1068,9 +1074,9 @@ class PRCodeSuggestions:
|
|||||||
pr_body += f"""<td>\n\n"""
|
pr_body += f"""<td>\n\n"""
|
||||||
else:
|
else:
|
||||||
pr_body += f"""<tr><td>\n\n"""
|
pr_body += f"""<tr><td>\n\n"""
|
||||||
suggestion_summary = (
|
# 新增测试建议表格列
|
||||||
suggestion['one_sentence_summary'].strip().rstrip('.')
|
test_content = suggestion.get('test_content', '').strip()
|
||||||
)
|
suggestion_summary = suggestion.get('one_sentence_summary', '').strip().rstrip('.')
|
||||||
if "'<" in suggestion_summary and ">'" in suggestion_summary:
|
if "'<" in suggestion_summary and ">'" in suggestion_summary:
|
||||||
# escape the '<' and '>' characters, otherwise they are interpreted as html tags
|
# escape the '<' and '>' characters, otherwise they are interpreted as html tags
|
||||||
get_logger().info(
|
get_logger().info(
|
||||||
@ -1085,6 +1091,8 @@ class PRCodeSuggestions:
|
|||||||
pr_body += f"""
|
pr_body += f"""
|
||||||
**{suggestion_content}**
|
**{suggestion_content}**
|
||||||
|
|
||||||
|
**测试建议:** {suggestion.get('test_content', '').strip()}
|
||||||
|
|
||||||
[{relevant_file} {range_str}]({code_snippet_link})
|
[{relevant_file} {range_str}]({code_snippet_link})
|
||||||
|
|
||||||
{example_code.rstrip()}
|
{example_code.rstrip()}
|
||||||
@ -1096,12 +1104,15 @@ class PRCodeSuggestions:
|
|||||||
|
|
||||||
pr_body += f"</details>"
|
pr_body += f"</details>"
|
||||||
|
|
||||||
|
# 新增测试建议表格列
|
||||||
|
pr_body += f"</td><td>{test_content}</td>"
|
||||||
|
|
||||||
# # add another column for 'score'
|
# # add another column for 'score'
|
||||||
score_int = int(suggestion.get('score', 0))
|
score_int = int(suggestion.get('score', 0))
|
||||||
score_str = f"{score_int}"
|
score_str = f"{score_int}"
|
||||||
if get_settings().pr_code_suggestions.new_score_mechanism:
|
if get_settings().pr_code_suggestions.new_score_mechanism:
|
||||||
score_str = self.get_score_str(score_int)
|
score_str = self.get_score_str(score_int)
|
||||||
pr_body += f"</td><td align=center>{score_str}\n\n"
|
pr_body += f"<td align=center>{score_str}\n\n"
|
||||||
|
|
||||||
pr_body += f"</td></tr>"
|
pr_body += f"</td></tr>"
|
||||||
counter_suggestions += 1
|
counter_suggestions += 1
|
||||||
@ -1109,6 +1120,19 @@ class PRCodeSuggestions:
|
|||||||
# pr_body += "</details>"
|
# pr_body += "</details>"
|
||||||
# pr_body += """</td></tr>"""
|
# pr_body += """</td></tr>"""
|
||||||
pr_body += """</tr></tbody></table>"""
|
pr_body += """</tr></tbody></table>"""
|
||||||
|
|
||||||
|
# 额外输出测试建议列表
|
||||||
|
test_suggestions = [
|
||||||
|
s.get('test_content', '').strip()
|
||||||
|
for label in suggestions_labels.values()
|
||||||
|
for s in label
|
||||||
|
if s.get('test_content', '').strip()
|
||||||
|
]
|
||||||
|
if test_suggestions:
|
||||||
|
pr_body += "\n\n<strong>【测试建议汇总】</strong><br>\n"
|
||||||
|
for idx, test_content in enumerate(test_suggestions, 1):
|
||||||
|
pr_body += f"{idx}. {test_content}<br>\n"
|
||||||
|
|
||||||
return pr_body
|
return pr_body
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
get_logger().info(
|
get_logger().info(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user