1# 2# Copyright (c) 2010-2025 Antmicro 3# 4# This file is licensed under the MIT License. 5# Full license text is available in 'licenses/MIT.txt'. 6# 7 8import os 9import zipfile 10import tempfile 11import json 12from typing import Iterable, List, TextIO, IO 13from datetime import datetime 14 15def create_coverview_archive(path: TextIO, report: Iterable[str], code_files: List[IO], coverview_dict: str) -> bool: 16 merge_config = {} 17 success = True 18 if coverview_dict is not None: 19 try: 20 merge_config = json.loads(coverview_dict) 21 except json.decoder.JSONDecodeError as e: 22 print('Malformed config JSON, will use default one:', e) 23 # Delay the failure and let the archive be generated with default contents 24 # so the time isn't wasted otherwise; the user can edit the JSON manually 25 success = False 26 27 if os.path.splitext(path.name)[1] != '.zip': 28 print('Ensure that the file will have ".zip" extension. Coverview might not handle the file properly otherwise!') 29 30 with zipfile.ZipFile(path.name, 'w') as archive: 31 # In case of very large coverage files it might be better to create a temporary file instead of in-memory string 32 archive.writestr('coverage.info', '\n'.join(line for line in report)) 33 config_file = { 34 "datasets": { 35 "application": { 36 "line": "coverage.info", 37 } 38 }, 39 "title": "Coverage dashboard", 40 "commit": "", 41 "branch": "", 42 "repo": "", 43 "timestamp": "", 44 "additional": { 45 "report_timestamp": str(datetime.now()), 46 } 47 } 48 # "merge_config" will replace values from "config_file" 49 config_file = {**config_file, **merge_config} 50 archive.writestr('config.json', json.dumps(config_file)) 51 52 with tempfile.TemporaryDirectory() as tmp_dir_name: 53 with open(os.path.join(tmp_dir_name, 'sources.txt'), 'w') as sources: 54 for code_file in code_files: 55 # Remember to revert the pointer, as we might have read the file already before 56 code_file.seek(0) 57 sources.write(f'### FILE: {code_file.name}\n') 58 sources.write(code_file.read()) 59 archive.write(sources.name, arcname='sources.txt') 60 61 print('Created archive:', archive.filename) 62 63 return success 64