# SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER <carmenbianca@fsfe.org>## SPDX-License-Identifier: GPL-3.0-or-later"""Logic to convert a .reuse/dep5 file to a REUSE.toml file."""importrefromtypingimportAny,Iterable,Optional,TypeVar,Union,castimporttomlkitfromdebian.copyrightimportCopyright,FilesParagraph,Headerfrom.global_licensingimportREUSE_TOML_VERSION_SINGLE_ASTERISK_PATTERN=re.compile(r"(?<!\*)\*(?!\*)")_T=TypeVar("_T")def_collapse_list_if_one_item(# Technically this should be Sequence[_T], but I can't get that to work.sequence:list[_T],)->Union[list[_T],_T]:"""Return the only item of the list if the length of the list is one, else return the list. """iflen(sequence)==1:returnsequence[0]returnsequencedef_header_from_dep5_header(header:Header,)->dict[str,Union[str,list[str]]]:result:dict[str,Union[str,list[str]]]={}ifheader.upstream_name:result["SPDX-PackageName"]=str(header.upstream_name)ifheader.upstream_contact:result["SPDX-PackageSupplier"]=_collapse_list_if_one_item(list(map(str,header.upstream_contact)))ifheader.source:result["SPDX-PackageDownloadLocation"]=str(header.source)ifheader.disclaimer:result["SPDX-PackageComment"]=str(header.disclaimer)returnresultdef_copyrights_from_paragraph(paragraph:FilesParagraph,)->Union[str,list[str]]:return_collapse_list_if_one_item([line.strip()forlineincast(str,paragraph.copyright).splitlines()])def_convert_asterisk(path:str)->str:"""This solves a semantics difference. A singular asterisk is semantically identical to a double asterisk in REUSE.toml. """return_SINGLE_ASTERISK_PATTERN.sub("**",path)def_paths_from_paragraph(paragraph:FilesParagraph)->Union[str,list[str]]:return_collapse_list_if_one_item([_convert_asterisk(path)forpathinlist(paragraph.files)])def_comment_from_paragraph(paragraph:FilesParagraph)->Optional[str]:returncast(Optional[str],paragraph.comment)def_annotations_from_paragraphs(paragraphs:Iterable[FilesParagraph],)->list[dict[str,Union[str,list[str]]]]:annotations=[]forparagraphinparagraphs:copyrights=_copyrights_from_paragraph(paragraph)paths=_paths_from_paragraph(paragraph)paragraph_result={"path":paths,"precedence":"aggregate","SPDX-FileCopyrightText":copyrights,"SPDX-License-Identifier":paragraph.license.to_str(),}comment=_comment_from_paragraph(paragraph)ifcomment:paragraph_result["SPDX-FileComment"]=commentannotations.append(paragraph_result)returnannotations
[docs]deftoml_from_dep5(dep5:Copyright)->str:"""Given a Copyright object, return an equivalent REUSE.toml string."""header=_header_from_dep5_header(dep5.header)annotations=_annotations_from_paragraphs(dep5.all_files_paragraphs())result:dict[str,Any]={"version":REUSE_TOML_VERSION}result.update(header)result["annotations"]=annotationsreturntomlkit.dumps(result)