chronaxis.batch.publication
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""关闭批量汇总JSON后独占安装正式报告,保留各任务已发布的独立输出。23报告只汇总状态、身份和错误,不合并指标或把失败会话当作零结果。沿现有结果4发布使用平台不覆盖移动;不支持的环境明确拒绝,失败暂存保留。5"""67import json8from pathlib import Path9import platform10import tempfile11from .models import BatchReport121314def write_batch_report(report: BatchReport) -> Path:15 """发布带本批时间的汇总文件。参数: report实际结果。返回: 实际报告路径。1617 异常: 类型、只读路径、未支持平台、已有目标或原文件错误;关闭失败不安装正式文件。18 副作用: 只写本批目录的唯一暂存文件,失败不删除任务结果或覆盖已有报告。19 """20 return _write_batch_report(report, {})212223def _write_batch_report(report, extra):24 """先完成可选的 fast 总量计算,再一次发布同一批报告。"""25 if not isinstance(report, BatchReport):26 raise TypeError('需要BatchReport')27 root = report.output_dir.absolute()28 # 本函数也可独立调用;平台和已有结果的发布规则仍须在此检查。29 from ..results.platform_files import require_publication_platform30 require_publication_platform()31 from ..results.publication import PublicationNames32 publication = report._publication or PublicationNames(root, ('batch_report.json',))33 destination = root / publication.names['batch_report.json']34 from ..results.owned_directory import directory_identity, remove_owned_directory35 temporary = identity = None36 # 编码、写入和真实close全部成功才安装;Windows rename在目标已存在时拒绝。37 try:38 temporary = Path(tempfile.mkdtemp(prefix='.batch-report-', suffix='.incomplete', dir=root))39 identity = directory_identity(temporary)40 with (temporary/'batch_report.json').open('x', encoding='utf-8', newline='') as stream:41 json.dump(dict(report.to_dict(), **extra), stream, ensure_ascii=False, allow_nan=False, indent=2)42 stream.write('\n')43 publication.publish(temporary, 'batch_report.json', only=('batch_report.json',))44 temporary.rmdir()45 return destination46 except BaseException as error:47 if publication.completed:48 error.published_report_path = destination49 # 不撤销已完成任务;只清理本次报告临时目录,保留最初的写出错误。50 try:51 if temporary is not None and identity is not None:52 remove_owned_directory(temporary, identity)53 except BaseException as cleanup:54 error.add_note('批量报告暂存清理失败:' + str(cleanup))55 try:56 publication.close()57 except BaseException as cleanup:58 error.add_note('批量命名锁释放失败:' + str(cleanup))59 raise60