diff --git a/pr_agent/git_providers/git_provider.py b/pr_agent/git_providers/git_provider.py index 3ad1b2e0..deb5df3d 100644 --- a/pr_agent/git_providers/git_provider.py +++ b/pr_agent/git_providers/git_provider.py @@ -26,6 +26,8 @@ class FilePatchInfo: tokens: int = -1 edit_type: EDIT_TYPE = EDIT_TYPE.UNKNOWN old_filename: str = None + num_plus_lines: int = -1 + num_minus_lines: int = -1 class GitProvider(ABC): diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index 7e13e0ee..3ae97742 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -143,8 +143,15 @@ class GithubProvider(GitProvider): else: get_logger().error(f"Unknown edit type: {file.status}") edit_type = EDIT_TYPE.UNKNOWN + + # count number of lines added and removed + patch_lines = patch.splitlines(keepends=True) + num_plus_lines = len([line for line in patch_lines if line.startswith('+')]) + num_minus_lines = len([line for line in patch_lines if line.startswith('-')]) file_patch_canonical_structure = FilePatchInfo(original_file_content_str, new_file_content_str, patch, - file.filename, edit_type=edit_type) + file.filename, edit_type=edit_type, + num_plus_lines=num_plus_lines, + num_minus_lines=num_minus_lines,) diff_files.append(file_patch_canonical_structure) self.diff_files = diff_files diff --git a/pr_agent/settings/pr_description_prompts.toml b/pr_agent/settings/pr_description_prompts.toml index bd94d3c1..2225088d 100644 --- a/pr_agent/settings/pr_description_prompts.toml +++ b/pr_agent/settings/pr_description_prompts.toml @@ -54,7 +54,7 @@ Class PRDescription(BaseModel): main_files_walkthrough: List[FileWalkthrough] = Field(max_items=10) {%- endif %} {%- if enable_semantic_files_types %} - pr_files[List[FileDescription]] = Field(max_items=15) + pr_files[List[FileDescription]] = Field(max_items=15") {%- endif %} ===== diff --git a/pr_agent/tools/pr_description.py b/pr_agent/tools/pr_description.py index 94a1ee83..5a074390 100644 --- a/pr_agent/tools/pr_description.py +++ b/pr_agent/tools/pr_description.py @@ -81,18 +81,8 @@ class PRDescription: else: return None - self.file_label_dict = {} - for file in self.data['pr_files']: - try: - filename = file['filename'].replace("'", "`").replace('"', '`') - changes_summary = file['changes_summary'] - label = file['label'] - if label not in self.file_label_dict: - self.file_label_dict[label] = [] - self.file_label_dict[label].append((filename, changes_summary)) - except Exception as e: - get_logger().error(f"Error preparing file label dict {self.pr_id}: {e}") - pass + if get_settings().pr_description.enable_semantic_files_types: + self._prepare_file_labels() pr_labels = [] if get_settings().pr_description.publish_labels: @@ -272,12 +262,13 @@ class PRDescription: # except for the items containing the word 'walkthrough' pr_body = "" for idx, (key, value) in enumerate(self.data.items()): - key_publish = key.rstrip(':').replace("_", " ").capitalize() if key == 'pr_files': value = self.file_label_dict + key_publish = "PR changes summary" + else: + key_publish = key.rstrip(':').replace("_", " ").capitalize() pr_body += f"## {key_publish}\n" if 'walkthrough' in key.lower(): - # for filename, description in value.items(): if self.git_provider.is_supported("gfm_markdown"): pr_body += "
files:\n\n" for file in value: @@ -295,30 +286,39 @@ class PRDescription: if self.git_provider.is_supported("gfm_markdown"): # pr_body += f"
{semantic_label['label']}\n\n" pr_body += f"| **{s_label}** |
files:
    " - else: - pr_body += f"| **{s_label}** | " list_tuples = value[semantic_label] - for filename,file_change_description in list_tuples: + for filename, file_change_description in list_tuples: filename = filename.replace("'", "`") - # description = file['changes_in_file'] - # pr_body += f'- `{filename}`\n' + filename_publish = filename.split("/")[-1] + filename_publish = f"**{filename_publish}**" + diff_plus_minus = "" + diff_files = self.git_provider.diff_files + for f in diff_files: + if f.filename.lower() == filename.lower(): + num_plus_lines = f.num_plus_lines + num_minus_lines = f.num_minus_lines + diff_plus_minus += f" ( +{num_plus_lines}/-{num_minus_lines} )" + break # try to add line numbers link to code suggestions if hasattr(self.git_provider, 'get_line_link'): filename = filename.strip() link = self.git_provider.get_line_link(filename, relevant_line_start=-1) if link: - filename = f"[{filename}]({link})" + diff_plus_minus = f"[{diff_plus_minus}]({link})" + diff_plus_minus= f" {diff_plus_minus}" + + if diff_plus_minus: + filename_publish += diff_plus_minus if self.git_provider.is_supported("gfm_markdown"): - pr_body += f"
    {filename}" - pr_body += f"
      Change summary:
      **{file_change_description}**
    " - # else: - # pr_body += f"{filename}    " + pr_body += f"
    {filename_publish}" + if diff_plus_minus: + pr_body += f"
      Change summary:
      **{file_change_description}**
    " + else: + pr_body += f"
      Change summary:
      **{file_change_description}**
" if self.git_provider.is_supported("gfm_markdown"): pr_body += "
|\n" - # else: - # pr_body += "|" else: # if the value is a list, join its items by comma if isinstance(value, list): @@ -330,4 +330,18 @@ class PRDescription: if get_settings().config.verbosity_level >= 2: get_logger().info(f"title:\n{title}\n{pr_body}") - return title, pr_body \ No newline at end of file + return title, pr_body + + def _prepare_file_labels(self): + self.file_label_dict = {} + for file in self.data['pr_files']: + try: + filename = file['filename'].replace("'", "`").replace('"', '`') + changes_summary = file['changes_summary'] + label = file['label'] + if label not in self.file_label_dict: + self.file_label_dict[label] = [] + self.file_label_dict[label].append((filename, changes_summary)) + except Exception as e: + get_logger().error(f"Error preparing file label dict {self.pr_id}: {e}") + pass \ No newline at end of file