61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
"""gitimport - Ladybug graph writes for Commit/File/Person (no git binary).
|
|
|
|
Commit records come from bin/git/import.go (go-git). This module only MERGEs
|
|
the version graph File-[:HAS_VERSION]->Commit-[:AUTHORED]->Person.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class Commit:
|
|
sha: str
|
|
author: str
|
|
email: str
|
|
date: str
|
|
subject: str
|
|
files: list[str] = field(default_factory=list)
|
|
|
|
|
|
GIT_SCHEMA = (
|
|
"CREATE NODE TABLE IF NOT EXISTS Commit (id STRING, repo STRING, subject STRING, "
|
|
"author STRING, email STRING, date STRING, PRIMARY KEY(id))",
|
|
"CREATE NODE TABLE IF NOT EXISTS Person (id STRING, name STRING, email STRING, PRIMARY KEY(id))",
|
|
"CREATE REL TABLE IF NOT EXISTS HAS_VERSION (FROM File TO Commit)",
|
|
"CREATE REL TABLE IF NOT EXISTS AUTHORED (FROM Commit TO Person)",
|
|
)
|
|
|
|
|
|
def ensure_git_schema(conn) -> None:
|
|
for stmt in GIT_SCHEMA:
|
|
conn.execute(stmt)
|
|
|
|
|
|
def index_commits(conn, commits: list[Commit], repo: str) -> int:
|
|
"""Write Commit/File/Person nodes + edges, one per commit (idempotent by sha)."""
|
|
ensure_git_schema(conn)
|
|
for c in commits:
|
|
conn.execute(
|
|
"MERGE (c:Commit {id:$sha}) SET c.repo=$repo, c.subject=$subject, "
|
|
"c.author=$author, c.email=$email, c.date=$date",
|
|
parameters={"sha": c.sha, "repo": repo, "subject": c.subject,
|
|
"author": c.author, "email": c.email, "date": c.date},
|
|
)
|
|
conn.execute(
|
|
"MERGE (p:Person {id:$email}) SET p.name=$name, p.email=$email",
|
|
parameters={"email": c.email, "name": c.author},
|
|
)
|
|
conn.execute("MATCH (c:Commit {id:$sha}), (p:Person {id:$email}) "
|
|
"MERGE (c)-[:AUTHORED]->(p)",
|
|
parameters={"sha": c.sha, "email": c.email})
|
|
for path in c.files:
|
|
conn.execute(
|
|
"MERGE (f:File {id:$fid}) SET f.path=$path, f.repo=$repo",
|
|
parameters={"fid": f"{repo}:{path}", "path": path, "repo": repo},
|
|
)
|
|
conn.execute("MATCH (f:File {id:$fid}), (c:Commit {id:$sha}) "
|
|
"MERGE (f)-[:HAS_VERSION]->(c)",
|
|
parameters={"fid": f"{repo}:{path}", "sha": c.sha})
|
|
return len(commits)
|