Coverage for r11k/forge.py: 100%

10 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-13 23:29 +0100

1""" 

2Python instances of all objects returned by the Puppet Forge API. 

3 

4This code could have been generated from their OpenAPI specification, 

5but the Python tools for it doesn't feel mature enough. Due to that 

6the names below are a bit arbitrary. 

7 

8Full documentation about each field can be found at 

9https://forgeapi.puppet.com/ 

10""" 

11 

12from typing import ( 

13 Any, 

14 Literal, 

15 Optional, 

16 TypedDict, 

17 Union, 

18) 

19from datetime import datetime 

20from semver import VersionInfo 

21from r11k.puppet import PuppetMetadata 

22 

23 

24def _parse_date(date: str) -> datetime: 

25 """Parse date from the format puppet forge uses (almost ISO8601).""" 

26 return datetime.strptime(date, "%Y-%m-%d %H:%M:%S %z") 

27 

28 

29class Superseeded(TypedDict): # pragma: no cover 

30 """Info about which modulesuperseeded the current module.""" 

31 

32 uri: str 

33 slug: str 

34 

35 

36class Owner(TypedDict): # pragma: no cover 

37 """Owner of a given puppet module.""" 

38 

39 uri: str 

40 slug: str 

41 username: str 

42 gravatar_id: str 

43 

44 

45class Release: 

46 """ 

47 Release info about a puppet module. 

48 

49 Returned by `/v3/releases` (the list and search endpoint). 

50 """ 

51 

52 def __init__(self, 

53 uri: str, 

54 slug: str, 

55 version: Union[str, VersionInfo], 

56 created_at: Union[str, datetime], 

57 deleted_at: Optional[Union[str, datetime]], 

58 file_uri: str, 

59 file_size: int, 

60 **_: Any): # pragma: no cover 

61 self.uri = uri 

62 self.slug = slug 

63 self.version: VersionInfo 

64 

65 if isinstance(version, VersionInfo): 

66 self.version = version 

67 else: 

68 self.version = VersionInfo.parse(version) 

69 

70 self.file_uri = file_uri 

71 self.file_size = file_size 

72 

73 self.created_at: datetime 

74 if isinstance(created_at, datetime): 

75 self.created_at = created_at 

76 else: 

77 self.created_at = _parse_date(created_at) 

78 

79 self.deleted_at: Optional[datetime] = None 

80 if isinstance(deleted_at, datetime): 

81 self.deleted_at = deleted_at 

82 elif isinstance(deleted_at, str): 

83 self.deleted_at = _parse_date(deleted_at) 

84 

85 

86class ForgeModule: 

87 """ 

88 Data about a puppet module. 

89 

90 Return value of `/v3/modules` (the list and search endpoint). 

91 """ 

92 

93 def __init__(self, 

94 uri: str, 

95 slug: str, 

96 name: str, 

97 deprecated_at: Optional[Union[str, datetime]], 

98 owner: Owner, 

99 **_: Any): # pragma: no cover 

100 self.uri = uri 

101 self.slug = slug 

102 self.name = name 

103 self.deprecated_at: Optional[datetime] = None 

104 if isinstance(deprecated_at, datetime): 

105 self.deprecated_at = deprecated_at 

106 elif isinstance(deprecated_at, str): 

107 self.deprecated_at = _parse_date(deprecated_at) 

108 self.owner = owner 

109 

110 

111class CurrentRelease(Release): 

112 """ 

113 Extended release info about a puppet module. 

114 

115 Superset of Releases for the currently active version (or an older 

116 if explicitly specified). 

117 """ 

118 

119 def __init__(self, 

120 uri: str, 

121 slug: str, 

122 module: Union[ForgeModule, dict], 

123 version: Union[str, VersionInfo], 

124 metadata: Union[PuppetMetadata, dict], 

125 tags: list[str], 

126 pdk: bool, 

127 validation_score: int, 

128 file_uri: str, 

129 file_size: int, 

130 file_md5: str, 

131 file_sha256: str, 

132 downloads: int, 

133 readme: str, 

134 changelog: str, 

135 license: str, 

136 reference: str, 

137 tasks: list[dict], 

138 plans: list[dict], 

139 created_at: Union[str, datetime], 

140 updated_at: Union[str, datetime], 

141 deleted_at: Optional[Union[str, datetime]], 

142 deleted_for: Optional[str], 

143 pe_compatibility: Optional[list[str]] = None, 

144 **_: Any): # pragma: no cover 

145 super().__init__(uri, slug, version, created_at, deleted_at, 

146 file_uri, file_size) 

147 self.module: ForgeModule 

148 if isinstance(module, ForgeModule): 

149 self.module = module 

150 else: 

151 self.module = ForgeModule(**module) 

152 

153 self.metadata: PuppetMetadata 

154 if isinstance(metadata, PuppetMetadata): 

155 self.metadata = metadata 

156 else: 

157 self.metadata = PuppetMetadata(**metadata) 

158 

159 self.tags = tags 

160 self.pdk = pdk 

161 self.validation_score = validation_score 

162 self.file_md5 = file_md5 

163 self.file_sha256 = file_sha256 

164 self.downloads = downloads 

165 self.readme = readme 

166 self.changelog = changelog 

167 self.license = license 

168 self.reference = reference 

169 self.pe_compatibility = pe_compatibility 

170 self.tasks = tasks 

171 self.plans = plans 

172 

173 self.updated_at: datetime 

174 if isinstance(updated_at, datetime): 

175 self.updated_at = updated_at 

176 else: 

177 self.updated_at = _parse_date(updated_at) 

178 self.deleted_for = deleted_for 

179 

180 

181class FullForgeModule(ForgeModule): 

182 """ 

183 Extended data about a puppet module. 

184 

185 The extended superset when only checking a single module. 

186 

187 Return value of `/v3/modules/{module_slug}`. 

188 """ 

189 

190 def __init__(self, 

191 uri: str, 

192 slug: str, 

193 name: str, 

194 downloads: int, 

195 created_at: Union[str, datetime], 

196 updated_at: Union[str, datetime], 

197 deprecated_at: Optional[Union[str, datetime]], 

198 deprecated_for: Optional[str], 

199 superseded_by: Optional[Superseeded], 

200 endorsement: Optional[Union[Literal['supported'], 

201 Literal['approved'], 

202 Literal['partner']]], 

203 module_group: Union[Literal['base'], Literal['pe_only']], 

204 premium: bool, 

205 owner: Owner, 

206 current_release: Union[CurrentRelease, dict], 

207 releases: list[Union[Release, dict]], 

208 feedback_score: int, 

209 homepage_url: str, 

210 issues_url: str, 

211 **_: Any): # pragma: no cover 

212 super().__init__(uri, slug, name, deprecated_at, owner) 

213 self.downloads = downloads 

214 

215 self.created_at: datetime 

216 if isinstance(created_at, datetime): 

217 self.created_at = created_at 

218 else: 

219 self.created_at = _parse_date(created_at) 

220 

221 self.update_at: datetime 

222 if isinstance(updated_at, datetime): 

223 self.updated_at = updated_at 

224 else: 

225 self.updated_at = _parse_date(updated_at) 

226 

227 self.deprecated_for = deprecated_for 

228 self.superseded_by = superseded_by 

229 self.endorsement = endorsement 

230 self.module_group = module_group 

231 self.premium = premium 

232 self.owner = owner 

233 

234 self.current_release: CurrentRelease 

235 if isinstance(current_release, CurrentRelease): 

236 self.current_release = current_release 

237 else: 

238 self.current_release = CurrentRelease(**current_release) 

239 

240 self.releases: list[Release] 

241 self.releases = [x if isinstance(x, Release) else Release(**x) for x in releases] 

242 

243 self.feedback_score = feedback_score 

244 self.homepage_url = homepage_url 

245 self.issues_url = issues_url