"""Repository model that provides GitHub-compatible interface for Gitea repositories.""" from typing import Optional, List, Dict, Any try: # When running tests or using as a module from models.pull_request import PullRequest except ImportError: # When using as a package from .pull_request import PullRequest class Repository: """ Repository wrapper that provides GitHub-compatible interface for Gitea repositories. """ def __init__(self, gitea_repo, gitea_client): """ Initialize repository wrapper. Args: gitea_repo: The Gitea repository object gitea_client: The Gitea client instance """ self._repo = gitea_repo self._gitea = gitea_client # Map Gitea attributes to GitHub attributes self.name = gitea_repo.name self.full_name = gitea_repo.full_name self.description = gitea_repo.description self.private = gitea_repo.private self.fork = gitea_repo.fork self.created_at = gitea_repo.created_at self.updated_at = gitea_repo.updated_at self.pushed_at = gitea_repo.updated_at # Gitea doesn't have pushed_at self.size = gitea_repo.size self.stargazers_count = gitea_repo.stars_count self.watchers_count = gitea_repo.watchers_count self.forks_count = gitea_repo.forks_count self.open_issues_count = gitea_repo.open_issues_count self.default_branch = gitea_repo.default_branch self.archived = gitea_repo.archived self.html_url = gitea_repo.html_url self.clone_url = gitea_repo.clone_url self.ssh_url = gitea_repo.ssh_url # Owner information self.owner = self._create_owner_object(gitea_repo.owner) def _create_owner_object(self, gitea_owner) -> Dict[str, Any]: """Create a GitHub-compatible owner object.""" return { 'login': gitea_owner.login, 'id': gitea_owner.id, 'avatar_url': gitea_owner.avatar_url, 'type': 'User' if not getattr(gitea_owner, 'is_organization', False) else 'Organization' } def get_pull(self, number: int) -> PullRequest: """ Get a pull request by number. Args: number: Pull request number Returns: PullRequest object """ gitea_pr = self._repo.get_pull(number) return PullRequest(gitea_pr, self._repo, self._gitea) def get_pulls(self, state: str = 'open', sort: str = 'created', direction: str = 'desc', base: Optional[str] = None, head: Optional[str] = None) -> List[PullRequest]: """ Get pull requests for the repository. Args: state: State of PRs to return ('open', 'closed', 'all') sort: Sort field ('created', 'updated', 'popularity') direction: Sort direction ('asc', 'desc') base: Filter by base branch head: Filter by head branch Returns: List of PullRequest objects """ # Map GitHub state to Gitea state gitea_state = state if state == 'all': gitea_state = None # Gitea uses None for all gitea_prs = self._repo.get_pulls(state=gitea_state) # Convert to PullRequest objects pulls = [PullRequest(pr, self._repo, self._gitea) for pr in gitea_prs] # Apply additional filters if needed if base: pulls = [pr for pr in pulls if pr.base.ref == base] if head: pulls = [pr for pr in pulls if pr.head.ref == head] return pulls def create_pull(self, title: str, body: str, head: str, base: str, draft: bool = False, **kwargs) -> PullRequest: """ Create a new pull request. Args: title: PR title body: PR description head: Source branch base: Target branch draft: Whether PR is a draft **kwargs: Additional parameters Returns: PullRequest object """ # Create PR using Gitea API gitea_pr = self._repo.create_pull_request( title=title, body=body, head=head, base=base # Note: Gitea might not support draft PRs ) return PullRequest(gitea_pr, self._repo, self._gitea) def get_contents(self, path: str, ref: Optional[str] = None) -> Any: """ Get file contents from repository. Args: path: File path ref: Git ref (branch, tag, commit SHA) Returns: File contents object """ # Get file contents using Gitea API contents = self._repo.get_file_contents(path, ref=ref) # Create GitHub-compatible response return { 'name': contents.name, 'path': contents.path, 'sha': contents.sha, 'size': contents.size, 'type': contents.type, 'content': contents.content, 'encoding': contents.encoding, 'download_url': contents.download_url, 'html_url': contents.html_url } def get_branches(self) -> List[Dict[str, Any]]: """ Get all branches in the repository. Returns: List of branch objects """ gitea_branches = self._repo.get_branches() branches = [] for branch in gitea_branches: branches.append({ 'name': branch.name, 'commit': { 'sha': branch.commit.id, 'url': branch.commit.url }, 'protected': branch.protected }) return branches def get_branch(self, branch: str) -> Dict[str, Any]: """ Get a specific branch. Args: branch: Branch name Returns: Branch object """ gitea_branch = self._repo.get_branch(branch) return { 'name': gitea_branch.name, 'commit': { 'sha': gitea_branch.commit.id, 'url': gitea_branch.commit.url }, 'protected': gitea_branch.protected } def create_fork(self, organization: Optional[str] = None) -> 'Repository': """ Create a fork of the repository. Args: organization: Organization to fork to (optional) Returns: Repository object for the fork """ gitea_fork = self._repo.create_fork(organization=organization) return Repository(gitea_fork, self._gitea) def get_commits(self, sha: Optional[str] = None, path: Optional[str] = None, since: Optional[str] = None, until: Optional[str] = None) -> List[Dict[str, Any]]: """ Get commits from the repository. Args: sha: Starting commit SHA or branch path: Only commits containing this path since: Only commits after this date until: Only commits before this date Returns: List of commit objects """ # Note: Gitea API might have different parameters gitea_commits = self._repo.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 }, 'committer': { 'name': commit.commit.committer.name, 'email': commit.commit.committer.email, 'date': commit.commit.committer.date } }, 'html_url': commit.html_url, 'author': commit.author, 'committer': commit.committer }) return commits def get_commit(self, sha: str) -> Dict[str, Any]: """ Get a specific commit. Args: sha: Commit SHA Returns: Commit object """ gitea_commit = self._repo.get_commit(sha) return { 'sha': gitea_commit.sha, 'commit': { 'message': gitea_commit.commit.message, 'author': { 'name': gitea_commit.commit.author.name, 'email': gitea_commit.commit.author.email, 'date': gitea_commit.commit.author.date }, 'committer': { 'name': gitea_commit.commit.committer.name, 'email': gitea_commit.commit.committer.email, 'date': gitea_commit.commit.committer.date } }, 'html_url': gitea_commit.html_url, 'author': gitea_commit.author, 'committer': gitea_commit.committer, 'stats': gitea_commit.stats, 'files': gitea_commit.files }