Coverage for src/prosemark/templates/ports/template_repository_port.py: 100%
23 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-10-01 00:05 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-10-01 00:05 +0000
1"""Template Repository Port Contract.
3Defines the interface for template storage and retrieval operations.
4"""
6from abc import ABC, abstractmethod
7from pathlib import Path
9from prosemark.templates.domain.entities.template import Template
10from prosemark.templates.domain.entities.template_directory import TemplateDirectory
13class TemplateRepositoryPort(ABC):
14 """Port for template storage and retrieval operations."""
16 @abstractmethod
17 def find_template_by_name(self, name: str, search_path: Path) -> Template | None:
18 """Find a template by name in the given search path.
20 Args:
21 name: Template name (without .md extension)
22 search_path: Directory path to search for templates
24 Returns:
25 Template instance if found, None otherwise
27 Raises:
28 TemplateDirectoryNotFoundError: If search_path does not exist
30 """
32 @abstractmethod
33 def find_template_directory(self, name: str, search_path: Path) -> TemplateDirectory | None:
34 """Find a template directory by name.
36 Args:
37 name: Directory name
38 search_path: Parent directory to search in
40 Returns:
41 TemplateDirectory instance if found, None otherwise
43 Raises:
44 TemplateDirectoryNotFoundError: If search_path does not exist
46 """
48 @abstractmethod
49 def get_templates_root(self) -> Path:
50 """Get the root directory for templates.
52 Returns:
53 Path to templates root directory
55 """
56 raise NotImplementedError # pragma: no cover
58 @abstractmethod
59 def get_template(self, template_name: str) -> Template:
60 """Load a single template by name from the templates root.
62 Args:
63 template_name: Name of the template (without .md extension)
65 Returns:
66 Template instance
68 Raises:
69 TemplateNotFoundError: If template doesn't exist
71 """
73 @abstractmethod
74 def get_template_directory(self, directory_name: str) -> TemplateDirectory:
75 """Load a template directory by name from the templates root.
77 Args:
78 directory_name: Name of the template directory
80 Returns:
81 TemplateDirectory instance
83 Raises:
84 TemplateDirectoryNotFoundError: If directory doesn't exist
86 """
88 @abstractmethod
89 def list_templates(self, search_path: Path) -> list[Template]:
90 """List all individual templates in the search path.
92 Args:
93 search_path: Directory path to search for templates
95 Returns:
96 List of Template instances (excludes directory templates)
98 Raises:
99 TemplateDirectoryNotFoundError: If search_path does not exist
101 """
103 @abstractmethod
104 def list_template_directories(self, search_path: Path) -> list[TemplateDirectory]:
105 """List all template directories in the search path.
107 Args:
108 search_path: Directory path to search for template directories
110 Returns:
111 List of TemplateDirectory instances
113 Raises:
114 TemplateDirectoryNotFoundError: If search_path does not exist
116 """
118 @abstractmethod
119 def load_template_content(self, template_path: Path) -> str:
120 """Load raw content from a template file.
122 Args:
123 template_path: Absolute path to template file
125 Returns:
126 Raw template content as string
128 Raises:
129 TemplateNotFoundError: If template file does not exist
130 FilePermissionError: If template file is not readable
132 """
134 @abstractmethod
135 def validate_template_path(self, path: Path) -> bool:
136 """Validate that a path points to a valid template location.
138 Args:
139 path: Path to validate
141 Returns:
142 True if path is valid for template operations
144 """