Coverage for src/qdrant_loader_core/graph/extractor/git.py: 100%
27 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-20 10:12 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-20 10:12 +0000
1from __future__ import annotations
3from typing import TYPE_CHECKING
5if TYPE_CHECKING:
6 from qdrant_loader.core.document import Document
8from qdrant_loader_core.graph.extractor.base_extractor import (
9 BaseEntityExtractor,
10)
11from qdrant_loader_core.graph.models import (
12 CoreNodeLabel,
13 GraphNode,
14 PersonInfo,
15)
18class GitEntityExtractor(BaseEntityExtractor):
19 """
20 Git repository graph extractor.
22 Extracts:
23 - Document node (file)
24 - Person node from last_commit_author
25 - Container node from repository
26 """
28 source_type = "git"
30 @staticmethod
31 def _repository_id(doc: Document) -> str | None:
32 name = doc.metadata.get("repository_name")
33 if not name:
34 return None
35 owner = doc.metadata.get("repository_owner")
36 return f"{owner}/{name}" if owner else name
38 def _project(
39 self,
40 doc: Document,
41 ) -> str | None:
42 return self._repository_id(doc)
44 def _build_document_node(
45 self,
46 doc: Document,
47 project: str | None,
48 ) -> GraphNode:
49 return GraphNode(
50 id=doc.id,
51 label=CoreNodeLabel.DOCUMENT.value,
52 project=project,
53 properties={
54 "title": doc.title,
55 "source_type": self.source_type,
56 },
57 )
59 def _extract_people(
60 self,
61 doc: Document,
62 ) -> list[tuple[PersonInfo, str]]:
63 author = doc.metadata.get("last_commit_author")
65 if not author:
66 return []
68 return [
69 (
70 PersonInfo(
71 id=f"git_user:{author}",
72 display_name=author,
73 ),
74 "last_committer",
75 )
76 ]
78 def _extract_container(
79 self,
80 doc: Document,
81 ) -> GraphNode | None:
82 repo_name = self._repository_id(doc)
84 if not repo_name:
85 return None
87 return GraphNode(
88 id=f"git:{repo_name}",
89 label=CoreNodeLabel.CONTAINER.value,
90 project=repo_name,
91 properties={
92 "kind": "repository",
93 "repository_name": repo_name,
94 "repository_owner": doc.metadata.get("repository_owner"),
95 "repository_url": doc.metadata.get("repository_url"),
96 },
97 )