diff --git a/docs/docs/tools/review.md b/docs/docs/tools/review.md index 8d4a5543..4e63bf2d 100644 --- a/docs/docs/tools/review.md +++ b/docs/docs/tools/review.md @@ -98,6 +98,11 @@ extra_instructions = "..." require_security_review If set to true, the tool will add a section that checks if the PR contains a possible security or vulnerability issue. Default is true. + + + require_todo_scan + If set to true, the tool will add a section that lists TODO comments found in the PR code changes. Default is true. + require_ticket_analysis_review diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 780c7953..ba55f938 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -131,6 +131,7 @@ def convert_to_markdown_v2(output_data: dict, "Focused PR": "✨", "Relevant ticket": "🎫", "Security concerns": "🔒", + "Todo sections": "✅", "Insights from user's answers": "📝", "Code feedback": "🤖", "Estimated effort to review [1-5]": "⏱️", @@ -153,7 +154,7 @@ def convert_to_markdown_v2(output_data: dict, for key, value in output_data['review'].items(): if value is None or value == '' or value == {} or value == []: - if key.lower() not in ['can_be_split', 'key_issues_to_review']: + if key.lower() not in ['can_be_split', 'key_issues_to_review', 'todo_sections']: continue key_nice = key.replace('_', ' ').capitalize() emoji = emojis.get(key_nice, "") @@ -209,6 +210,50 @@ def convert_to_markdown_v2(output_data: dict, markdown_text += f"### {emoji} Security concerns\n\n" value = emphasize_header(value.strip(), only_markdown=True) markdown_text += f"{value}\n\n" + elif 'todo sections' in key_nice.lower(): + if gfm_supported: + markdown_text += f"" + if is_value_no(value): + markdown_text += f"{emoji} No ToDo sections" + else: + markdown_text += f"{emoji} ToDo sections

\n\n" + if isinstance(value, list): + markdown_text += "\n" + markdown_text += f"\n" + else: + if is_value_no(value): + markdown_text += f"### {emoji} No ToDo sections\n\n" + else: + markdown_text += f"### {emoji} ToDo sections\n\n" + if isinstance(value, list): + for todo_item in value: + relevant_file = todo_item.get('relevant_file', '') + line_number = todo_item.get('line_number', '') + content = todo_item.get('content', '') + if git_provider and relevant_file and line_number: + reference_link = git_provider.get_line_link(relevant_file, line_number, line_number) + file_line = f"[{relevant_file} [{line_number}]]({reference_link})" + else: + file_line = f"{relevant_file} [{line_number}]" + if content.strip(): + markdown_text += f"- {file_line}: {content}\n" + else: + markdown_text += f"- {file_line}\n" elif 'can be split' in key_nice.lower(): if gfm_supported: markdown_text += f"" diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index c6437931..e4c279b9 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -77,6 +77,7 @@ require_tests_review=true require_estimate_effort_to_review=true require_can_be_split_review=false require_security_review=true +require_todo_scan=true require_ticket_analysis_review=true # general options persistent_comment=true diff --git a/pr_agent/settings/pr_reviewer_prompts.toml b/pr_agent/settings/pr_reviewer_prompts.toml index d4c0a523..87cbbc06 100644 --- a/pr_agent/settings/pr_reviewer_prompts.toml +++ b/pr_agent/settings/pr_reviewer_prompts.toml @@ -72,6 +72,11 @@ class KeyIssuesComponentLink(BaseModel): start_line: int = Field(description="The start line that corresponds to this issue in the relevant file") end_line: int = Field(description="The end line that corresponds to this issue in the relevant file") +class TodoSection(BaseModel): + relevant_file: str = Field(description="The file containing the TODO comment") + line_number: int = Field(description="The line number of the TODO comment") + content: str = Field(description="The content of the TODO comment. Only include items that are actual TODO comments inside code comments (e.g., lines starting with #, //, /*,