xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oe/sbom.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyunimport collections
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunDepRecipe = collections.namedtuple("DepRecipe", ("doc", "doc_sha1", "recipe"))
8*4882a593SmuzhiyunDepSource = collections.namedtuple("DepSource", ("doc", "doc_sha1", "recipe", "file"))
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun
11*4882a593Smuzhiyundef get_recipe_spdxid(d):
12*4882a593Smuzhiyun    return "SPDXRef-%s-%s" % ("Recipe", d.getVar("PN"))
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun
15*4882a593Smuzhiyundef get_package_spdxid(pkg):
16*4882a593Smuzhiyun    return "SPDXRef-Package-%s" % pkg
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun
19*4882a593Smuzhiyundef get_source_file_spdxid(d, idx):
20*4882a593Smuzhiyun    return "SPDXRef-SourceFile-%s-%d" % (d.getVar("PN"), idx)
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun
23*4882a593Smuzhiyundef get_packaged_file_spdxid(pkg, idx):
24*4882a593Smuzhiyun    return "SPDXRef-PackagedFile-%s-%d" % (pkg, idx)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun
27*4882a593Smuzhiyundef get_image_spdxid(img):
28*4882a593Smuzhiyun    return "SPDXRef-Image-%s" % img
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun
31*4882a593Smuzhiyundef get_sdk_spdxid(sdk):
32*4882a593Smuzhiyun    return "SPDXRef-SDK-%s" % sdk
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun
35*4882a593Smuzhiyundef write_doc(d, spdx_doc, subdir, spdx_deploy=None, indent=None):
36*4882a593Smuzhiyun    from pathlib import Path
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun    if spdx_deploy is None:
39*4882a593Smuzhiyun        spdx_deploy = Path(d.getVar("SPDXDEPLOY"))
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun    dest = spdx_deploy / subdir / (spdx_doc.name + ".spdx.json")
42*4882a593Smuzhiyun    dest.parent.mkdir(exist_ok=True, parents=True)
43*4882a593Smuzhiyun    with dest.open("wb") as f:
44*4882a593Smuzhiyun        doc_sha1 = spdx_doc.to_json(f, sort_keys=True, indent=indent)
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun    l = spdx_deploy / "by-namespace" / spdx_doc.documentNamespace.replace("/", "_")
47*4882a593Smuzhiyun    l.parent.mkdir(exist_ok=True, parents=True)
48*4882a593Smuzhiyun    l.symlink_to(os.path.relpath(dest, l.parent))
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun    return doc_sha1
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun
53*4882a593Smuzhiyundef read_doc(fn):
54*4882a593Smuzhiyun    import hashlib
55*4882a593Smuzhiyun    import oe.spdx
56*4882a593Smuzhiyun    import io
57*4882a593Smuzhiyun    import contextlib
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun    @contextlib.contextmanager
60*4882a593Smuzhiyun    def get_file():
61*4882a593Smuzhiyun        if isinstance(fn, io.IOBase):
62*4882a593Smuzhiyun            yield fn
63*4882a593Smuzhiyun        else:
64*4882a593Smuzhiyun            with fn.open("rb") as f:
65*4882a593Smuzhiyun                yield f
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun    with get_file() as f:
68*4882a593Smuzhiyun        sha1 = hashlib.sha1()
69*4882a593Smuzhiyun        while True:
70*4882a593Smuzhiyun            chunk = f.read(4096)
71*4882a593Smuzhiyun            if not chunk:
72*4882a593Smuzhiyun                break
73*4882a593Smuzhiyun            sha1.update(chunk)
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun        f.seek(0)
76*4882a593Smuzhiyun        doc = oe.spdx.SPDXDocument.from_json(f)
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun    return (doc, sha1.hexdigest())
79