Files
Yiqun/gitea-shim/python/models/repository.py

291 lines
9.5 KiB
Python

"""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
}