58 lines
1.6 KiB
Python
58 lines
1.6 KiB
Python
"""Abstract Git (repository / source-control) connector interface."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from typing import Protocol, AsyncIterator, Optional, Sequence
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CommitInfo:
|
|
sha: str
|
|
message: str
|
|
author_email: str
|
|
author_name: str
|
|
authored_at: datetime
|
|
branch: Optional[str] = None
|
|
files_changed: Sequence[str] = ()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PullRequestInfo:
|
|
number: int
|
|
title: str
|
|
state: str # open | closed | merged
|
|
branch: str
|
|
target_branch: str
|
|
author: str
|
|
created_at: datetime
|
|
merged_at: Optional[datetime] = None
|
|
description: Optional[str] = None
|
|
commit_shas: Sequence[str] = ()
|
|
labels: Sequence[str] = ()
|
|
|
|
|
|
class GitConnector(Protocol):
|
|
"""Any Git-hosting provider: GitHub, GitLab, Bitbucket, local Gitea..."""
|
|
|
|
async def list_commits(
|
|
self, repo_ref: str, *, branch: Optional[str] = None, since: Optional[datetime] = None
|
|
) -> AsyncIterator[CommitInfo]: ...
|
|
|
|
async def get_commit(self, repo_ref: str, sha: str) -> Optional[CommitInfo]: ...
|
|
|
|
async def list_pull_requests(
|
|
self, repo_ref: str, *, state: str = "open"
|
|
) -> AsyncIterator[PullRequestInfo]: ...
|
|
|
|
async def get_pull_request(self, repo_ref: str, number: int) -> Optional[PullRequestInfo]: ...
|
|
|
|
async def index_repository(self, repo_ref: str) -> None:
|
|
"""Trigger a full sync (artifacts + relationships) for a repo.
|
|
|
|
Implementation must emit events; it must NOT mutate Core data
|
|
directly.
|
|
"""
|
|
...
|