Coverage for src/somesy/fortran/writer.py: 81%
75 statements
« prev ^ index » next coverage.py v7.6.0, created at 2025-03-10 14:56 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2025-03-10 14:56 +0000
1"""Fortran writer."""
3import logging
4from pathlib import Path
5from typing import List, Optional, Union
7import tomlkit
8from rich.pretty import pretty_repr
10from somesy.core.models import Entity, 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__(
22 self,
23 path: Path,
24 pass_validation: Optional[bool] = False,
25 ):
26 """Fortran config file handler parsed from fpm.toml.
28 See [somesy.core.writer.ProjectMetadataWriter.__init__][].
29 """
30 mappings: FieldKeyMapping = {
31 "authors": ["author"],
32 "maintainers": ["maintainer"],
33 "documentation": IgnoreKey(),
34 }
35 super().__init__(
36 path,
37 create_if_not_exists=False,
38 direct_mappings=mappings,
39 pass_validation=pass_validation,
40 )
42 @property
43 def authors(self):
44 """Return the only author of the fpm.toml file as list."""
45 authors = []
46 try:
47 self._to_person(self._get_property(self._get_key("authors")))
48 authors = [self._get_property(self._get_key("authors"))]
49 except ValueError:
50 logger.warning("Cannot convert authors to Person object.")
51 return authors
53 @authors.setter
54 def authors(self, authors: List[Union[Person, Entity]]) -> None:
55 """Set the authors of the project."""
56 self._set_property(self._get_key("authors"), self._from_person(authors[0]))
58 @property
59 def maintainers(self):
60 """Return the only author of the fpm.toml file as list."""
61 maintainers = self._get_property(self._get_key("maintainers"))
62 if maintainers:
63 return [self._get_property(self._get_key("maintainers"))]
64 return []
66 @maintainers.setter
67 def maintainers(self, maintainers: List[Union[Person, Entity]]) -> None:
68 """Set the maintainers of the project."""
69 maintainers = self._from_person(maintainers[0])
70 self._set_property(self._get_key("maintainers"), maintainers)
72 def _load(self) -> None:
73 """Load fpm.toml file."""
74 with open(self.path) as f:
75 self._data = tomlkit.load(f)
77 def _validate(self) -> None:
78 """Validate poetry config using pydantic class.
80 In order to preserve toml comments and structure, tomlkit library is used.
81 Pydantic class only used for validation.
82 """
83 if self.pass_validation:
84 return
85 config = dict(self._get_property([]))
86 logger.debug(
87 f"Validating config using {FortranConfig.__name__}: {pretty_repr(config)}"
88 )
89 FortranConfig(**config)
91 def save(self, path: Optional[Path] = None) -> None:
92 """Save the fpm file."""
93 path = path or self.path
94 with open(path, "w") as f:
95 tomlkit.dump(self._data, f)
97 @staticmethod
98 def _from_person(person: Union[Person, Entity]):
99 """Convert project metadata person/entity object to poetry string for person format "full name <email>."""
100 return person.to_name_email_string()
102 @staticmethod
103 def _to_person(person: str) -> Optional[Union[Person, Entity]]:
104 """Convert from free string to person or entity object."""
105 try:
106 return Person.from_name_email_string(person)
107 except (ValueError, AttributeError):
108 logger.info(f"Cannot convert {person} to Person object, trying Entity.")
110 try:
111 return Entity.from_name_email_string(person)
112 except (ValueError, AttributeError):
113 logger.warning(f"Cannot convert {person} to Entity.")
114 return None
116 def sync(self, metadata: ProjectMetadata) -> None:
117 """Sync output file with other metadata files."""
118 self.name = metadata.name
119 self.description = metadata.description
121 if metadata.version:
122 self.version = metadata.version
124 if metadata.keywords:
125 self.keywords = metadata.keywords
127 self.authors = metadata.authors()
128 maintainers = metadata.maintainers()
130 # set if not empty
131 if maintainers:
132 # only one maintainer is allowed
133 self.maintainers = maintainers
135 self.license = metadata.license.value
137 self.homepage = str(metadata.homepage) if metadata.homepage else None