"""Pull Request model that provides GitHub-compatible interface for Gitea pull requests.""" from typing import Optional, Dict, Any, List class PullRequest: """ Pull Request wrapper that provides GitHub-compatible interface for Gitea pull requests. """ def __init__(self, gitea_pr, gitea_repo, gitea_client): """ Initialize pull request wrapper. Args: gitea_pr: The Gitea pull request object gitea_repo: The Gitea repository object gitea_client: The Gitea client instance """ self._pr = gitea_pr self._repo = gitea_repo self._gitea = gitea_client # Map Gitea attributes to GitHub attributes self.number = gitea_pr.number self.state = gitea_pr.state self.title = gitea_pr.title self.body = gitea_pr.body self.created_at = gitea_pr.created_at self.updated_at = gitea_pr.updated_at self.closed_at = gitea_pr.closed_at self.merged_at = gitea_pr.merged_at self.merge_commit_sha = gitea_pr.merge_commit_sha self.html_url = gitea_pr.html_url self.diff_url = gitea_pr.diff_url self.patch_url = gitea_pr.patch_url self.mergeable = gitea_pr.mergeable self.merged = gitea_pr.merged self.draft = getattr(gitea_pr, 'draft', False) # Gitea might not have draft PRs # User information self.user = self._create_user_object(gitea_pr.user) self.assignee = self._create_user_object(gitea_pr.assignee) if gitea_pr.assignee else None self.assignees = [self._create_user_object(a) for a in getattr(gitea_pr, 'assignees', [])] # Branch information self.base = self._create_branch_info(gitea_pr.base) self.head = self._create_branch_info(gitea_pr.head) # Labels and milestone self.labels = [self._create_label_object(l) for l in getattr(gitea_pr, 'labels', [])] self.milestone = self._create_milestone_object(gitea_pr.milestone) if gitea_pr.milestone else None def _create_user_object(self, gitea_user) -> Dict[str, Any]: """Create a GitHub-compatible user object.""" if not gitea_user: return None return { 'login': gitea_user.login, 'id': gitea_user.id, 'avatar_url': gitea_user.avatar_url, 'type': 'User' } def _create_branch_info(self, gitea_branch) -> Dict[str, Any]: """Create a GitHub-compatible branch info object.""" return { 'ref': gitea_branch.ref, 'sha': gitea_branch.sha, 'repo': { 'name': gitea_branch.repo.name, 'full_name': gitea_branch.repo.full_name, 'owner': self._create_user_object(gitea_branch.repo.owner) } if gitea_branch.repo else None } def _create_label_object(self, gitea_label) -> Dict[str, Any]: """Create a GitHub-compatible label object.""" return { 'name': gitea_label.name, 'color': gitea_label.color, 'description': gitea_label.description } def _create_milestone_object(self, gitea_milestone) -> Dict[str, Any]: """Create a GitHub-compatible milestone object.""" return { 'title': gitea_milestone.title, 'description': gitea_milestone.description, 'state': gitea_milestone.state, 'number': gitea_milestone.id, 'due_on': gitea_milestone.due_on } def update(self, **kwargs) -> 'PullRequest': """ Update the pull request. Args: **kwargs: Fields to update (title, body, state, base, etc.) Returns: Updated PullRequest object """ # Map GitHub parameters to Gitea parameters update_params = {} if 'title' in kwargs: update_params['title'] = kwargs['title'] if 'body' in kwargs: update_params['body'] = kwargs['body'] if 'state' in kwargs: update_params['state'] = kwargs['state'] if 'assignee' in kwargs: update_params['assignee'] = kwargs['assignee'] if 'assignees' in kwargs: update_params['assignees'] = kwargs['assignees'] if 'labels' in kwargs: update_params['labels'] = kwargs['labels'] if 'milestone' in kwargs: update_params['milestone'] = kwargs['milestone'] # Update using Gitea API updated_pr = self._pr.update(**update_params) # Return new PullRequest instance with updated data return PullRequest(updated_pr, self._repo, self._gitea) def merge(self, commit_title: Optional[str] = None, commit_message: Optional[str] = None, sha: Optional[str] = None, merge_method: str = 'merge') -> Dict[str, Any]: """ Merge the pull request. Args: commit_title: Title for the merge commit commit_message: Message for the merge commit sha: SHA that must match the HEAD of the PR merge_method: Merge method ('merge', 'squash', 'rebase') Returns: Merge result information """ # Map GitHub merge methods to Gitea gitea_merge_style = { 'merge': 'merge', 'squash': 'squash', 'rebase': 'rebase' }.get(merge_method, 'merge') # Merge using Gitea API result = self._pr.merge( style=gitea_merge_style, title=commit_title, message=commit_message ) return { 'sha': result.sha if hasattr(result, 'sha') else None, 'merged': True, 'message': 'Pull Request successfully merged' } def get_commits(self) -> List[Dict[str, Any]]: """ Get commits in the pull request. Returns: List of commit objects """ gitea_commits = self._pr.get_commits() commits = [] for commit in gitea_commits: commits.append({ 'sha': commit.sha, 'commit': { 'message': commit.commit.message, 'author': { 'name': commit.commit.author.name, 'email': commit.commit.author.email, 'date': commit.commit.author.date } }, 'html_url': commit.html_url }) return commits def get_files(self) -> List[Dict[str, Any]]: """ Get files changed in the pull request. Returns: List of file objects """ gitea_files = self._pr.get_files() files = [] for file in gitea_files: files.append({ 'filename': file.filename, 'status': file.status, 'additions': file.additions, 'deletions': file.deletions, 'changes': file.changes, 'patch': file.patch, 'sha': file.sha, 'blob_url': file.blob_url, 'raw_url': file.raw_url }) return files def create_review_comment(self, body: str, commit_id: str, path: str, position: int) -> Dict[str, Any]: """ Create a review comment on the pull request. Args: body: Comment body commit_id: Commit SHA to comment on path: File path to comment on position: Line position in the diff Returns: Comment object """ comment = self._pr.create_review_comment( body=body, commit_id=commit_id, path=path, position=position ) return { 'id': comment.id, 'body': comment.body, 'path': comment.path, 'position': comment.position, 'commit_id': comment.commit_id, 'user': self._create_user_object(comment.user), 'created_at': comment.created_at, 'updated_at': comment.updated_at } def create_issue_comment(self, body: str) -> Dict[str, Any]: """ Create a general comment on the pull request. Args: body: Comment body Returns: Comment object """ comment = self._pr.create_comment(body=body) return { 'id': comment.id, 'body': comment.body, 'user': self._create_user_object(comment.user), 'created_at': comment.created_at, 'updated_at': comment.updated_at }