Merge remote-tracking branch 'origin/main' into tr/agent_logic

This commit is contained in:
mrT23
2023-07-17 15:59:37 +03:00
13 changed files with 320 additions and 250 deletions

180
INSTALL.md Normal file
View File

@ -0,0 +1,180 @@
## Installation
---
#### Method 1: Use Docker image (no installation required)
To request a review for a PR, or ask a question about a PR, you can run directly from the Docker image. Here's how:
1. To request a review for a PR, run the following command:
```
docker run --rm -it -e OPENAI.KEY=<your key> -e GITHUB.USER_TOKEN=<your token> codiumai/pr-agent --pr_url <pr_url> review
```
2. To ask a question about a PR, run the following command:
```
docker run --rm -it -e OPENAI.KEY=<your key> -e GITHUB.USER_TOKEN=<your token> codiumai/pr-agent --pr_url <pr_url> ask "<your question>"
```
Possible questions you can ask include:
- What is the main theme of this PR?
- Is the PR ready for merge?
- What are the main changes in this PR?
- Should this PR be split into smaller parts?
- Can you compose a rhymed song about this PR?
---
#### Method 2: Run as a GitHub Action
You can use our pre-built Github Action Docker image to run PR-Agent as a Github Action.
1. Add the following file to your repository under `.github/workflows/pr_agent.yml`:
```yaml
on:
pull_request:
issue_comment:
jobs:
pr_agent_job:
runs-on: ubuntu-latest
name: Run pr agent on every pull request, respond to user comments
steps:
- name: PR Agent action step
id: pragent
uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
2. Add the following secret to your repository under `Settings > Secrets`:
```
OPENAI_KEY: <your key>
```
The GITHUB_TOKEN secret is automatically created by GitHub.
3. Merge this change to your main branch.
When you open your next PR, you should see a comment from `github-actions` bot with a review of your PR, and instructions on how to use the rest of the tools.
4. You may configure PR-Agent by adding environment variables under the env section corresponding to any configurable property in the [configuration](./CONFIGURATION.md) file. Some examples:
```yaml
env:
# ... previous environment values
OPENAI.ORG: "<Your organization name under your OpenAI account>"
PR_REVIEWER.REQUIRE_TESTS_REVIEW: "false" # Disable tests review
PR_CODE_SUGGESTIONS.NUM_CODE_SUGGESTIONS: 6 # Increase number of code suggestions
```
---
#### Method 3: Run from source
1. Clone this repository:
```
git clone https://github.com/Codium-ai/pr-agent.git
```
2. Install the requirements in your favorite virtual environment:
```
pip install -r requirements.txt
```
3. Copy the secrets template file and fill in your OpenAI key and your GitHub user token:
```
cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml
# Edit .secrets.toml file
```
4. Run the appropriate Python scripts from the scripts folder:
```
python pr_agent/cli.py --pr_url <pr_url> review
python pr_agent/cli.py --pr_url <pr_url> ask <your question>
python pr_agent/cli.py --pr_url <pr_url> describe
python pr_agent/cli.py --pr_url <pr_url> improve
```
---
#### Method 4: Run as a polling server
Request reviews by tagging your Github user on a PR
Follow steps 1-3 of method 2.
Run the following command to start the server:
```
python pr_agent/servers/github_polling.py
```
---
#### Method 5: Run as a GitHub App
Allowing you to automate the review process on your private or public repositories.
1. Create a GitHub App from the [Github Developer Portal](https://docs.github.com/en/developers/apps/creating-a-github-app).
- Set the following permissions:
- Pull requests: Read & write
- Issue comment: Read & write
- Metadata: Read-only
- Set the following events:
- Issue comment
- Pull request
2. Generate a random secret for your app, and save it for later. For example, you can use:
```
WEBHOOK_SECRET=$(python -c "import secrets; print(secrets.token_hex(10))")
```
3. Acquire the following pieces of information from your app's settings page:
- App private key (click "Generate a private key" and save the file)
- App ID
4. Clone this repository:
```
git clone https://github.com/Codium-ai/pr-agent.git
```
5. Copy the secrets template file and fill in the following:
- Your OpenAI key.
- Set deployment_type to 'app'
- Copy your app's private key to the private_key field.
- Copy your app's ID to the app_id field.
- Copy your app's webhook secret to the webhook_secret field.
```
cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml
# Edit .secrets.toml file
```
6. Build a Docker image for the app and optionally push it to a Docker repository. We'll use Dockerhub as an example:
```
docker build . -t codiumai/pr-agent:github_app --target github_app -f docker/Dockerfile
docker push codiumai/pr-agent:github_app # Push to your Docker repository
```
7. Host the app using a server, serverless function, or container environment. Alternatively, for development and
debugging, you may use tools like smee.io to forward webhooks to your local machine.
8. Go back to your app's settings, and set the following:
- Webhook URL: The URL of your app's server or the URL of the smee.io channel.
- Webhook secret: The secret you generated earlier.
9. Install the app by navigating to the "Install App" tab and selecting your desired repositories.
---

214
README.md
View File

@ -16,30 +16,36 @@ CodiumAI `PR-Agent` is an open-source tool aiming to help developers review PRs
**Auto-Description**: Automatically generating PR description - name, type, summary, and code walkthrough. **Auto-Description**: Automatically generating PR description - name, type, summary, and code walkthrough.
\ \
**PR Review**: Feedback about the PR main theme, type, relevant tests, security issues, focused, and various suggestions for the PR content. **PR Review**: Feedback about the PR main theme, type, relevant tests, security issues, focused PR, and various suggestions for the PR content.
\ \
**Question Answering**: Answering free-text questions about the PR. **Question Answering**: Answering free-text questions about the PR.
\ \
**Code Suggestion**: Committable code suggestions for improving the PR. **Code Suggestion**: Committable code suggestions for improving the PR.
Example results: <h3>Example results:</h2>
</div> </div>
<h>Describe:</h> <h4>Describe:</h4>
<div align="center"> <div align="center">
<p float="center"> <p float="center">
<img src="./pics/describe.gif" width="800"> <img src="./pics/describe.gif" width="800">
</p> </p>
</div> </div>
<h>Ask:</h> <h4>Review:</h4>
<div align="center">
<p float="center">
<img src="./pics/review.gif" width="800">
</p>
</div>
<h4>Ask:</h4>
<div align="center"> <div align="center">
<p float="center"> <p float="center">
<img src="./pics/ask.gif" width="800"> <img src="./pics/ask.gif" width="800">
</p> </p>
</div> </div>
<h>Code Suggestion:</h> <h4>Improve:</h4>
<div align="center"> <div align="center">
<p float="center"> <p float="center">
<img src="./pics/pr_code_suggestions.png" width="800"> <img src="./pics/improve.gif" width="800">
</p> </p>
</div> </div>
<div align="left"> <div align="left">
@ -56,22 +62,22 @@ Example results:
## Live demo ## Live demo
Experience GPT-4 powered PR review on your public GitHub repository with our hosted PR-Agent. To try it, just mention `@CodiumAI-Agent` in any PR comment! The agent will generate a PR review in response. Experience GPT-4 powered PR review on your public GitHub repository with our hosted PR-Agent. To try it, just mention `@CodiumAI-Agent` and add the desired command in any PR comment! The agent will generate a response based on your command.
![Review generation process](./pics/pr-agent-review-process1.gif) ![Review generation process](./pics/demo.gif)
To set up your own PR-Agent, see the [Quickstart](#Quickstart) section To set up your own PR-Agent, see the [Quickstart](#Quickstart) section
--- ---
## Overview ## Overview
`PR-Agent` offers extensive pull request functionalities across various git providers: `PR-Agent` offers extensive pull request functionalities across various git providers:
| | | Github | Gitlab | Bitbucket | | | | GitHub | Gitlab | Bitbucket |
|-------|---------------------------------------------|--------|--------|-----------| |-------|---------------------------------------------|--------|--------|-----------|
| TOOLS | Review | ✓ | ✓ | ✓ | | TOOLS | Review | ✓ | ✓ | ✓ |
| | ⮑ Inline review | ✓ | ✓ | | | | ⮑ Inline review | ✓ | ✓ | |
| | Ask | ✓ | ✓ | | | | Ask | ✓ | ✓ | |
| | Auto-Description | ✓ | | | | | Auto-Description | ✓ | | |
| | Improve Code | ✓ | | | | | Improve Code | ✓ | | |
| | | | | | | | | | | |
| USAGE | CLI | ✓ | ✓ | ✓ | | USAGE | CLI | ✓ | ✓ | ✓ |
| | Tagging bot | ✓ | ✓ | | | | Tagging bot | ✓ | ✓ | |
@ -89,7 +95,7 @@ Examples for invoking the different tools via the [CLI](#quickstart):
"<pr_url>" is the url of the relevant PR (for example: https://github.com/Codium-ai/pr-agent/pull/50). "<pr_url>" is the url of the relevant PR (for example: https://github.com/Codium-ai/pr-agent/pull/50).
In the [configuration](./CONFIGURATION.md) file you can select your git provider (Github, Gitlab, Bitbucket), and further configure the different tools. In the [configuration](./CONFIGURATION.md) file you can select your git provider (GitHub, Gitlab, Bitbucket), and further configure the different tools.
## Quickstart ## Quickstart
@ -100,190 +106,26 @@ To get started with PR-Agent quickly, you first need to acquire two tokens:
There are several ways to use PR-Agent. Let's start with the simplest one: There are several ways to use PR-Agent. Let's start with the simplest one:
---
#### Method 1: Use Docker image (no installation required) ## Install
Here are several ways to install and run PR-Agent:
To request a review for a PR, or ask a question about a PR, you can run directly from the Docker image. Here's how: - [Method 1: Use Docker image (no installation required)](INSTALL.md#method-1-use-docker-image-no-installation-required)
- [Method 2: Run as a GitHub Action](INSTALL.md#method-2-run-as-a-github-action)
1. To request a review for a PR, run the following command: - [Method 3: Run from source](INSTALL.md#method-3-run-from-source)
- [Method 4: Run as a polling server](INSTALL.md#method-4-run-as-a-polling-server)
``` - Request reviews by tagging your GitHub user on a PR
docker run --rm -it -e OPENAI.KEY=<your key> -e GITHUB.USER_TOKEN=<your token> codiumai/pr-agent --pr_url <pr_url> review - [Method 5: Run as a GitHub App](INSTALL.md#method-5-run-as-a-github-app)
``` - Allowing you to automate the review process on your private or public repositories
2. To ask a question about a PR, run the following command:
```
docker run --rm -it -e OPENAI.KEY=<your key> -e GITHUB.USER_TOKEN=<your token> codiumai/pr-agent --pr_url <pr_url> ask "<your question>"
```
Possible questions you can ask include:
- What is the main theme of this PR?
- Is the PR ready for merge?
- What are the main changes in this PR?
- Should this PR be split into smaller parts?
- Can you compose a rhymed song about this PR.
---
#### Method 2: Run as a Github Action
You can use our pre-built Github Action Docker image to run PR-Agent as a Github Action.
1. Add the following file to your repository under `.github/workflows/pr_agent.yml`:
```yaml
on:
pull_request:
issue_comment:
jobs:
pr_agent_job:
runs-on: ubuntu-latest
name: Run pr agent on every pull request, respond to user comments
steps:
- name: PR Agent action step
id: pragent
uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
2. Add the following secret to your repository under `Settings > Secrets`:
```
OPENAI_KEY: <your key>
```
The GITHUB_TOKEN secret is automatically created by Github.
3. Merge this change to your main branch.
When you open your next PR, you should see a comment from `github-actions` bot with a review of your PR, and instructions on how to use the rest of the tools.
4. You may configure PR-Agent by adding environment variables under the env section that corresponds to any configurable property in the [configuration](./CONFIGURATION.md) file. Some examples:
```yaml
env:
# ... previous environment values
OPENAI.ORG: "<Your organization name under your OpenAI account>"
PR_REVIEWER.REQUIRE_TESTS_REVIEW: "false" # Disable tests review
PR_CODE_SUGGESTIONS.NUM_CODE_SUGGESTIONS: 6 # Increase number of code suggestions
```
---
#### Method 3: Run from source
1. Clone this repository:
```
git clone https://github.com/Codium-ai/pr-agent.git
```
2. Install the requirements in your favorite virtual environment:
```
pip install -r requirements.txt
```
3. Copy the secrets template file and fill in your OpenAI key and your GitHub user token:
```
cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml
# Edit .secrets.toml file
```
4. Run the appropriate Python scripts from the scripts folder:
```
python pr_agent/cli.py --pr_url <pr_url> review
python pr_agent/cli.py --pr_url <pr_url> ask <your question>
python pr_agent/cli.py --pr_url <pr_url> describe
python pr_agent/cli.py --pr_url <pr_url> improve
```
---
#### Method 4: Run as a polling server; request reviews by tagging your Github user on a PR
Follow steps 1-3 of method 2.
Run the following command to start the server:
```
python pr_agent/servers/github_polling.py
```
---
#### Method 5: Run as a Github App, allowing you to automate the review process on your private or public repositories.
1. Create a GitHub App from the [Github Developer Portal](https://docs.github.com/en/developers/apps/creating-a-github-app).
- Set the following permissions:
- Pull requests: Read & write
- Issue comment: Read & write
- Metadata: Read-only
- Set the following events:
- Issue comment
- Pull request
2. Generate a random secret for your app, and save it for later. For example, you can use:
```
WEBHOOK_SECRET=$(python -c "import secrets; print(secrets.token_hex(10))")
```
3. Acquire the following pieces of information from your app's settings page:
- App private key (click "Generate a private key", and save the file)
- App ID
4. Clone this repository:
```
git clone https://github.com/Codium-ai/pr-agent.git
```
5. Copy the secrets template file and fill in the following:
- Your OpenAI key.
- Set deployment_type to 'app'
- Copy your app's private key to the private_key field.
- Copy your app's ID to the app_id field.
- Copy your app's webhook secret to the webhook_secret field.
```
cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml
# Edit .secrets.toml file
```
6. Build a Docker image for the app and optionally push it to a Docker repository. We'll use Dockerhub as an example:
```
docker build . -t codiumai/pr-agent:github_app --target github_app -f docker/Dockerfile
docker push codiumai/pr-agent:github_app # Push to your Docker repository
```
7. Host the app using a server, serverless function, or container environment. Alternatively, for development and
debugging, you may use tools like smee.io to forward webhooks to your local machine.
8. Go back to your app's settings, set the following:
- Webhook URL: The URL of your app's server, or the URL of the smee.io channel.
- Webhook secret: The secret you generated earlier.
9. Install the app by navigating to the "Install App" tab, and selecting your desired repositories.
---
## Usage and Tools ## Usage and Tools
**PR-Agent** provides four types of interactions ("tools"): `"PR Reviewer"`, `"PR Q&A"`, `"PR Description"` and `"PR Code Sueggestions"`. **PR-Agent** provides four types of interactions ("tools"): `"PR Reviewer"`, `"PR Q&A"`, `"PR Description"` and `"PR Code Sueggestions"`.
- The "PR Reviewer" tool automatically analyzes PRs, and provides different types of feedbacks. - The "PR Reviewer" tool automatically analyzes PRs, and provides different types of feedback.
- The "PR Ask" tool answers free-text questions about the PR. - The "PR Ask" tool answers free-text questions about the PR.
- The "PR Description" tool automatically sets the PR Title and body. - The "PR Description" tool automatically sets the PR Title and body.
- The "PR Code Suggestion" tool provide inline code suggestions for the PR, that can be applied and committed. - The "PR Code Suggestion" tool provide inline code suggestions for the PR that can be applied and committed.
## How it works ## How it works

BIN
pics/demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

BIN
pics/improve.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 MiB

BIN
pics/review.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 MiB

View File

@ -61,18 +61,24 @@ def parse_code_suggestion(code_suggestions: dict) -> str:
return markdown_text return markdown_text
def try_fix_json(review, max_iter=10): def try_fix_json(review, max_iter=10, code_suggestions=False):
if review.endswith("}"):
return fix_json_escape_char(review)
# Try to fix JSON if it is broken/incomplete: parse until the last valid code suggestion # Try to fix JSON if it is broken/incomplete: parse until the last valid code suggestion
data = {} data = {}
if code_suggestions:
closing_bracket = "]}"
else:
closing_bracket = "]}}"
if review.rfind("'Code suggestions': [") > 0 or review.rfind('"Code suggestions": [') > 0: if review.rfind("'Code suggestions': [") > 0 or review.rfind('"Code suggestions": [') > 0:
last_code_suggestion_ind = [m.end() for m in re.finditer(r"\}\s*,", review)][-1] - 1 last_code_suggestion_ind = [m.end() for m in re.finditer(r"\}\s*,", review)][-1] - 1
valid_json = False valid_json = False
iter_count = 0 iter_count = 0
while last_code_suggestion_ind > 0 and not valid_json and iter_count < max_iter: while last_code_suggestion_ind > 0 and not valid_json and iter_count < max_iter:
try: try:
data = json.loads(review[:last_code_suggestion_ind] + "]}}") data = json.loads(review[:last_code_suggestion_ind] + closing_bracket)
valid_json = True valid_json = True
review = review[:last_code_suggestion_ind].strip() + "]}}" review = review[:last_code_suggestion_ind].strip() + closing_bracket
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
review = review[:last_code_suggestion_ind] review = review[:last_code_suggestion_ind]
# Use regular expression to find the last occurrence of "}," with any number of whitespaces or newlines # Use regular expression to find the last occurrence of "}," with any number of whitespaces or newlines
@ -82,3 +88,17 @@ def try_fix_json(review, max_iter=10):
logging.error("Unable to decode JSON response from AI") logging.error("Unable to decode JSON response from AI")
data = {} data = {}
return data return data
def fix_json_escape_char(json_message=None):
result = None
try:
result = json.loads(json_message)
except Exception as e:
# Find the offending character index:
idx_to_replace = int(str(e).split(' ')[-1].replace(')', ''))
# Remove the offending character:
json_message = list(json_message)
json_message[idx_to_replace] = ' '
new_message = ''.join(json_message)
return fix_JSON(json_message=new_message)
return result

View File

@ -61,9 +61,6 @@ class BitbucketProvider:
def get_title(self): def get_title(self):
return self.pr.title return self.pr.title
def get_description(self):
return self.pr.body
def get_languages(self): def get_languages(self):
languages = {self._get_repo().get_data('language'): 0} languages = {self._get_repo().get_data('language'): 0}
return languages return languages

View File

@ -134,9 +134,6 @@ class GithubProvider(GitProvider):
def get_title(self): def get_title(self):
return self.pr.title return self.pr.title
def get_description(self):
return self.pr.body
def get_languages(self): def get_languages(self):
languages = self._get_repo().get_languages() languages = self._get_repo().get_languages()
return languages return languages

View File

@ -28,6 +28,8 @@ class GitLabProvider(GitProvider):
self.diff_files = None self.diff_files = None
self.temp_comments = [] self.temp_comments = []
self._set_merge_request(merge_request_url) self._set_merge_request(merge_request_url)
self.RE_HUNK_HEADER = re.compile(
r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")
@property @property
def pr(self): def pr(self):
@ -84,25 +86,26 @@ class GitLabProvider(GitProvider):
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()
edit_type, found, source_line_no, target_file, target_line_no = self.search_line(relevant_file, edit_type, found, source_line_no, target_file, target_line_no = self.search_line(relevant_file,
relevant_line_in_file) relevant_line_in_file)
self.send_inline_comment(body, edit_type, found, relevant_file, relevant_line_in_file, source_line_no,
target_file, target_line_no)
def send_inline_comment(self, body, edit_type, found, relevant_file, relevant_line_in_file, source_line_no,
target_file, target_line_no):
if not found: if not found:
logging.info(f"Could not find position for {relevant_file} {relevant_line_in_file}") logging.info(f"Could not find position for {relevant_file} {relevant_line_in_file}")
else: else:
if edit_type == 'addition':
position = target_line_no - 1
else:
position = source_line_no - 1
d = self.last_diff d = self.last_diff
pos_obj = {'position_type': 'text', pos_obj = {'position_type': 'text',
'new_path': target_file.filename, 'new_path': target_file.filename,
'old_path': target_file.old_filename if target_file.old_filename else target_file.filename, 'old_path': target_file.old_filename if target_file.old_filename else target_file.filename,
'base_sha': d.base_commit_sha, 'start_sha': d.start_commit_sha, 'head_sha': d.head_commit_sha} 'base_sha': d.base_commit_sha, 'start_sha': d.start_commit_sha, 'head_sha': d.head_commit_sha}
if edit_type == 'deletion': if edit_type == 'deletion':
pos_obj['old_line'] = position pos_obj['old_line'] = source_line_no - 1
elif edit_type == 'addition': elif edit_type == 'addition':
pos_obj['new_line'] = position pos_obj['new_line'] = target_line_no - 1
else: else:
pos_obj['new_line'] = position pos_obj['new_line'] = target_line_no - 1
pos_obj['old_line'] = position pos_obj['old_line'] = source_line_no - 1
self.mr.discussions.create({'body': body, self.mr.discussions.create({'body': body,
'position': pos_obj}) 'position': pos_obj})
@ -110,24 +113,58 @@ class GitLabProvider(GitProvider):
relevant_file: str, relevant_file: str,
relevant_lines_start: int, relevant_lines_start: int,
relevant_lines_end: int): relevant_lines_end: int):
raise "not implemented yet for gitlab" self.diff_files = self.diff_files if self.diff_files else self.get_diff_files()
target_file = None
for file in self.diff_files:
if file.filename == relevant_file:
if file.filename == relevant_file:
target_file = file
break
range = relevant_lines_end - relevant_lines_start + 1
body = body.replace('```suggestion', f'```suggestion:-0+{range}')
d = self.last_diff
#
# pos_obj = {'position_type': 'text',
# 'new_path': target_file.filename,
# 'old_path': target_file.old_filename if target_file.old_filename else target_file.filename,
# 'base_sha': d.base_commit_sha, 'start_sha': d.start_commit_sha, 'head_sha': d.head_commit_sha}
lines = target_file.head_file.splitlines()
relevant_line_in_file = lines[relevant_lines_start - 1]
edit_type, found, source_line_no, target_file, target_line_no = self.find_in_file(target_file, relevant_line_in_file)
self.send_inline_comment(body, edit_type, found, relevant_file, relevant_line_in_file, source_line_no,
target_file, target_line_no)
# if lines[relevant_lines_start][0] == '-':
# pos_obj['old_line'] = relevant_lines_start
# elif lines[relevant_lines_start][0] == '+':
# pos_obj['new_line'] = relevant_lines_start
# else:
# pos_obj['new_line'] = relevant_lines_start
# pos_obj['old_line'] = relevant_lines_start
# self.mr.discussions.create({'body': body,
# 'position': pos_obj})
def search_line(self, relevant_file, relevant_line_in_file): def search_line(self, relevant_file, relevant_line_in_file):
RE_HUNK_HEADER = re.compile(
r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")
target_file = None target_file = None
source_line_no = 0
target_line_no = 0
found = False
edit_type = self.get_edit_type(relevant_line_in_file) edit_type = self.get_edit_type(relevant_line_in_file)
for file in self.diff_files: for file in self.diff_files:
if file.filename == relevant_file: if file.filename == relevant_file:
edit_type, found, source_line_no, target_file, target_line_no = self.find_in_file(file,
relevant_line_in_file)
return edit_type, found, source_line_no, target_file, target_line_no
def find_in_file(self, file, relevant_line_in_file):
edit_type = 'context'
source_line_no = 0
target_line_no = 0
found = False
target_file = file target_file = file
patch = file.patch patch = file.patch
patch_lines = patch.splitlines() patch_lines = patch.splitlines()
for i, line in enumerate(patch_lines): for i, line in enumerate(patch_lines):
if line.startswith('@@'): if line.startswith('@@'):
match = RE_HUNK_HEADER.match(line) match = self.RE_HUNK_HEADER.match(line)
if not match: if not match:
continue continue
start_old, size_old, start_new, size_new, _ = match.groups() start_old, size_old, start_new, size_new, _ = match.groups()
@ -171,9 +208,6 @@ class GitLabProvider(GitProvider):
def get_title(self): def get_title(self):
return self.mr.title return self.mr.title
def get_description(self):
return self.mr.description
def get_languages(self): def get_languages(self):
languages = self.gl.projects.get(self.id_project).languages() languages = self.gl.projects.get(self.id_project).languages()
return languages return languages

View File

@ -94,7 +94,7 @@ async def polling_loop():
success = await agent.handle_request(pr_url, rest_of_comment) success = await agent.handle_request(pr_url, rest_of_comment)
if not success: if not success:
git_provider.set_pr(pr_url) git_provider.set_pr(pr_url)
git_provider.publish_comment("### How to user PR-Agent\n" + git_provider.publish_comment("### How to use PR-Agent\n" +
bot_help_text(user_id)) bot_help_text(user_id))
elif response.status != 304: elif response.status != 304:

View File

@ -10,7 +10,7 @@ from pr_agent.algo.pr_processing import get_pr_diff
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import convert_to_markdown, try_fix_json from pr_agent.algo.utils import convert_to_markdown, try_fix_json
from pr_agent.config_loader import settings from pr_agent.config_loader import settings
from pr_agent.git_providers import get_git_provider, GithubProvider from pr_agent.git_providers import get_git_provider, BitbucketProvider
from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.git_providers.git_provider import get_main_pr_language
@ -39,7 +39,7 @@ class PRCodeSuggestions:
settings.pr_code_suggestions_prompt.user) settings.pr_code_suggestions_prompt.user)
async def suggest(self): async def suggest(self):
assert type(self.git_provider) == GithubProvider, "Only Github is supported for now" assert type(self.git_provider) != BitbucketProvider, "Bitbucket is not supported for now"
logging.info('Generating code suggestions for PR...') logging.info('Generating code suggestions for PR...')
if settings.config.publish_review: if settings.config.publish_review:
@ -86,7 +86,7 @@ class PRCodeSuggestions:
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.info(f"Could not parse json response: {review}") logging.info(f"Could not parse json response: {review}")
data = try_fix_json(review) data = try_fix_json(review, code_suggestions=True)
return data return data
def push_inline_code_suggestions(self, data): def push_inline_code_suggestions(self, data):

View File

@ -23,7 +23,7 @@ class PRDescription:
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,
"branch": self.git_provider.get_pr_branch(), "branch": self.git_provider.get_pr_branch(),
"description": self.git_provider.get_description(), "description": self.git_provider.get_pr_description(),
"language": self.main_pr_language, "language": self.main_pr_language,
"diff": "", # empty diff for initial calculation "diff": "", # empty diff for initial calculation
} }

View File

@ -22,7 +22,7 @@ class PRQuestions:
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,
"branch": self.git_provider.get_pr_branch(), "branch": self.git_provider.get_pr_branch(),
"description": self.git_provider.get_description(), "description": self.git_provider.get_pr_description(),
"language": self.main_pr_language, "language": self.main_pr_language,
"diff": "", # empty diff for initial calculation "diff": "", # empty diff for initial calculation
"questions": self.question_str, "questions": self.question_str,