15199d831SAndrew Geissler# 292b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors 392b42cb3SPatrick Williams# 45199d831SAndrew Geissler# SPDX-License-Identifier: GPL-2.0-only 55199d831SAndrew Geissler# 65199d831SAndrew Geissler 75199d831SAndrew Geisslerimport collections 85199d831SAndrew Geissler 95199d831SAndrew GeisslerDepRecipe = collections.namedtuple("DepRecipe", ("doc", "doc_sha1", "recipe")) 105199d831SAndrew GeisslerDepSource = collections.namedtuple("DepSource", ("doc", "doc_sha1", "recipe", "file")) 115199d831SAndrew Geissler 125199d831SAndrew Geissler 135199d831SAndrew Geisslerdef get_recipe_spdxid(d): 145199d831SAndrew Geissler return "SPDXRef-%s-%s" % ("Recipe", d.getVar("PN")) 155199d831SAndrew Geissler 165199d831SAndrew Geissler 176aa7eec5SAndrew Geisslerdef get_download_spdxid(d, idx): 186aa7eec5SAndrew Geissler return "SPDXRef-Download-%s-%d" % (d.getVar("PN"), idx) 196aa7eec5SAndrew Geissler 206aa7eec5SAndrew Geissler 215199d831SAndrew Geisslerdef get_package_spdxid(pkg): 225199d831SAndrew Geissler return "SPDXRef-Package-%s" % pkg 235199d831SAndrew Geissler 245199d831SAndrew Geissler 255199d831SAndrew Geisslerdef get_source_file_spdxid(d, idx): 265199d831SAndrew Geissler return "SPDXRef-SourceFile-%s-%d" % (d.getVar("PN"), idx) 275199d831SAndrew Geissler 285199d831SAndrew Geissler 295199d831SAndrew Geisslerdef get_packaged_file_spdxid(pkg, idx): 305199d831SAndrew Geissler return "SPDXRef-PackagedFile-%s-%d" % (pkg, idx) 315199d831SAndrew Geissler 325199d831SAndrew Geissler 335199d831SAndrew Geisslerdef get_image_spdxid(img): 345199d831SAndrew Geissler return "SPDXRef-Image-%s" % img 355199d831SAndrew Geissler 365199d831SAndrew Geissler 377e0e3c0cSAndrew Geisslerdef get_sdk_spdxid(sdk): 387e0e3c0cSAndrew Geissler return "SPDXRef-SDK-%s" % sdk 397e0e3c0cSAndrew Geissler 407e0e3c0cSAndrew Geissler 41*220dafdbSAndrew Geisslerdef _doc_path_by_namespace(spdx_deploy, arch, doc_namespace): 42*220dafdbSAndrew Geissler return spdx_deploy / "by-namespace" / arch / doc_namespace.replace("/", "_") 43b542dec1SPatrick Williams 44b542dec1SPatrick Williams 45*220dafdbSAndrew Geisslerdef doc_find_by_namespace(spdx_deploy, search_arches, doc_namespace): 46*220dafdbSAndrew Geissler for pkgarch in search_arches: 47*220dafdbSAndrew Geissler p = _doc_path_by_namespace(spdx_deploy, pkgarch, doc_namespace) 48*220dafdbSAndrew Geissler if os.path.exists(p): 49*220dafdbSAndrew Geissler return p 50*220dafdbSAndrew Geissler return None 51*220dafdbSAndrew Geissler 52*220dafdbSAndrew Geissler 53*220dafdbSAndrew Geisslerdef _doc_path_by_hashfn(spdx_deploy, arch, doc_name, hashfn): 54*220dafdbSAndrew Geissler return ( 55*220dafdbSAndrew Geissler spdx_deploy / "by-hash" / arch / hashfn.split()[1] / (doc_name + ".spdx.json") 56*220dafdbSAndrew Geissler ) 57*220dafdbSAndrew Geissler 58*220dafdbSAndrew Geissler 59*220dafdbSAndrew Geisslerdef doc_find_by_hashfn(spdx_deploy, search_arches, doc_name, hashfn): 60*220dafdbSAndrew Geissler for pkgarch in search_arches: 61*220dafdbSAndrew Geissler p = _doc_path_by_hashfn(spdx_deploy, pkgarch, doc_name, hashfn) 62*220dafdbSAndrew Geissler if os.path.exists(p): 63*220dafdbSAndrew Geissler return p 64*220dafdbSAndrew Geissler return None 65b542dec1SPatrick Williams 66b542dec1SPatrick Williams 67b542dec1SPatrick Williamsdef doc_path(spdx_deploy, doc_name, arch, subdir): 68b542dec1SPatrick Williams return spdx_deploy / arch / subdir / (doc_name + ".spdx.json") 69b542dec1SPatrick Williams 70b542dec1SPatrick Williams 71b542dec1SPatrick Williamsdef write_doc(d, spdx_doc, arch, subdir, spdx_deploy=None, indent=None): 725199d831SAndrew Geissler from pathlib import Path 735199d831SAndrew Geissler 745199d831SAndrew Geissler if spdx_deploy is None: 755199d831SAndrew Geissler spdx_deploy = Path(d.getVar("SPDXDEPLOY")) 765199d831SAndrew Geissler 77b542dec1SPatrick Williams dest = doc_path(spdx_deploy, spdx_doc.name, arch, subdir) 785199d831SAndrew Geissler dest.parent.mkdir(exist_ok=True, parents=True) 795199d831SAndrew Geissler with dest.open("wb") as f: 80615f2f11SAndrew Geissler doc_sha1 = spdx_doc.to_json(f, sort_keys=True, indent=indent) 815199d831SAndrew Geissler 82*220dafdbSAndrew Geissler l = _doc_path_by_namespace(spdx_deploy, arch, spdx_doc.documentNamespace) 83b542dec1SPatrick Williams l.parent.mkdir(exist_ok=True, parents=True) 84b542dec1SPatrick Williams l.symlink_to(os.path.relpath(dest, l.parent)) 85b542dec1SPatrick Williams 86*220dafdbSAndrew Geissler l = _doc_path_by_hashfn( 87*220dafdbSAndrew Geissler spdx_deploy, arch, spdx_doc.name, d.getVar("BB_HASHFILENAME") 88*220dafdbSAndrew Geissler ) 895199d831SAndrew Geissler l.parent.mkdir(exist_ok=True, parents=True) 905199d831SAndrew Geissler l.symlink_to(os.path.relpath(dest, l.parent)) 915199d831SAndrew Geissler 925199d831SAndrew Geissler return doc_sha1 935199d831SAndrew Geissler 945199d831SAndrew Geissler 955199d831SAndrew Geisslerdef read_doc(fn): 965199d831SAndrew Geissler import hashlib 975199d831SAndrew Geissler import oe.spdx 985199d831SAndrew Geissler import io 995199d831SAndrew Geissler import contextlib 1005199d831SAndrew Geissler 1015199d831SAndrew Geissler @contextlib.contextmanager 1025199d831SAndrew Geissler def get_file(): 1035199d831SAndrew Geissler if isinstance(fn, io.IOBase): 1045199d831SAndrew Geissler yield fn 1055199d831SAndrew Geissler else: 1065199d831SAndrew Geissler with fn.open("rb") as f: 1075199d831SAndrew Geissler yield f 1085199d831SAndrew Geissler 1095199d831SAndrew Geissler with get_file() as f: 1105199d831SAndrew Geissler sha1 = hashlib.sha1() 1115199d831SAndrew Geissler while True: 1125199d831SAndrew Geissler chunk = f.read(4096) 1135199d831SAndrew Geissler if not chunk: 1145199d831SAndrew Geissler break 1155199d831SAndrew Geissler sha1.update(chunk) 1165199d831SAndrew Geissler 1175199d831SAndrew Geissler f.seek(0) 1185199d831SAndrew Geissler doc = oe.spdx.SPDXDocument.from_json(f) 1195199d831SAndrew Geissler 1205199d831SAndrew Geissler return (doc, sha1.hexdigest()) 121