code suggestions

This commit is contained in:
mrT23
2023-07-19 20:57:14 +03:00
parent a2eb2e4dac
commit 3d5d517f2a
5 changed files with 93 additions and 76 deletions

View File

@ -53,8 +53,7 @@ class GitProvider(ABC):
pass pass
@abstractmethod @abstractmethod
def publish_code_suggestion(self, body: str, relevant_file: str, def publish_code_suggestions(self, code_suggestions: list):
relevant_lines_start: int, relevant_lines_end: int):
pass pass
@abstractmethod @abstractmethod

View File

@ -146,24 +146,32 @@ class GithubProvider(GitProvider):
def publish_inline_comments(self, comments: list[dict]): def publish_inline_comments(self, comments: list[dict]):
self.pr.create_review(commit=self.last_commit_id, comments=comments) self.pr.create_review(commit=self.last_commit_id, comments=comments)
def publish_code_suggestion(self, body: str, def publish_code_suggestions(self, code_suggestions: list):
relevant_file: str, """
relevant_lines_start: int, Publishes code suggestions as comments on the PR.
relevant_lines_end: int): In practice current APU enables to send only one code suggestion per comment. Might change in the future.
"""
post_parameters_list = []
import github.PullRequestComment
for suggestion in code_suggestions:
body = suggestion['body']
relevant_file = suggestion['relevant_file']
relevant_lines_start = suggestion['relevant_lines_start']
relevant_lines_end = suggestion['relevant_lines_end']
if not relevant_lines_start or relevant_lines_start == -1: if not relevant_lines_start or relevant_lines_start == -1:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.exception(f"Failed to publish code suggestion, relevant_lines_start is {relevant_lines_start}") logging.exception(
return False f"Failed to publish code suggestion, relevant_lines_start is {relevant_lines_start}")
continue
if relevant_lines_end < relevant_lines_start: if relevant_lines_end < relevant_lines_start:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.exception(f"Failed to publish code suggestion, " logging.exception(f"Failed to publish code suggestion, "
f"relevant_lines_end is {relevant_lines_end} and " f"relevant_lines_end is {relevant_lines_end} and "
f"relevant_lines_start is {relevant_lines_start}") f"relevant_lines_start is {relevant_lines_start}")
return False continue
try:
import github.PullRequestComment
if relevant_lines_end > relevant_lines_start: if relevant_lines_end > relevant_lines_start:
post_parameters = { post_parameters = {
"body": body, "body": body,
@ -181,6 +189,8 @@ class GithubProvider(GitProvider):
"line": relevant_lines_start, "line": relevant_lines_start,
"side": "RIGHT", "side": "RIGHT",
} }
try:
headers, data = self.pr._requester.requestJsonAndCheck( headers, data = self.pr._requester.requestJsonAndCheck(
"POST", f"{self.pr.url}/comments", input=post_parameters "POST", f"{self.pr.url}/comments", input=post_parameters
) )
@ -314,7 +324,6 @@ class GithubProvider(GitProvider):
for p in pr_types: for p in pr_types:
color = label_color_map.get(p, "d1bcf9") # default to "Other" color color = label_color_map.get(p, "d1bcf9") # default to "Other" color
post_parameters.append({"name": p, "color": color}) post_parameters.append({"name": p, "color": color})
post_parameters.append({"name": p, "color": colors[ind]})
headers, data = self.pr._requester.requestJsonAndCheck( headers, data = self.pr._requester.requestJsonAndCheck(
"PUT", f"{self.pr.issue_url}/labels", input=post_parameters "PUT", f"{self.pr.issue_url}/labels", input=post_parameters
) )

View File

@ -135,10 +135,13 @@ class GitLabProvider(GitProvider):
self.mr.discussions.create({'body': body, self.mr.discussions.create({'body': body,
'position': pos_obj}) 'position': pos_obj})
def publish_code_suggestion(self, body: str, def publish_code_suggestions(self, code_suggestions: list):
relevant_file: str, for suggestion in code_suggestions:
relevant_lines_start: int, body = suggestion['body']
relevant_lines_end: int): relevant_file = suggestion['relevant_file']
relevant_lines_start = suggestion['relevant_lines_start']
relevant_lines_end = suggestion['relevant_lines_end']
self.diff_files = self.diff_files if self.diff_files else self.get_diff_files() self.diff_files = self.diff_files if self.diff_files else self.get_diff_files()
target_file = None target_file = None
for file in self.diff_files: for file in self.diff_files:

View File

@ -1,9 +1,9 @@
commands_text = "> /review [-i]: Request a review of your Pull Request. For an incremental review, which only " \ commands_text = "> **/review [-i]**: Request a review of your Pull Request. For an incremental review, which only " \
"considers changes since the last review, include the '-i' option.\n" \ "considers changes since the last review, include the '-i' option.\n" \
"> /describe: Modify the PR title and description based on the contents of the PR.\n" \ "> **/describe**: Modify the PR title and description based on the contents of the PR.\n" \
"> /improve: Suggest improvements to the code in the PR. " \ "> **/improve**: Suggest improvements to the code in the PR. " \
"These will be provided as pull request comments, ready to commit.\n" \ "These will be provided as pull request comments, ready to commit.\n" \
"> /ask \\<QUESTION\\>: Pose a question about the PR.\n" "> **/ask \\<QUESTION\\>**: Pose a question about the PR.\n"
def bot_help_text(user: str): def bot_help_text(user: str):

View File

@ -79,7 +79,6 @@ class PRCodeSuggestions:
def _prepare_pr_code_suggestions(self) -> str: def _prepare_pr_code_suggestions(self) -> str:
review = self.prediction.strip() review = self.prediction.strip()
data = None
try: try:
data = json.loads(review) data = json.loads(review)
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
@ -89,6 +88,7 @@ class PRCodeSuggestions:
return data return data
def push_inline_code_suggestions(self, data): def push_inline_code_suggestions(self, data):
code_suggestions = []
for d in data['Code suggestions']: for d in data['Code suggestions']:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.info(f"suggestion: {d}") logging.info(f"suggestion: {d}")
@ -100,6 +100,16 @@ class PRCodeSuggestions:
new_code_snippet = d['improved code'] new_code_snippet = d['improved code']
if new_code_snippet: if new_code_snippet:
new_code_snippet = self.dedent_code(relevant_file, relevant_lines_start, new_code_snippet)
body = f"**Suggestion:** {content}\n```suggestion\n" + new_code_snippet + "\n```"
code_suggestions.append({'body': body,'relevant_file': relevant_file,
'relevant_lines_start': relevant_lines_start,
'relevant_lines_end': relevant_lines_end})
self.git_provider.publish_code_suggestions(code_suggestions)
def dedent_code(self, relevant_file, relevant_lines_start, new_code_snippet):
try: # dedent code snippet try: # dedent code snippet
self.diff_files = self.git_provider.diff_files if self.git_provider.diff_files \ self.diff_files = self.git_provider.diff_files if self.git_provider.diff_files \
else self.git_provider.get_diff_files() else self.git_provider.get_diff_files()
@ -119,8 +129,4 @@ class PRCodeSuggestions:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.info(f"Could not dedent code snippet for file {relevant_file}, error: {e}") logging.info(f"Could not dedent code snippet for file {relevant_file}, error: {e}")
body = f"**Suggestion:** {content}\n```suggestion\n" + new_code_snippet + "\n```" return new_code_snippet
self.git_provider.publish_code_suggestion(body=body,
relevant_file=relevant_file,
relevant_lines_start=relevant_lines_start,
relevant_lines_end=relevant_lines_end)