smith.infrastructure.metadata

Metadata adapter — persist and load template source info in smith.infrastructure.gitignore.

 1"""Metadata adapter — persist and load template source info in .gitignore."""
 2
 3from pathlib import Path
 4
 5from smith.domain.value_objects import TemplateSource
 6from smith.infrastructure.gitignore import START_MARKER, GitignoreManager
 7
 8
 9class SectionMetadata:
10    """Store and retrieve template source metadata inside the gitignore section."""
11
12    def __init__(self, project_dir: Path) -> None:
13        """Initialise with the project root directory."""
14        self._gitignore = GitignoreManager(project_dir)
15
16    def save_source(self, source: TemplateSource) -> None:
17        """Write the source identifier into the smith-managed section header."""
18        lines = self._gitignore._read_lines()
19        bounds = self._gitignore._find_section_bounds(lines)
20        if bounds is None:
21            return
22        start = bounds[0]
23        header = f"{START_MARKER} source:{source.kind}:{source.location}\n"
24        lines[start] = header
25        self._gitignore._write_lines(lines)
26
27    def load_source(self) -> TemplateSource | None:
28        """Read the source identifier from the smith-managed section header."""
29        lines = self._gitignore._read_lines()
30        bounds = self._gitignore._find_section_bounds(lines)
31        if bounds is None:
32            return None
33        header = lines[bounds[0]].strip()
34        for part in header.split():
35            if part.startswith("source:"):
36                value = part[len("source:") :]
37                if ":" in value:
38                    kind, location = value.split(":", 1)
39                    return TemplateSource(kind=kind, location=location)  # type: ignore[arg-type]
40        return None
class SectionMetadata:
10class SectionMetadata:
11    """Store and retrieve template source metadata inside the gitignore section."""
12
13    def __init__(self, project_dir: Path) -> None:
14        """Initialise with the project root directory."""
15        self._gitignore = GitignoreManager(project_dir)
16
17    def save_source(self, source: TemplateSource) -> None:
18        """Write the source identifier into the smith-managed section header."""
19        lines = self._gitignore._read_lines()
20        bounds = self._gitignore._find_section_bounds(lines)
21        if bounds is None:
22            return
23        start = bounds[0]
24        header = f"{START_MARKER} source:{source.kind}:{source.location}\n"
25        lines[start] = header
26        self._gitignore._write_lines(lines)
27
28    def load_source(self) -> TemplateSource | None:
29        """Read the source identifier from the smith-managed section header."""
30        lines = self._gitignore._read_lines()
31        bounds = self._gitignore._find_section_bounds(lines)
32        if bounds is None:
33            return None
34        header = lines[bounds[0]].strip()
35        for part in header.split():
36            if part.startswith("source:"):
37                value = part[len("source:") :]
38                if ":" in value:
39                    kind, location = value.split(":", 1)
40                    return TemplateSource(kind=kind, location=location)  # type: ignore[arg-type]
41        return None

Store and retrieve template source metadata inside the gitignore section.

SectionMetadata(project_dir: pathlib._local.Path)
13    def __init__(self, project_dir: Path) -> None:
14        """Initialise with the project root directory."""
15        self._gitignore = GitignoreManager(project_dir)

Initialise with the project root directory.

def save_source(self, source: smith.domain.value_objects.TemplateSource) -> None:
17    def save_source(self, source: TemplateSource) -> None:
18        """Write the source identifier into the smith-managed section header."""
19        lines = self._gitignore._read_lines()
20        bounds = self._gitignore._find_section_bounds(lines)
21        if bounds is None:
22            return
23        start = bounds[0]
24        header = f"{START_MARKER} source:{source.kind}:{source.location}\n"
25        lines[start] = header
26        self._gitignore._write_lines(lines)

Write the source identifier into the smith-managed section header.

def load_source(self) -> smith.domain.value_objects.TemplateSource | None:
28    def load_source(self) -> TemplateSource | None:
29        """Read the source identifier from the smith-managed section header."""
30        lines = self._gitignore._read_lines()
31        bounds = self._gitignore._find_section_bounds(lines)
32        if bounds is None:
33            return None
34        header = lines[bounds[0]].strip()
35        for part in header.split():
36            if part.startswith("source:"):
37                value = part[len("source:") :]
38                if ":" in value:
39                    kind, location = value.split(":", 1)
40                    return TemplateSource(kind=kind, location=location)  # type: ignore[arg-type]
41        return None

Read the source identifier from the smith-managed section header.