Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
get_sources_binaries.py 3.32 KiB
#!/usr/bin/env python3

# SPDX-License-Identifier: GPL-2.0-only
# SPDX-FileCopyrightText: Alberto Pianon <pianon@array.eu>


import os
import re
import json

from bb.tinfoil import Tinfoil

def parse_pkgdata(pkgdata_file):
    pkgdata_text = pkgdata_file.read()
    pkgdata = {}
    p = re.compile('^([^:]+): (.*)$')
    lines = pkgdata_text.split('\n')
    for line in lines:
        m = p.match(line)
        if m:
            key = m.group(1)
            value = json.loads(m.group(2)) if key == 'FILES_INFO' else m.group(2).strip()
            pkgdata.update({ key: value })
    return pkgdata


def main():

    with Tinfoil() as tf:

        tf.prepare()

            image_dir = tf.config_data.getVar('DEPLOY_DIR_IMAGE')
            machine = tf.config_data.getVar('MACHINE')
            pkgdata_dir = tf.config_data.getVar('PKGDATA_DIR')
            
            manifests = [
                f for f in os.listdir(image_dir)
                if f.endswith('.manifest')
                and os.path.islink(os.path.join(image_dir,f))
            ]

            package_names = []
            for manifest in manifests:
                image = os.path.basename(manifest).replace(f'-{machine}.manifest', '')
                print(f"parsing image '{image}'")
                with open(os.path.join(image_dir, manifest), 'r') as f:
                    package_names += [ line.split()[0] for line in f if line ]
            package_names = sorted(list(set(package_names)))
            if '' in package_names:
                package_names.remove('')

            print("retrieving recipe for each package")
            recipes = {}
            for package_name in package_names:
                pkgdata_file = os.path.join(pkgdata_dir, 'runtime-reverse', package_name)
                with open(pkgdata_file, 'r') as f:
                    pkgdata = parse_pkgdata(f)
                recipe = pkgdata.get('PN')
                if recipe not in recipes:
                    print(f"parsing recipe {recipe}")
                    r = tf.parse_recipe(recipe)
                    arch = r.getVar("PACKAGE_ARCH")
                    workdir = r.getVar("WORKDIR")
                    src_dir = r.getVar("S") 
                    sysroot = os.path.join(workdir, 'recipe-sysroot')
                    sysroot_native = os.path.join(workdir, 'recipe-sysroot-native')
                    build_dir = os.path.join(workdir, r.getVar("BUILDDIR") or "build")
                    recipes[recipe] = {
                        "version": r.getVar('PV'),
                        "revision": r.getVar('PR'),
                        "arch": arch,
                        "workdir": workdir,
                        "patched_configured_src_dir": src_dir if os.path.isdir(src_dir) else None,
                        "recipe-sysroot": sysroot if os.path.isdir(sysroot) else None,
                        "recipe-sysroot-native": sysroot_native if os.path.isdir(sysroot_native) else None,
                        "build_dir": build_dir if os.path.isdir(build_dir) else None,
                        "rpms": os.listdir(os.path.join(workdir, "deploy-rpms", arch.replace("-", "_"))),
                    }
            with open(sys.argv[1], "w") as j:
                json.dump(recipes, j, indent=4)
            print("DONE!")


if __name__ == "__main__":
    main()