Coverage for src/somesy/fortran/writer.py: 87%

70 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-04-30 09:42 +0000

1"""Fortran writer.""" 

2import logging 

3from pathlib import Path 

4from typing import Any, List, Optional 

5 

6import tomlkit 

7from rich.pretty import pretty_repr 

8 

9from somesy.core.models import Person, ProjectMetadata 

10from somesy.core.writer import FieldKeyMapping, IgnoreKey, ProjectMetadataWriter 

11 

12from .models import FortranConfig 

13 

14logger = logging.getLogger("somesy") 

15 

16 

17class Fortran(ProjectMetadataWriter): 

18 """Fortran config file handler parsed from fpm.toml.""" 

19 

20 def __init__(self, path: Path): 

21 """Fortran config file handler parsed from fpm.toml. 

22 

23 See [somesy.core.writer.ProjectMetadataWriter.__init__][]. 

24 """ 

25 mappings: FieldKeyMapping = { 

26 "authors": ["author"], 

27 "maintainers": ["maintainer"], 

28 "documentation": IgnoreKey(), 

29 } 

30 super().__init__(path, create_if_not_exists=False, direct_mappings=mappings) 

31 

32 @property 

33 def authors(self): 

34 """Return the only author of the fpm.toml file as list.""" 

35 authors = [] 

36 try: 

37 self._to_person(self._get_property(self._get_key("authors"))) 

38 authors = [self._get_property(self._get_key("authors"))] 

39 except ValueError: 

40 logger.warning("Cannot convert authors to Person object.") 

41 return authors 

42 

43 @authors.setter 

44 def authors(self, authors: List[Person]) -> None: 

45 """Set the authors of the project.""" 

46 authors = self._from_person(authors[0]) 

47 self._set_property(self._get_key("authors"), authors) 

48 

49 @property 

50 def maintainers(self): 

51 """Return the only author of the fpm.toml file as list.""" 

52 maintainers = self._get_property(self._get_key("maintainers")) 

53 if maintainers: 

54 return [self._get_property(self._get_key("maintainers"))] 

55 return [] 

56 

57 @maintainers.setter 

58 def maintainers(self, maintainers: List[Person]) -> None: 

59 """Set the maintainers of the project.""" 

60 maintainers = self._from_person(maintainers[0]) 

61 self._set_property(self._get_key("maintainers"), maintainers) 

62 

63 def _load(self) -> None: 

64 """Load fpm.toml file.""" 

65 with open(self.path) as f: 

66 self._data = tomlkit.load(f) 

67 

68 def _validate(self) -> None: 

69 """Validate poetry config using pydantic class. 

70 

71 In order to preserve toml comments and structure, tomlkit library is used. 

72 Pydantic class only used for validation. 

73 """ 

74 config = dict(self._get_property([])) 

75 logger.debug( 

76 f"Validating config using {FortranConfig.__name__}: {pretty_repr(config)}" 

77 ) 

78 FortranConfig(**config) 

79 

80 def save(self, path: Optional[Path] = None) -> None: 

81 """Save the fpm file.""" 

82 path = path or self.path 

83 with open(path, "w") as f: 

84 tomlkit.dump(self._data, f) 

85 

86 @staticmethod 

87 def _from_person(person: Person): 

88 """Convert project metadata person object to poetry string for person format "full name <email>.""" 

89 return person.to_name_email_string() 

90 

91 @staticmethod 

92 def _to_person(person_obj: Any) -> Person: 

93 """Cannot convert from free string to person object.""" 

94 try: 

95 return Person.from_name_email_string(person_obj) 

96 except ValueError: 

97 logger.warning(f"Cannot convert {person_obj} to Person object.") 

98 return None 

99 

100 def sync(self, metadata: ProjectMetadata) -> None: 

101 """Sync output file with other metadata files.""" 

102 self.name = metadata.name 

103 self.description = metadata.description 

104 

105 if metadata.version: 

106 self.version = metadata.version 

107 

108 if metadata.keywords: 

109 self.keywords = metadata.keywords 

110 

111 self.authors = metadata.authors() 

112 maintainers = metadata.maintainers() 

113 

114 # set if not empty 

115 if maintainers: 

116 # only one maintainer is allowed 

117 self.maintainers = maintainers 

118 

119 self.license = metadata.license.value 

120 

121 self.homepage = str(metadata.homepage) if metadata.homepage else None