Coverage for rust2rpm/generator/meta.py: 100%

241 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2024-11-26 13:52 +0100

1"""Module containing base parameter classes and functionality for preparing template parameters.""" 

2 

3import time 

4from abc import ABCMeta, abstractmethod 

5from dataclasses import dataclass 

6from typing import Any 

7 

8 

9class InvalidMetadataError(ValueError): 

10 """Raised for invalid project metadata (like missing SPDX license expression).""" 

11 

12 

13class Template(metaclass=ABCMeta): 

14 """Base class for all templates.""" 

15 

16 @abstractmethod 

17 def render(self) -> str: 

18 """Render spec file from template with the computed parameters.""" 

19 

20 

21class Parameters: 

22 """Base class for all parameter classes.""" 

23 

24 

25def parameters_as_dict(p: Parameters) -> dict[str, Any]: 

26 """Convert `Parameters` into a dictionary suitable for passing to `jinja2.Template.render`. 

27 

28 Class attributes that start with underscores are ignored. 

29 """ 

30 return {attr: getattr(p, attr) for attr in dir(p) if not attr.startswith("_")} 

31 

32 

33@dataclass(frozen=True) 

34class TargetParameters(metaclass=ABCMeta): 

35 """Base class for target-specific parameters.""" 

36 

37 _date: time.struct_time | None 

38 _packager: str | None 

39 _use_rpmautospec: bool 

40 

41 @property 

42 @abstractmethod 

43 def rpm_release(self) -> str: 

44 """RPM package Release (exact value depends on the target).""" 

45 

46 @property 

47 @abstractmethod 

48 def rpm_group(self) -> str | None: 

49 """RPM package Group (not defined in all targets).""" 

50 

51 @property 

52 @abstractmethod 

53 def include_build_requires(self) -> bool: 

54 """Toggle between dynamically generated and static BuildRequires.""" 

55 

56 @property 

57 @abstractmethod 

58 def include_requires(self) -> bool: 

59 """Toggle between dynamically generated and static Requires.""" 

60 

61 @property 

62 @abstractmethod 

63 def include_provides(self) -> bool: 

64 """Toggle between dynamically generated and static Provides.""" 

65 

66 @property 

67 @abstractmethod 

68 def rpm_changelog_date(self) -> str: 

69 """Date used in the automatically generated %changelog entry.""" 

70 

71 @property 

72 @abstractmethod 

73 def rpm_changelog_packager(self) -> str: 

74 """Packager identity used in the automatically generated %changelog entry.""" 

75 

76 @property 

77 @abstractmethod 

78 def spec_copyright_year(self) -> str | None: 

79 """Copyright year for templates that include it (opensuse).""" 

80 

81 @property 

82 @abstractmethod 

83 def rpm_buildrequires(self) -> list[str]: 

84 """Automatically generated RPM BuildRequires for crate dependencies.""" 

85 

86 @property 

87 @abstractmethod 

88 def rpm_test_requires(self) -> list[str]: 

89 """Automatically generated test-only RPM BuildRequires for crate dependencies.""" 

90 

91 @property 

92 @abstractmethod 

93 def rpm_requires(self) -> dict[str | None, list[str]]: 

94 """Automatically generated RPM Requires for subpackages.""" 

95 

96 @property 

97 @abstractmethod 

98 def rpm_provides(self) -> dict[str | None, str]: 

99 """Automatically generated RPM Provides for subpackages.""" 

100 

101 @property 

102 @abstractmethod 

103 def use_rpmautospec(self) -> bool: 

104 """Toggle usage of RPMAutospec in the generated spec file.""" 

105 

106 

107@dataclass(frozen=True) 

108class ParametersFedora(TargetParameters, metaclass=ABCMeta): 

109 """Base class for parameters specific to the "fedora" target.""" 

110 

111 @property 

112 def rpm_release(self) -> str: 

113 """RPM package Release (exact value depends on the target).""" 

114 return "%autorelease" if self._use_rpmautospec else "1%{?dist}" 

115 

116 @property 

117 def rpm_group(self) -> str | None: 

118 """RPM package Group (not defined in all targets).""" 

119 return None 

120 

121 @property 

122 def include_build_requires(self) -> bool: 

123 """Toggle between dynamically generated and static BuildRequires.""" 

124 return False 

125 

126 @property 

127 def include_requires(self) -> bool: 

128 """Toggle between dynamically generated and static Requires.""" 

129 return False 

130 

131 @property 

132 def include_provides(self) -> bool: 

133 """Toggle between dynamically generated and static Provides.""" 

134 return False 

135 

136 @property 

137 def rpm_changelog_date(self) -> str: 

138 """Date used in the automatically generated %changelog entry.""" 

139 date_format = "%a %b %d %Y" 

140 return time.strftime(date_format, self._date) if self._date else time.strftime(date_format) 

141 

142 @property 

143 def rpm_changelog_packager(self) -> str: 

144 """Packager identity used in the automatically generated %changelog entry.""" 

145 return self._packager or "rust2rpm <nobody@fedoraproject.org>" 

146 

147 @property 

148 def spec_copyright_year(self) -> str | None: 

149 """Copyright year for templates that include it (opensuse).""" 

150 return None 

151 

152 @property 

153 def rpm_buildrequires(self) -> list[str]: 

154 """Automatically generated RPM BuildRequires for crate dependencies.""" 

155 return [] 

156 

157 @property 

158 def rpm_test_requires(self) -> list[str]: 

159 """Automatically generated test-only RPM BuildRequires for crate dependencies.""" 

160 return [] 

161 

162 @property 

163 def rpm_requires(self) -> dict[str | None, list[str]]: 

164 """Automatically generated RPM Requires for subpackages.""" 

165 return {} 

166 

167 @property 

168 def rpm_provides(self) -> dict[str | None, str]: 

169 """Automatically generated RPM Provides for subpackages.""" 

170 return {} 

171 

172 @property 

173 def use_rpmautospec(self) -> bool: 

174 """Toggle usage of RPMAutospec in the generated spec file.""" 

175 return self._use_rpmautospec 

176 

177 

178@dataclass(frozen=True) 

179class ParametersMageia(TargetParameters, metaclass=ABCMeta): 

180 """Base class for parameters specific to the "mageia" target.""" 

181 

182 @property 

183 def rpm_release(self) -> str: 

184 """RPM package Release (exact value depends on the target).""" 

185 return "%mkrel 1" 

186 

187 @property 

188 def rpm_group(self) -> str | None: 

189 """RPM package Group (not defined in all targets).""" 

190 return "Development/Rust" 

191 

192 @property 

193 def include_build_requires(self) -> bool: 

194 """Toggle between dynamically generated and static BuildRequires.""" 

195 return True 

196 

197 @property 

198 def include_requires(self) -> bool: 

199 """Toggle between dynamically generated and static Requires.""" 

200 return False 

201 

202 @property 

203 def include_provides(self) -> bool: 

204 """Toggle between dynamically generated and static Provides.""" 

205 return False 

206 

207 @property 

208 def rpm_changelog_date(self) -> str: 

209 """Date used in the automatically generated %changelog entry.""" 

210 date_format = "%a %b %d %Y" 

211 return time.strftime(date_format, self._date) if self._date else time.strftime(date_format) 

212 

213 @property 

214 def rpm_changelog_packager(self) -> str: 

215 """Packager identity used in the automatically generated %changelog entry.""" 

216 return self._packager or "rust2rpm <nobody@mageia.org>" 

217 

218 @property 

219 def spec_copyright_year(self) -> str | None: 

220 """Copyright year for templates that include it (opensuse).""" 

221 return None 

222 

223 @property 

224 def rpm_requires(self) -> dict[str | None, list[str]]: 

225 """Automatically generated RPM Requires for subpackages.""" 

226 return {} 

227 

228 @property 

229 def rpm_provides(self) -> dict[str | None, str]: 

230 """Automatically generated RPM Provides for subpackages.""" 

231 return {} 

232 

233 @property 

234 def use_rpmautospec(self) -> bool: 

235 """Toggle usage of RPMAutospec in the generated spec file.""" 

236 return False 

237 

238 

239@dataclass(frozen=True) 

240class ParametersOpenSUSE(TargetParameters, metaclass=ABCMeta): 

241 """Base class for parameters specific to the "opensuse" target.""" 

242 

243 @property 

244 def rpm_release(self) -> str: 

245 """RPM package Release (exact value depends on the target).""" 

246 return "0" 

247 

248 @property 

249 def rpm_group(self) -> str | None: 

250 """RPM package Group (not defined in all targets).""" 

251 return "Development/Libraries/Rust" 

252 

253 @property 

254 def include_build_requires(self) -> bool: 

255 """Toggle between dynamically generated and static BuildRequires.""" 

256 return True 

257 

258 @property 

259 def include_requires(self) -> bool: 

260 """Toggle between dynamically generated and static Requires.""" 

261 return False 

262 

263 @property 

264 def include_provides(self) -> bool: 

265 """Toggle between dynamically generated and static Provides.""" 

266 return False 

267 

268 @property 

269 def rpm_changelog_date(self) -> str: 

270 """Date used in the automatically generated %changelog entry.""" 

271 date_format = "%a %b %d %T %Z %Y" 

272 return time.strftime(date_format, self._date) if self._date else time.strftime(date_format) 

273 

274 @property 

275 def rpm_changelog_packager(self) -> str: 

276 """Packager identity used in the automatically generated %changelog entry.""" 

277 return self._packager or "rust2rpm <opensuse-packaging@opensuse.org>" 

278 

279 @property 

280 def spec_copyright_year(self) -> str | None: 

281 """Copyright year for templates that include it (opensuse).""" 

282 return time.strftime("%Y") 

283 

284 @property 

285 def rpm_requires(self) -> dict[str | None, list[str]]: 

286 """Automatically generated RPM Requires for subpackages.""" 

287 return {} 

288 

289 @property 

290 def rpm_provides(self) -> dict[str | None, str]: 

291 """Automatically generated RPM Provides for subpackages.""" 

292 return {} 

293 

294 @property 

295 def use_rpmautospec(self) -> bool: 

296 """Toggle usage of RPMAutospec in the generated spec file.""" 

297 return False 

298 

299 

300@dataclass(frozen=True) 

301class ParametersEpelEight(TargetParameters, metaclass=ABCMeta): 

302 """Base class for parameters specific to the "epel8" target.""" 

303 

304 @property 

305 def rpm_release(self) -> str: 

306 """RPM package Release (exact value depends on the target).""" 

307 return "%autorelease" if self._use_rpmautospec else "1%{?dist}" 

308 

309 @property 

310 def rpm_group(self) -> str | None: 

311 """RPM package Group (not defined in all targets).""" 

312 return None 

313 

314 @property 

315 def include_build_requires(self) -> bool: 

316 """Toggle between dynamically generated and static BuildRequires.""" 

317 return False 

318 

319 @property 

320 def include_requires(self) -> bool: 

321 """Toggle between dynamically generated and static Requires.""" 

322 return False 

323 

324 @property 

325 def include_provides(self) -> bool: 

326 """Toggle between dynamically generated and static Provides.""" 

327 return False 

328 

329 @property 

330 def rpm_changelog_date(self) -> str: 

331 """Date used in the automatically generated %changelog entry.""" 

332 date_format = "%a %b %d %Y" 

333 return time.strftime(date_format, self._date) if self._date else time.strftime(date_format) 

334 

335 @property 

336 def rpm_changelog_packager(self) -> str: 

337 """Packager identity used in the automatically generated %changelog entry.""" 

338 return self._packager or "rust2rpm <nobody@fedoraproject.org>" 

339 

340 @property 

341 def spec_copyright_year(self) -> str | None: 

342 """Copyright year for templates that include it (opensuse).""" 

343 return None 

344 

345 @property 

346 def rpm_buildrequires(self) -> list[str]: 

347 """Automatically generated RPM BuildRequires for crate dependencies.""" 

348 return [] 

349 

350 @property 

351 def rpm_test_requires(self) -> list[str]: 

352 """Automatically generated test-only RPM BuildRequires for crate dependencies.""" 

353 return [] 

354 

355 @property 

356 def rpm_requires(self) -> dict[str | None, list[str]]: 

357 """Automatically generated RPM Requires for subpackages.""" 

358 return {} 

359 

360 @property 

361 def rpm_provides(self) -> dict[str | None, str]: 

362 """Automatically generated RPM Provides for subpackages.""" 

363 return {} 

364 

365 @property 

366 def use_rpmautospec(self) -> bool: 

367 """Toggle usage of RPMAutospec in the generated spec file.""" 

368 return self._use_rpmautospec 

369 

370 

371@dataclass(frozen=True) 

372class ParametersPlain(TargetParameters, metaclass=ABCMeta): 

373 """Base class for parameters specific to the "plain" target.""" 

374 

375 @property 

376 def rpm_release(self) -> str: 

377 """RPM package Release (exact value depends on the target).""" 

378 return "1%{?dist}" 

379 

380 @property 

381 def rpm_group(self) -> str | None: 

382 """RPM package Group (not defined in all targets).""" 

383 return None 

384 

385 @property 

386 def include_build_requires(self) -> bool: 

387 """Toggle between dynamically generated and static BuildRequires.""" 

388 return True 

389 

390 @property 

391 def include_requires(self) -> bool: 

392 """Toggle between dynamically generated and static Requires.""" 

393 return True 

394 

395 @property 

396 def include_provides(self) -> bool: 

397 """Toggle between dynamically generated and static Provides.""" 

398 return True 

399 

400 @property 

401 def rpm_changelog_date(self) -> str: 

402 """Date used in the automatically generated %changelog entry.""" 

403 date_format = "%a %b %d %Y" 

404 return time.strftime(date_format, self._date) if self._date else time.strftime(date_format) 

405 

406 @property 

407 def rpm_changelog_packager(self) -> str: 

408 """Packager identity used in the automatically generated %changelog entry.""" 

409 return self._packager or "rust2rpm <packager@example.com>" 

410 

411 @property 

412 def spec_copyright_year(self) -> str | None: 

413 """Copyright year for templates that include it (opensuse).""" 

414 return time.strftime("%Y") 

415 

416 @property 

417 def use_rpmautospec(self) -> bool: 

418 """Toggle usage of RPMAutospec in the generated spec file.""" 

419 return False