Coverage for src/somesy/fortran/writer.py: 87%
70 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-29 07:42 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-29 07:42 +0000
1"""Fortran writer."""
3import logging
4from pathlib import Path
5from typing import Any, List, Optional
7import tomlkit
8from rich.pretty import pretty_repr
10from somesy.core.models import Person, ProjectMetadata
11from somesy.core.writer import FieldKeyMapping, IgnoreKey, ProjectMetadataWriter
13from .models import FortranConfig
15logger = logging.getLogger("somesy")
18class Fortran(ProjectMetadataWriter):
19 """Fortran config file handler parsed from fpm.toml."""
21 def __init__(self, path: Path):
22 """Fortran config file handler parsed from fpm.toml.
24 See [somesy.core.writer.ProjectMetadataWriter.__init__][].
25 """
26 mappings: FieldKeyMapping = {
27 "authors": ["author"],
28 "maintainers": ["maintainer"],
29 "documentation": IgnoreKey(),
30 }
31 super().__init__(path, create_if_not_exists=False, direct_mappings=mappings)
33 @property
34 def authors(self):
35 """Return the only author of the fpm.toml file as list."""
36 authors = []
37 try:
38 self._to_person(self._get_property(self._get_key("authors")))
39 authors = [self._get_property(self._get_key("authors"))]
40 except ValueError:
41 logger.warning("Cannot convert authors to Person object.")
42 return authors
44 @authors.setter
45 def authors(self, authors: List[Person]) -> None:
46 """Set the authors of the project."""
47 authors = self._from_person(authors[0])
48 self._set_property(self._get_key("authors"), authors)
50 @property
51 def maintainers(self):
52 """Return the only author of the fpm.toml file as list."""
53 maintainers = self._get_property(self._get_key("maintainers"))
54 if maintainers:
55 return [self._get_property(self._get_key("maintainers"))]
56 return []
58 @maintainers.setter
59 def maintainers(self, maintainers: List[Person]) -> None:
60 """Set the maintainers of the project."""
61 maintainers = self._from_person(maintainers[0])
62 self._set_property(self._get_key("maintainers"), maintainers)
64 def _load(self) -> None:
65 """Load fpm.toml file."""
66 with open(self.path) as f:
67 self._data = tomlkit.load(f)
69 def _validate(self) -> None:
70 """Validate poetry config using pydantic class.
72 In order to preserve toml comments and structure, tomlkit library is used.
73 Pydantic class only used for validation.
74 """
75 config = dict(self._get_property([]))
76 logger.debug(
77 f"Validating config using {FortranConfig.__name__}: {pretty_repr(config)}"
78 )
79 FortranConfig(**config)
81 def save(self, path: Optional[Path] = None) -> None:
82 """Save the fpm file."""
83 path = path or self.path
84 with open(path, "w") as f:
85 tomlkit.dump(self._data, f)
87 @staticmethod
88 def _from_person(person: Person):
89 """Convert project metadata person object to poetry string for person format "full name <email>."""
90 return person.to_name_email_string()
92 @staticmethod
93 def _to_person(person_obj: Any) -> Optional[Person]:
94 """Cannot convert from free string to person object."""
95 try:
96 return Person.from_name_email_string(person_obj)
97 except (ValueError, AttributeError):
98 logger.warning(f"Cannot convert {person_obj} to Person object.")
99 return None
101 def sync(self, metadata: ProjectMetadata) -> None:
102 """Sync output file with other metadata files."""
103 self.name = metadata.name
104 self.description = metadata.description
106 if metadata.version:
107 self.version = metadata.version
109 if metadata.keywords:
110 self.keywords = metadata.keywords
112 self.authors = metadata.authors()
113 maintainers = metadata.maintainers()
115 # set if not empty
116 if maintainers:
117 # only one maintainer is allowed
118 self.maintainers = maintainers
120 self.license = metadata.license.value
122 self.homepage = str(metadata.homepage) if metadata.homepage else None