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

70 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-29 07:50 +0000

1"""Fortran writer.""" 

2 

3import logging 

4from pathlib import Path 

5from typing import Any, List, Optional 

6 

7import tomlkit 

8from rich.pretty import pretty_repr 

9 

10from somesy.core.models import Person, ProjectMetadata 

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

12 

13from .models import FortranConfig 

14 

15logger = logging.getLogger("somesy") 

16 

17 

18class Fortran(ProjectMetadataWriter): 

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

20 

21 def __init__(self, path: Path): 

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

23 

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) 

32 

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 

43 

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) 

49 

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 [] 

57 

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) 

63 

64 def _load(self) -> None: 

65 """Load fpm.toml file.""" 

66 with open(self.path) as f: 

67 self._data = tomlkit.load(f) 

68 

69 def _validate(self) -> None: 

70 """Validate poetry config using pydantic class. 

71 

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) 

80 

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) 

86 

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() 

91 

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 

100 

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 

105 

106 if metadata.version: 

107 self.version = metadata.version 

108 

109 if metadata.keywords: 

110 self.keywords = metadata.keywords 

111 

112 self.authors = metadata.authors() 

113 maintainers = metadata.maintainers() 

114 

115 # set if not empty 

116 if maintainers: 

117 # only one maintainer is allowed 

118 self.maintainers = maintainers 

119 

120 self.license = metadata.license.value 

121 

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