Coverage for src / rhiza / models / lock.py: 100%
28 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-02 07:04 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-02 07:04 +0000
1"""Lock model for Rhiza configuration."""
3from dataclasses import dataclass, field
4from typing import Any
6from rhiza.models._base import YamlSerializable
7from rhiza.models._git_utils import _normalize_to_list
8from rhiza.models.template import GitHost
11@dataclass(frozen=True, kw_only=True)
12class TemplateLock(YamlSerializable):
13 """Represents the structure of .rhiza/template.lock.
15 Attributes:
16 sha: The commit SHA of the last-synced template.
17 repo: The template repository (e.g., "jebel-quant/rhiza").
18 host: The git hosting platform (e.g., "github", "gitlab").
19 ref: The branch or ref that was synced (e.g., "main").
20 include: List of paths included from the template.
21 exclude: List of paths excluded from the template.
22 templates: List of template bundle names.
23 files: List of file paths that were synced.
24 synced_at: ISO 8601 UTC timestamp of when the sync was performed.
25 strategy: The sync strategy used (e.g., "merge", "diff", "materialize").
26 """
28 sha: str
29 repo: str = ""
30 host: GitHost | str = GitHost.GITHUB
31 ref: str = "main"
32 include: list[str] = field(default_factory=list)
33 exclude: list[str] = field(default_factory=list)
34 templates: list[str] = field(default_factory=list)
35 files: list[str] = field(default_factory=list)
36 synced_at: str = ""
37 strategy: str = ""
39 @classmethod
40 def from_config(cls, config: dict[str, Any]) -> "TemplateLock":
41 """Create a TemplateLock instance from a configuration dictionary.
43 Args:
44 config: Dictionary containing lock configuration.
46 Returns:
47 A new TemplateLock instance.
48 """
49 return cls(
50 sha=config.get("sha", ""),
51 repo=config.get("repo", ""),
52 host=config.get("host", GitHost.GITHUB),
53 ref=config.get("ref", "main"),
54 include=_normalize_to_list(config.get("include")),
55 exclude=_normalize_to_list(config.get("exclude")),
56 templates=_normalize_to_list(config.get("templates")),
57 files=_normalize_to_list(config.get("files")),
58 synced_at=config.get("synced_at", ""),
59 strategy=config.get("strategy", ""),
60 )
62 @property
63 def config(self) -> dict[str, Any]:
64 """Return the lock's current state as a configuration dictionary."""
65 config: dict[str, Any] = {
66 "sha": self.sha,
67 "repo": self.repo,
68 "host": str(self.host),
69 "ref": self.ref,
70 "include": self.include,
71 "exclude": self.exclude,
72 "templates": self.templates,
73 "files": self.files,
74 }
75 if self.synced_at:
76 config["synced_at"] = self.synced_at
77 if self.strategy:
78 config["strategy"] = self.strategy
79 return config