diff --git a/CHANGELOG.md b/CHANGELOG.md index 6164830ba..6dda62bb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ ## 2023-08-01 +2023-08-01 ### Enhanced - Introduced the ability to retrieve commit messages from pull requests across different git providers. - Implemented commit messages retrieval for GitHub and GitLab providers. - Updated the PR description template to include a section for commit messages if they exist. +- Added support for repository-specific configuration files (.pr_agent.yaml) for the PR Agent. +- Implemented this feature for both GitHub and GitLab providers. +- Added a new configuration option 'use_repo_settings_file' to enable or disable the use of a repo-specific settings file. + ## 2023-07-30 diff --git a/pr_agent/agent/pr_agent.py b/pr_agent/agent/pr_agent.py index d0037c95c..cdc8eb0cf 100644 --- a/pr_agent/agent/pr_agent.py +++ b/pr_agent/agent/pr_agent.py @@ -1,7 +1,11 @@ +import logging +import os import shlex +import tempfile from pr_agent.algo.utils import update_settings_from_args from pr_agent.config_loader import get_settings +from pr_agent.git_providers import get_git_provider from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions from pr_agent.tools.pr_description import PRDescription from pr_agent.tools.pr_information_from_user import PRInformationFromUser @@ -31,11 +35,31 @@ def __init__(self): pass async def handle_request(self, pr_url, request) -> bool: + # First, apply repo specific settings if exists + if get_settings().config.use_repo_settings_file: + repo_settings_file = None + try: + git_provider = get_git_provider()(pr_url) + repo_settings = git_provider.get_repo_settings() + if repo_settings: + repo_settings_file = None + fd, repo_settings_file = tempfile.mkstemp(suffix='.toml') + os.write(fd, repo_settings) + get_settings().load_file(repo_settings_file) + finally: + if repo_settings_file: + try: + os.remove(repo_settings_file) + except Exception as e: + logging.error(f"Failed to remove temporary settings file {repo_settings_file}", e) + + # Then, apply user specific settings if exists request = request.replace("'", "\\'") lexer = shlex.shlex(request, posix=True) lexer.whitespace_split = True action, *args = list(lexer) args = update_settings_from_args(args) + action = action.lstrip("/").lower() if action == "reflect_and_review" and not get_settings().pr_reviewer.ask_and_reflect: action = "review" diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index ae3eaebae..4869ca692 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -7,11 +7,11 @@ from retry import retry from starlette_context import context +from .git_provider import FilePatchInfo, GitProvider, IncrementalPR from ..algo.language_handler import is_valid_file from ..algo.utils import load_large_diff from ..config_loader import get_settings from ..servers.utils import RateLimitExceeded -from .git_provider import FilePatchInfo, GitProvider, IncrementalPR class GithubProvider(GitProvider): @@ -251,6 +251,13 @@ def get_notifications(self, since: datetime): def get_issue_comments(self): return self.pr.get_issue_comments() + def get_repo_settings(self): + try: + contents = self.repo_obj.get_contents(".pr_agent.toml", ref=self.pr.head.sha).decoded_content + return contents + except Exception: + return "" + @staticmethod def _parse_pr_url(pr_url: str) -> Tuple[str, int]: parsed_url = urlparse(pr_url) diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index 10363ec18..170b356e6 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -253,6 +253,13 @@ def get_pr_description(self): def get_issue_comments(self): raise NotImplementedError("GitLab provider does not support issue comments yet") + def get_repo_settings(self): + try: + contents = self.gl.projects.get(self.id_project).files.get(file_path='.pr_agent.toml', ref=self.mr.source_branch) + return contents + except Exception: + return "" + def _parse_merge_request_url(self, merge_request_url: str) -> Tuple[str, int]: parsed_url = urlparse(merge_request_url) diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 5d9c08467..fe7f1ec29 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -6,6 +6,7 @@ publish_output=true publish_output_progress=true verbosity_level=0 # 0,1,2 use_extra_bad_extensions=false +use_repo_settings_file=true [pr_reviewer] # /review # require_focused_review=true