generated from coulomb/repo-seed
Milestone 2’s core deterministic scanner path
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -13,6 +14,48 @@ class Repository:
|
||||
status: str
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RepositorySnapshot:
|
||||
id: int
|
||||
repository_id: int
|
||||
commit_hash: str
|
||||
branch: str
|
||||
source_path: str
|
||||
file_count: int
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AnalysisRun:
|
||||
id: int
|
||||
repository_id: int
|
||||
snapshot_id: int | None
|
||||
status: str
|
||||
started_at: str
|
||||
completed_at: str | None
|
||||
error_message: str | None
|
||||
scanner_version: str
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ObservedFact:
|
||||
id: int
|
||||
repository_id: int
|
||||
analysis_run_id: int
|
||||
snapshot_id: int | None
|
||||
kind: str
|
||||
path: str
|
||||
name: str
|
||||
value: str
|
||||
metadata: dict[str, Any]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ScanSummary:
|
||||
analysis_run: AnalysisRun
|
||||
snapshot: RepositorySnapshot | None
|
||||
facts: list[ObservedFact]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Evidence:
|
||||
id: int
|
||||
|
||||
@@ -2,7 +2,15 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from repo_registry.core.models import Repository, RepositoryAbilityMap, SearchResult
|
||||
from repo_registry.core.models import (
|
||||
AnalysisRun,
|
||||
ObservedFact,
|
||||
Repository,
|
||||
RepositoryAbilityMap,
|
||||
ScanSummary,
|
||||
SearchResult,
|
||||
)
|
||||
from repo_registry.repo_scanning.scanner import DeterministicScanner
|
||||
from repo_registry.storage.sqlite import RegistryStore
|
||||
|
||||
|
||||
@@ -11,6 +19,7 @@ class RegistryService:
|
||||
|
||||
def __init__(self, store: RegistryStore) -> None:
|
||||
self.store = store
|
||||
self.scanner = DeterministicScanner()
|
||||
|
||||
def register_repository(
|
||||
self,
|
||||
@@ -33,6 +42,48 @@ class RegistryService:
|
||||
def get_repository(self, repository_id: int) -> Repository:
|
||||
return self.store.get_repository(repository_id)
|
||||
|
||||
def analyze_repository(
|
||||
self,
|
||||
repository_id: int,
|
||||
*,
|
||||
source_path: str | None = None,
|
||||
) -> ScanSummary:
|
||||
repository = self.store.get_repository(repository_id)
|
||||
run = self.store.create_analysis_run(repository_id)
|
||||
self.store.update_repository_status(repository_id, "analyzing")
|
||||
try:
|
||||
scan_result = self.scanner.scan(source_path or repository.url)
|
||||
except Exception as exc:
|
||||
failed_run = self.store.fail_analysis_run(repository_id, run.id, str(exc))
|
||||
return ScanSummary(analysis_run=failed_run, snapshot=None, facts=[])
|
||||
|
||||
completed_run = self.store.complete_analysis_run(
|
||||
repository_id,
|
||||
run.id,
|
||||
scan_result,
|
||||
)
|
||||
snapshot = (
|
||||
self.store.get_snapshot(completed_run.snapshot_id)
|
||||
if completed_run.snapshot_id is not None
|
||||
else None
|
||||
)
|
||||
facts = self.store.list_observed_facts(repository_id, completed_run.id)
|
||||
return ScanSummary(
|
||||
analysis_run=completed_run,
|
||||
snapshot=snapshot,
|
||||
facts=facts,
|
||||
)
|
||||
|
||||
def list_analysis_runs(self, repository_id: int) -> list[AnalysisRun]:
|
||||
return self.store.list_analysis_runs(repository_id)
|
||||
|
||||
def list_observed_facts(
|
||||
self,
|
||||
repository_id: int,
|
||||
analysis_run_id: int | None = None,
|
||||
) -> list[ObservedFact]:
|
||||
return self.store.list_observed_facts(repository_id, analysis_run_id)
|
||||
|
||||
def add_ability(
|
||||
self,
|
||||
repository_id: int,
|
||||
|
||||
Reference in New Issue
Block a user