From 654938f27c837d131c70f54fec25b4854dd4534a Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 10 Dec 2023 17:30:27 +0200 Subject: [PATCH 1/5] feat: Enhance code feedback formatting in utils.py --- pr_agent/algo/utils.py | 58 +++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index d5e1a3c63..50505e248 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -59,7 +59,7 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool=True) -> str: if key.lower() == 'code feedback': if gfm_supported: markdown_text += f"\n\n- " - markdown_text += f"
{ emoji } Code feedback:\n\n" + markdown_text += f"
{ emoji } Code feedback:" else: markdown_text += f"\n\n- **{emoji} Code feedback:**\n\n" else: @@ -91,24 +91,52 @@ def parse_code_suggestion(code_suggestions: dict, gfm_supported: bool=True) -> s str: A string containing the markdown formatted text generated from the input dictionary. """ markdown_text = "" - for sub_key, sub_value in code_suggestions.items(): - if isinstance(sub_value, dict): # "code example" - markdown_text += f" - **{sub_key}:**\n" - for code_key, code_value in sub_value.items(): # 'before' and 'after' code - code_str = f"```\n{code_value}\n```" - code_str_indented = textwrap.indent(code_str, ' ') - markdown_text += f" - **{code_key}:**\n{code_str_indented}\n" - else: - if "relevant file" in sub_key.lower(): - markdown_text += f"\n - **{sub_key}:** {sub_value} \n" + if gfm_supported and 'relevant line' in code_suggestions: + # markdown_text=markdown_text.strip() + markdown_text += '' + relevant_file = '' + for sub_key, sub_value in code_suggestions.items(): + try: + if sub_key.lower() == 'relevant file': + relevant_file = sub_value.strip('`').strip('"').strip("'") + markdown_text += f"" + # continue + elif sub_key.lower() == 'suggestion': + markdown_text += f"" + elif sub_key.lower() == 'relevant line': + markdown_text += f"" + sub_value_list = sub_value.split('](') + relevant_line = sub_value_list[0].lstrip('`').lstrip('[') + if len(sub_value_list) > 1: + link = sub_value_list[1].rstrip(')').strip('`') + markdown_text += f"" + else: + markdown_text += f"" + markdown_text += "" + except Exception as e: + get_logger().exception(f"Failed to parse code suggestion: {e}") + pass + markdown_text += '
{sub_key}{relevant_file}
{sub_key}      {sub_value}
relevant line{relevant_line}{relevant_line}
' + markdown_text += "
" + else: + for sub_key, sub_value in code_suggestions.items(): + if isinstance(sub_value, dict): # "code example" + markdown_text += f" - **{sub_key}:**\n" + for code_key, code_value in sub_value.items(): # 'before' and 'after' code + code_str = f"```\n{code_value}\n```" + code_str_indented = textwrap.indent(code_str, ' ') + markdown_text += f" - **{code_key}:**\n{code_str_indented}\n" else: - markdown_text += f" **{sub_key}:** {sub_value} \n" - if not gfm_supported: - if "relevant line" not in sub_key.lower(): # nicer presentation + if "relevant file" in sub_key.lower(): + markdown_text += f"\n - **{sub_key}:** {sub_value} \n" + else: + markdown_text += f" **{sub_key}:** {sub_value} \n" + if not gfm_supported: + if "relevant line" not in sub_key.lower(): # nicer presentation # markdown_text = markdown_text.rstrip('\n') + "\\\n" # works for gitlab markdown_text = markdown_text.rstrip('\n') + " \n" # works for gitlab and bitbucker - markdown_text += "\n" + markdown_text += "\n" return markdown_text From a247fc326342fb818a41d3b30eb7141b658e59c5 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 10 Dec 2023 17:46:49 +0200 Subject: [PATCH 2/5] s --- pr_agent/algo/utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 50505e248..c68e7f6f2 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -64,9 +64,9 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool=True) -> str: markdown_text += f"\n\n- **{emoji} Code feedback:**\n\n" else: markdown_text += f"- {emoji} **{key}:**\n\n" - for item in value: + for i, item in enumerate(value): if isinstance(item, dict) and key.lower() == 'code feedback': - markdown_text += parse_code_suggestion(item, gfm_supported) + markdown_text += parse_code_suggestion(item, i, gfm_supported) elif item: markdown_text += f" - {item}\n" if key.lower() == 'code feedback': @@ -80,7 +80,7 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool=True) -> str: return markdown_text -def parse_code_suggestion(code_suggestions: dict, gfm_supported: bool=True) -> str: +def parse_code_suggestion(code_suggestions: dict, i:int, gfm_supported: bool=True) -> str: """ Convert a dictionary of data into markdown format. @@ -91,6 +91,8 @@ def parse_code_suggestion(code_suggestions: dict, gfm_supported: bool=True) -> s str: A string containing the markdown formatted text generated from the input dictionary. """ markdown_text = "" + if i == 0: + markdown_text += "
" if gfm_supported and 'relevant line' in code_suggestions: # markdown_text=markdown_text.strip() markdown_text += '' From 2b1e841ef15b5b88673ddff1d0487fe992cfb81d Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 10 Dec 2023 19:45:54 +0200 Subject: [PATCH 3/5] s --- pr_agent/algo/utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index c68e7f6f2..8b2f21d79 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -80,7 +80,7 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool=True) -> str: return markdown_text -def parse_code_suggestion(code_suggestions: dict, i:int, gfm_supported: bool=True) -> str: +def parse_code_suggestion(code_suggestions: dict, i: int = 0, gfm_supported: bool = True) -> str: """ Convert a dictionary of data into markdown format. @@ -91,12 +91,10 @@ def parse_code_suggestion(code_suggestions: dict, i:int, gfm_supported: bool=Tru str: A string containing the markdown formatted text generated from the input dictionary. """ markdown_text = "" - if i == 0: - markdown_text += "
" if gfm_supported and 'relevant line' in code_suggestions: - # markdown_text=markdown_text.strip() + if i == 0: + markdown_text += "
" markdown_text += '
' - relevant_file = '' for sub_key, sub_value in code_suggestions.items(): try: if sub_key.lower() == 'relevant file': From b8cc110cbe7179b983a609eea128f0da2ddacf80 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 10 Dec 2023 19:51:08 +0200 Subject: [PATCH 4/5] s --- tests/unittest/test_convert_to_markdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittest/test_convert_to_markdown.py b/tests/unittest/test_convert_to_markdown.py index b03c4fdec..800d3ada8 100644 --- a/tests/unittest/test_convert_to_markdown.py +++ b/tests/unittest/test_convert_to_markdown.py @@ -71,7 +71,7 @@ def test_simple_dictionary_input(self): - ๐Ÿ“Œ **Type of PR:** Test type\n\ - ๐Ÿงช **Relevant tests added:** no\n\ - โœจ **Focused PR:** Yes\n\ -- **General PR suggestions:** general suggestion...\n\n\n-
๐Ÿค– Code feedback:\n\n - **Code example:**\n - **Before:**\n ```\n Code before\n ```\n - **After:**\n ```\n Code after\n ```\n\n - **Code example:**\n - **Before:**\n ```\n Code before 2\n ```\n - **After:**\n ```\n Code after 2\n ```\n\n
\ +- **General PR suggestions:** general suggestion...\n\n\n-
๐Ÿค– Code feedback: - **Code example:**\n - **Before:**\n ```\n Code before\n ```\n - **After:**\n ```\n Code after\n ```\n\n - **Code example:**\n - **Before:**\n ```\n Code before 2\n ```\n - **After:**\n ```\n Code after 2\n ```\n\n
\ """ assert convert_to_markdown(input_data).strip() == expected_output.strip() From 02c0c89b13628c558adfeae882e593218512a8ba Mon Sep 17 00:00:00 2001 From: mrT23 Date: Mon, 11 Dec 2023 08:29:09 +0200 Subject: [PATCH 5/5] feat: Add exception handling for discussion creation in gitlab_provider.py --- pr_agent/git_providers/gitlab_provider.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index 7b11ef54e..c5e77d07c 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -211,7 +211,11 @@ def send_inline_comment(self,body: str,edit_type: str,found: bool,relevant_file: pos_obj['new_line'] = target_line_no - 1 pos_obj['old_line'] = source_line_no - 1 get_logger().debug(f"Creating comment in {self.id_mr} with body {body} and position {pos_obj}") - self.mr.discussions.create({'body': body, 'position': pos_obj}) + try: + self.mr.discussions.create({'body': body, 'position': pos_obj}) + except Exception as e: + get_logger().debug( + f"Failed to create comment in {self.id_mr} with position {pos_obj} (probably not a '+' line)") def get_relevant_diff(self, relevant_file: str, relevant_line_in_file: int) -> Optional[dict]: changes = self.mr.changes() # Retrieve the changes for the merge request once