mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-05 21:30:40 +08:00
Merge pull request #1118 from Codium-ai/tr/bitbucket_diffs
Improve Bitbucket patch diff handling
This commit is contained in:
@ -8,7 +8,7 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0, patch_extra_lines_after=0) -> str:
|
def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0, patch_extra_lines_after=0) -> str:
|
||||||
if not patch_str or (patch_extra_lines_before == 0 and patch_extra_lines_after == 0):
|
if not patch_str or (patch_extra_lines_before == 0 and patch_extra_lines_after == 0) or not original_file_str:
|
||||||
return patch_str
|
return patch_str
|
||||||
|
|
||||||
if type(original_file_str) == bytes:
|
if type(original_file_str) == bytes:
|
||||||
@ -52,9 +52,9 @@ def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0, patch
|
|||||||
extended_size1 = size1 + (start1 - extended_start1) + patch_extra_lines_after
|
extended_size1 = size1 + (start1 - extended_start1) + patch_extra_lines_after
|
||||||
extended_start2 = max(1, start2 - patch_extra_lines_before)
|
extended_start2 = max(1, start2 - patch_extra_lines_before)
|
||||||
extended_size2 = size2 + (start2 - extended_start2) + patch_extra_lines_after
|
extended_size2 = size2 + (start2 - extended_start2) + patch_extra_lines_after
|
||||||
if extended_start1 - 1 + extended_size1 > len(original_lines):
|
if extended_start1 - 1 + extended_size1 > len_original_lines:
|
||||||
# we cannot extend beyond the original file
|
# we cannot extend beyond the original file
|
||||||
delta_cap = extended_start1 - 1 + extended_size1 - len(original_lines)
|
delta_cap = extended_start1 - 1 + extended_size1 - len_original_lines
|
||||||
extended_size1 = max(extended_size1 - delta_cap, size1)
|
extended_size1 = max(extended_size1 - delta_cap, size1)
|
||||||
extended_size2 = max(extended_size2 - delta_cap, size2)
|
extended_size2 = max(extended_size2 - delta_cap, size2)
|
||||||
delta_lines = original_lines[extended_start1 - 1:start1 - 1]
|
delta_lines = original_lines[extended_start1 - 1:start1 - 1]
|
||||||
|
@ -108,8 +108,12 @@ class BitbucketProvider(GitProvider):
|
|||||||
get_logger().error(f"Failed to publish code suggestion, error: {e}")
|
get_logger().error(f"Failed to publish code suggestion, error: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def publish_file_comments(self, file_comments: list) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
def is_supported(self, capability: str) -> bool:
|
def is_supported(self, capability: str) -> bool:
|
||||||
if capability in ['get_issue_comments', 'publish_inline_comments', 'get_labels', 'gfm_markdown']:
|
if capability in ['get_issue_comments', 'publish_inline_comments', 'get_labels', 'gfm_markdown',
|
||||||
|
'publish_file_comments']:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -137,9 +141,28 @@ class BitbucketProvider(GitProvider):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
diff_split = [
|
# get the pr patches
|
||||||
"diff --git%s" % x for x in self.pr.diff().split("diff --git") if x.strip()
|
pr_patch = self.pr.diff()
|
||||||
]
|
diff_split = ["diff --git" + x for x in pr_patch.split("diff --git") if x.strip()]
|
||||||
|
if len(diff_split) != len(diffs):
|
||||||
|
get_logger().error(f"Error - failed to split the diff into {len(diffs)} parts")
|
||||||
|
return []
|
||||||
|
# bitbucket diff has a header for each file, we need to remove it:
|
||||||
|
# "diff --git filename
|
||||||
|
# index caa56f0..61528d7 100644
|
||||||
|
# --- a/pr_agent/cli_pip.py
|
||||||
|
# +++ b/pr_agent/cli_pip.py
|
||||||
|
# @@ -... @@"
|
||||||
|
for i, _ in enumerate(diff_split):
|
||||||
|
diff_split_lines = diff_split[i].splitlines()
|
||||||
|
if (len(diff_split_lines) > 5 and
|
||||||
|
diff_split_lines[2].startswith("---") and
|
||||||
|
diff_split_lines[3].startswith("+++") and
|
||||||
|
diff_split_lines[4].startswith("@@")):
|
||||||
|
diff_split[i] = "\n".join(diff_split_lines[4:])
|
||||||
|
else:
|
||||||
|
get_logger().error(f"Error - failed to remove the bitbucket header from diff {i}")
|
||||||
|
break
|
||||||
|
|
||||||
invalid_files_names = []
|
invalid_files_names = []
|
||||||
diff_files = []
|
diff_files = []
|
||||||
@ -148,10 +171,14 @@ class BitbucketProvider(GitProvider):
|
|||||||
invalid_files_names.append(diff.new.path)
|
invalid_files_names.append(diff.new.path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
original_file_content_str = self._get_pr_file_content(
|
try:
|
||||||
diff.old.get_data("links")
|
original_file_content_str = self._get_pr_file_content(diff.old.get_data("links")['self']['href'])
|
||||||
)
|
new_file_content_str = self._get_pr_file_content(diff.new.get_data("links")['self']['href'])
|
||||||
new_file_content_str = self._get_pr_file_content(diff.new.get_data("links"))
|
except Exception as e:
|
||||||
|
get_logger().exception(f"Error - bitbucket failed to get file content, error: {e}")
|
||||||
|
original_file_content_str = ""
|
||||||
|
new_file_content_str = ""
|
||||||
|
|
||||||
file_patch_canonic_structure = FilePatchInfo(
|
file_patch_canonic_structure = FilePatchInfo(
|
||||||
original_file_content_str,
|
original_file_content_str,
|
||||||
new_file_content_str,
|
new_file_content_str,
|
||||||
@ -172,7 +199,6 @@ class BitbucketProvider(GitProvider):
|
|||||||
if invalid_files_names:
|
if invalid_files_names:
|
||||||
get_logger().info(f"Disregarding files with invalid extensions:\n{invalid_files_names}")
|
get_logger().info(f"Disregarding files with invalid extensions:\n{invalid_files_names}")
|
||||||
|
|
||||||
|
|
||||||
self.diff_files = diff_files
|
self.diff_files = diff_files
|
||||||
return diff_files
|
return diff_files
|
||||||
|
|
||||||
@ -314,6 +340,9 @@ class BitbucketProvider(GitProvider):
|
|||||||
def get_pr_branch(self):
|
def get_pr_branch(self):
|
||||||
return self.pr.source_branch
|
return self.pr.source_branch
|
||||||
|
|
||||||
|
def get_pr_owner_id(self) -> str | None:
|
||||||
|
return self.workspace_slug
|
||||||
|
|
||||||
def get_pr_description_full(self):
|
def get_pr_description_full(self):
|
||||||
return self.pr.description
|
return self.pr.description
|
||||||
|
|
||||||
@ -400,6 +429,13 @@ class BitbucketProvider(GitProvider):
|
|||||||
get_logger().exception(f"Failed to create empty file {file_path} in branch {branch}")
|
get_logger().exception(f"Failed to create empty file {file_path} in branch {branch}")
|
||||||
|
|
||||||
def _get_pr_file_content(self, remote_link: str):
|
def _get_pr_file_content(self, remote_link: str):
|
||||||
|
try:
|
||||||
|
response = requests.request("GET", remote_link, headers=self.headers)
|
||||||
|
if response.status_code == 404: # not found
|
||||||
|
return ""
|
||||||
|
contents = response.text
|
||||||
|
return contents
|
||||||
|
except Exception:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def get_commit_messages(self):
|
def get_commit_messages(self):
|
||||||
|
Reference in New Issue
Block a user