File size: 2,566 Bytes
d557d77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""Repository entity model."""

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from pathlib import Path
from typing import Optional
from uuid import uuid4


class RepositoryStatus(str, Enum):
    """Repository indexing status."""

    PENDING = "pending"
    CLONING = "cloning"
    INDEXING = "indexing"
    READY = "ready"
    ERROR = "error"


@dataclass
class Repository:
    """Represents an indexed GitHub repository."""

    url: str
    branch: str = "main"
    id: str = field(default_factory=lambda: str(uuid4()))
    clone_path: Optional[Path] = None
    indexed_at: Optional[datetime] = None
    chunk_count: int = 0
    status: RepositoryStatus = RepositoryStatus.PENDING
    error_message: Optional[str] = None
    last_commit: Optional[str] = None  # SHA of last indexed commit (for incremental updates)

    @property
    def name(self) -> str:
        """Extract repository name from URL."""
        return self.url.rstrip("/").split("/")[-1].replace(".git", "")

    @property
    def owner(self) -> str:
        """Extract repository owner from URL."""
        parts = self.url.rstrip("/").split("/")
        return parts[-2] if len(parts) >= 2 else ""

    @property
    def full_name(self) -> str:
        """Get owner/repo format."""
        return f"{self.owner}/{self.name}"

    def to_dict(self) -> dict:
        """Convert to dictionary for serialization."""
        return {
            "id": self.id,
            "url": self.url,
            "branch": self.branch,
            "clone_path": str(self.clone_path) if self.clone_path else None,
            "indexed_at": self.indexed_at.isoformat() if self.indexed_at else None,
            "chunk_count": self.chunk_count,
            "status": self.status.value,
            "error_message": self.error_message,
            "last_commit": self.last_commit,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "Repository":
        """Create from dictionary."""
        return cls(
            id=data["id"],
            url=data["url"],
            branch=data.get("branch", "main"),
            clone_path=Path(data["clone_path"]) if data.get("clone_path") else None,
            indexed_at=datetime.fromisoformat(data["indexed_at"])
            if data.get("indexed_at")
            else None,
            chunk_count=data.get("chunk_count", 0),
            status=RepositoryStatus(data.get("status", "pending")),
            error_message=data.get("error_message"),
            last_commit=data.get("last_commit"),
        )