Coverage for src/somesy/mkdocs/writer.py: 100%
53 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-04-30 09:42 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2024-04-30 09:42 +0000
1"""Project documentation with Markdown (MkDocs) parser and saver."""
2import logging
3from pathlib import Path
4from typing import List, Optional
6from rich.pretty import pretty_repr
7from ruamel.yaml import YAML
9from somesy.core.models import Person, ProjectMetadata
10from somesy.core.writer import FieldKeyMapping, IgnoreKey, ProjectMetadataWriter
11from somesy.mkdocs.models import MkDocsConfig
13logger = logging.getLogger("somesy")
16class MkDocs(ProjectMetadataWriter):
17 """Project documentation with Markdown (MkDocs) parser and saver."""
19 def __init__(self, path: Path, create_if_not_exists: bool = False):
20 """Project documentation with Markdown (MkDocs) parser.
22 See [somesy.core.writer.ProjectMetadataWriter.__init__][].
23 """
24 self._yaml = YAML()
25 self._yaml.preserve_quotes = True
27 mappings: FieldKeyMapping = {
28 "name": ["site_name"],
29 "description": ["site_description"],
30 "homepage": ["site_url"],
31 "repository": ["repo_url"],
32 "authors": ["site_author"],
33 "documentation": IgnoreKey(),
34 "version": IgnoreKey(),
35 "maintainers": IgnoreKey(),
36 "license": IgnoreKey(),
37 "keywords": IgnoreKey(),
38 }
39 super().__init__(
40 path, create_if_not_exists=create_if_not_exists, direct_mappings=mappings
41 )
43 def _load(self):
44 """Load the MkDocs file."""
45 with open(self.path) as f:
46 self._data = self._yaml.load(f)
48 def _validate(self):
49 """Validate the MkDocs file."""
50 config = dict(self._get_property([]))
51 logger.debug(
52 f"Validating config using {MkDocsConfig.__name__}: {pretty_repr(config)}"
53 )
54 MkDocsConfig(**config)
56 def save(self, path: Optional[Path] = None) -> None:
57 """Save the MkDocs object to a file."""
58 path = path or self.path
59 self._yaml.dump(self._data, path)
61 @property
62 def authors(self):
63 """Return the only author from the source file as list."""
64 authors = []
65 try:
66 self._to_person(self._get_property(self._get_key("authors")))
67 authors = [self._get_property(self._get_key("authors"))]
68 except AttributeError:
69 logger.warning("Cannot convert authors to Person object.")
70 return authors
72 @authors.setter
73 def authors(self, authors: List[Person]) -> None:
74 """Set the authors of the project."""
75 authors = self._from_person(authors[0])
76 self._set_property(self._get_key("authors"), authors)
78 @staticmethod
79 def _from_person(person: Person):
80 """MkDocs Person is a string with full name."""
81 return person.to_name_email_string()
83 @staticmethod
84 def _to_person(person: str):
85 """MkDocs Person is a string with full name."""
86 return Person.from_name_email_string(person)
88 def sync(self, metadata: ProjectMetadata) -> None:
89 """Sync the MkDocs object with the ProjectMetadata object."""
90 self.name = metadata.name
91 self.description = metadata.description
92 # no author merge since it is a free text field
93 self.authors = metadata.authors()
94 if metadata.homepage:
95 self.homepage = str(metadata.homepage)
96 if metadata.repository:
97 self.repository = str(metadata.repository)
98 self.repo_name = metadata.repository.path